基于C#VS2013 WPF的OpenStreetMap,在地图上显示100万个带标记的位置

时间:2015-10-07 01:38:37

标签: c# wpf visual-studio openstreetmap gmap.net

我想在基于OpenStreetMap的地图上显示100万个位置。

我在C#VS2013和GMAP.NET WPF上工作。但是,当我为每个位置添加标记时,由于标记是位图图像,因此无法显示地图。 100万个标记在我的笔记本电脑上消耗了太多内存(8 GB内存)。

代码是:

   public void add_marker(List<Tuple<double, double>> latLongList, ref GMapControl myMap)
    {
            System.Windows.Media.Imaging.BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.UriSource = new Uri(@"C:\djx_2014_6_3\my_projects\test_gmap_dot_net\GMap_WPF\try1\try_gmap_wpf\try_gmap_wpf\images\map_marker.png", UriKind.Absolute);
            bitmapImage.DecodePixelHeight = 5;
            bitmapImage.DecodePixelWidth = 5;
            bitmapImage.EndInit();
            foreach(var v  in latLongList)
            {
                GMap.NET.PointLatLng point = new GMap.NET.PointLatLng(v.Item1, v.Item2);
                GMapMarker marker = new GMapMarker(point);
                System.Windows.Controls.Image image = new System.Windows.Controls.Image();
                image.Source = bitmapImage;
                marker.Shape = image;
                marker.ZIndex = 5;
                myMap.Markers.Add(marker);
            }
    }

我不想将图像用作标记,但我无法找到如何在openStreetMap中使用默认标记。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

WPF并非旨在用于此类事情。首先,你要为每个标签创建一个Bitmap,这是一个用户控件,并为GUI命中测试和绑定等带来了相当大的开销。其次,WPF使用DirectX渲染,这意味着在某些时候所有数据都有使用顶点缓冲区设置并上传到图形卡。如果您使用数据绑定或尝试创建单独的UI元素,那么这将需要大量的初始设置时间和内存,正如您已经发现的那样。如果你试图自己绘制它们(例如通过创建自己的用户控件并覆盖OnRender),那么情况会更糟,因为现在所有的工作都是在每一帧完成(除了仍然需要初始设置的缓冲的东西,所以你回到原点了。)

如果我必须自己这样做,我将首先用适当的2D结构组织数据集,例如k-d树,R *树或甚至基本的四叉树。这将允许您在任何给定时刻快速确定哪些标记位于视锥体中。

接下来,我会将相应的绑定添加到滚动条等,以便我可以准确地监视当前视图视锥的位置,然后每个帧我将基于此更新可见标记列表。只要您没有超过几千个对象立即进入视图就应该没问题,否则您将不得不使用队列错开多个帧的更新。

如果这不符合您的需求,那么您实际上只剩下两个选项:1)手动生成原始位图数据,或2)使用更合适的技术。