-2

我想在基于 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 中使用默认标记。

任何帮助,将不胜感激。

4

1 回答 1

1

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

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

接下来,我将添加适当的绑定到滚动条等,以便我可以准确监控当前视锥体的位置,然后每一帧我都会根据它更新可见标签列表。只要您一次没有超过几千个对象进入视野,您应该没问题,否则您将不得不使用队列在多个帧上错开更新。

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

于 2015-10-07T03:45:31.443 回答