`
chxiaowu
  • 浏览: 240007 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

如何在Google Map中处理大量标记

 
阅读更多

http://www.cnblogs.com/SunYu/archive/2010/07/29/1788249.html

 

 

 在你有一个合理的标记数量的时候,使Google Map标记是很平常的。但是一旦你有几百个、甚至更多地标的时候,性能迅速的开始降低。在本文章中,我会告诉你一些提高性能的方法。同时我会放一个测试页面去比较它们的效率。

         如果你是第一次使用Google Map的标记,我建议你先去了解一下在Google Map上使用标记的一些基本原理和操作。

The Marker Manager-Keeps track of them

您的第一选择可能是利用MarkerManager,因为它是一个由谷歌提供的实用工具库。首先要将标记添加到MarkerManager,而不是使用GMap2.addOverlay()逐个的将每一个Marker添加到Map。MarkerManager会不断跟踪你所有的标记。通过定义几个不同的zoom-levels,将可能会同时出现的Marker集合放在同一level上,避免在同一时间大量的Marker同时显示。

MarkerManager 最初比直接加入到地图中有些慢,但是这样添加的好处是你可以更好的控制它们。

使用addMarker(GMarker, minZoom, maxZoom?)将标记添加到MarkerManager,这个方法携带三个参数,第一个是你要添加的标记,后两个参数是可选的,但是界定了在什么level上这个标记是可见的。

A simple example

//Create a new map

var map=new GMap2(document.getElementById('map'));

map.setCenter(new GLatLng(59.5,14.0),6);

//Create a new instance of the MarkerManager

var mgr = new MarkerManager(map);

// Create a new marker 

var marker = new GMarker(new GLatLng(59.0, 13.80)); 

// Add marker to the MarkerManager 

mgr.addMarker(marker);

明显的,没有谁会想MarkerManager添加单一的标记,但是如果你有几百个标记,那么可能就要这么做了。

Bulk adding the markers

使用MarkerManager更高效的办法是,首先将所有标记添加到一个数组中,然后用addMarkers(markerArray, minZoom, maxZoom?)将这个数组添加到MarkerManager。

 

        // Create a new instance of the MarkerManager 

        var mgr = new MarkerManager(map); 

        // Create marker array 

        var markers = []; 

        // Loop to create markers and adding them to the MarkerManager 

        for(var i = 0; i < 50; i += 0.1) { 

            var marker = new GMarker(new GLatLng(59.0 + i, 13.80 + i)); 

            markers.push(marker); 

        } 

        // Add the array to the MarkerManager 

        mgr.addMarkers(markers); 

        // Refresh the MarkerManager to make the markers appear on the map 

        mgr.refresh();

         请注意,在将存有标记数组添加到MarkerManager之后,必须调用mgr.refresh()。在逐个添加Marker的时候是不需要的。

附加方法

removeMarker(marker)

从MarkerManager中移除一个标记。

clearMarkers()

移除所有标记。

getMarkerCount(zoom)

返回在指定的zoom-level下的标记个数。

 

MarkerManager是Google提供的一个实用工具库。从下面的链接你可以下载源代码以及说明文档和例子。Google Maps MarkerManager SVN

http://gmaps-utility-library.googlecode.com/svn/trunk/markermanager/release/

 

Marker Light - Markers on a diet(高亮标记-首都标记)

Google的Pamela Fox 为减少复杂标记,从而提高效率的MarkerLight制作了一个简单的程序。这样做的代价是,真的仅仅是在地图上显示一个图片,但你不能与之交互。如果你不需要与程序交互,那么这种办法真的是一种简单的提高性能的办法,这样做唯一的区别就是你创建的是一个MarkerLight,而不是一个GMarker。

作者Pamelas后来解释了为什么这种方法会提高效率:

GMarker之所以耗时这么长是因为它实际上是由多个DOM元素构成-前景,阴影,打印版本,可点击区域等。

如果你的目的只是显示,那么你可以选择象MarkerLight那样创建一个带有背景URL的DIV那样去创建一个GOverlay的扩展(或者背景颜色、甚至更好的)

                                                                                                                         ------Pamela Fox

以下是如何使用它:

map.addOverlay(new MarkerLight(latlng, {image: "red_dot.png"}));

 

red_dot.png这个图片是用于marker中的。这是最小最简单的一个。你可以尝试在Pamelas test page上用不同数量的标记测试效率。Download markerlight.js

 

Using Marker Light in combination with MarkerManager-结合MarkerManager使用Marker Light

用MarkerManager的集中式添加MarkerLight的好处很多,而且真的很简单,只是将二者结合起来。

mgr.addMarker(new MarkerLight(latlng, {image: "red_dot.png"}));

这样做的原因是你可以显示在不同缩放级别下不同数量的标记。这种方式可以确保不会有太多的标记在同一时间显示。

Clusterer - Only show what you need

另一种方法是使用ACME实验室群集Clusterer。这是一个第三方库,提供了更快捷的方式加入标记。它是在BSD许可证下发布,并免费提供。

只需要做两件事情,效率会更快:

         1.只有当前可见的标记会被建立。

         2.如果有太多的标记需要显示,那么它们会组合在一起成为群集标记。 

这会让你的地图上即使有成千上万个标记依然能保持良好的性能。我的测试表明,这种方法的效率要显著快于使用MarkerManager的方式。

以下是如何使用它:

        // Create a Clusterer object 

        var clusterer = new Clusterer(map); 

        // Create marker 

        var marker = new GMarker(new GLatLng(57.8, 14.0)); 

        // Add marker to the map 

        clusterer.AddMarker(marker, 'text to infobox'); 

调用clusterer.RemoveMarker(marker)方法来从Map中移除标记。另外还有一些方法来改变标志的行为。

  1. 1.       clusterer.SetIcon(GIcon) 

改变簇的图标

  1. 2.       clusterer.SetMaxVisibleMarkers(n) 

设置标记最多可见的数量门限,默认值是150.

  1. 3.       clusterer.SetMinMarkersPerCluster(n)

为一个标记集合设置最少的标记数,默认值是5.

  1. 4.       clusterer.SetMaxLinesPerInfoBox(n)

设置信息框内文本的最大行数,默认值是10.

Download Clusterer2.js

 

ClusterMarker - Chunk 'em all up

ClusterMarker是一个根据GNU通用公共许可证发布的免费javascript库,可以集中添加标记。这个库的独特行在于它会自动检测标记,彼此相交和集成为一个标记群集。

下面的图片说明是如何工作的:

  

Images by Martin Pearman

该构造函数有两个参数,如下:

var cluster = new ClusterMarker(map, options).

 

Map是对一个有如下属性的对象引用的 map对象和选项的参考(map is a reference to the map object and options is an object literal that can have these properties:)

  1. 1.       clusterMarkerIcon [GIcon]

         将默认的簇标记图标更改为你所选择的图标。

  1. 2.       markers [array]

         所有你想传递给ClusterMarker的标记的数组

除了这些属性,你也可以使用类中的其他所有属性,查看完整的文档说明列表documentation

如下是如何使用最少的代码量,用ClusterMarker添加标记:

    var markerArray = [];  

    // Insert code to fill the markerArray with markers...  

    // Creating a new cluster by adding the map and the markerarray  

    var cluster = new ClusterMarker(map, {markers: markerArray});  

    // Refreshing to show the added markers  

cluster.refresh();

这段代码将会在地图上插入标记,如果他们足够近的话,就用一个图标表示他们。欲了解更多关于如何细粒度操作的几种方法和属性,有关详细说明类库是如何工作的,在Clustermarker 项目页面上有很多优秀的文档。Clustermarker Project page.

MarkerClusterer - The new kid in town

这个使用工具库的所有都是最新的,在我最初写这篇文章的时候还没有。这个库,是吴小溪写的,谷歌地图的开放源码工具库的一部分,易于使用,具有优良的性能。

像其他的类库一样,他们聚集在一起使其更容易有一个概观,减少了可见标记的数量。观看下面的图像,看看如何:

 

Image by Xiaoxi Wu

 

它的构造函数需要三个参数,第一个是地图的引用,第二个是一个GMarkers数组,第三个被选择的对象与文字。只有第一个参数是必须的。

        var markers = [];  

        // Insert code to fill the markerArray with markers...  

        // Creating a new cluster by adding the map and the array of markers  

        var markerCluster = new MarkerClusterer(map, markers); 

查看完整的说明文档和它的功能documentation。更多信息去GoogleGeo开发博客读MarkerClusterer: A Solution to the Too Many Markers Problem

 

Compare performance

Compare the different techniques on the Test page

我的灵感来自于Pamela Fox的对MarkerLight的测试页,我也做了一个我自己的测试页

,你也可以测试本文中所有不同做法的性能。

结果:

我在几个不同的浏览器运行了测试,每一个测试,我使用不同的技术添加500个标记,每次测试之间我刷新浏览器。所有的测试平台采用一个具有3.60 GHz的奔腾4处理器和超线程运行Windows XP的2 GB内存的PC。

Load times in milliseconds (ms)

 

在这个测试中,Clusterer2是所有技术中最快的一个。但是要知道这是不是真实的数据,因为我只能够测量从我提交它们到标记传递到地图的时间,而不是知道在地图上看见标记的实际时间。当考虑到这方面,我觉得MarkerClusterer是最快的技术,紧随其后的是ClusterMarker。

 

当谈到浏览器,性能最高的是带有绿色标记的浏览器,性能最差的带有红色标记的浏览器。毫无疑义,IE性能很差。谷歌浏览器和Safari整体上表现出,他们的javascript引擎和性能一直很快。

 

如果你有什么好的想法去改善这个测试,使之能够更好的衡量直到标记在地图上显示实际时间,请在评论中通过共享或我的主页联络我。Contact page.

 

结论

利用这篇文章中的技术,执行效果一般都很好,因为你没有一个令人难以置信的大量的标记。对于一些特殊的场合,这些技术并不能满足你的需求,你将不得不采取更加极端的措施,例如,创建一个大的覆盖层,覆盖所有的标记,但是这超出了本文的讲述范围。

 

我希望这些技术能 帮到你,Happy coding!

分享到:
评论

相关推荐

    vue2googlemap基于Vue2x和google地图组件

    Vue2googlemap支持Google Maps API中的各种事件监听,如点击地图、标记、路径等,可以很方便地在Vue组件中响应这些事件。 5. **自定义组件** 除了内置组件,还可以根据需求自定义组件,实现更复杂的地图交互逻辑...

    Google Map API 使用示例

    在实际开发中,可能还需要考虑性能优化,例如使用分块加载地图(Clustering)处理大量数据点,以及根据用户行为动态加载或隐藏地图元素。 通过学习和实践这些示例,你可以熟练掌握 Google Map API 的基础和高级功能...

    GoogleMap定位系统、与Webservice连接

    在GoogleMap定位系统和Web服务连接中,Service常用于持续获取位置更新或者在后台处理数据请求。使用Service可以避免因为用户离开应用界面而中断这些任务,但同时也需要考虑服务的生命周期管理和资源消耗。 **...

    GoogleMap&Android

    对于大规模数据的显示,如大量标记或路径,可以使用GroundOverlay或ClusterManager来提高性能和用户体验。 11. **离线地图** 虽然Google Maps API不直接支持离线地图,但开发者可以利用SQLite数据库或第三方库...

    Google+Map+MarkerCluster++使用簡介

    3. **性能优化**:处理大量标记时,可以考虑分页加载或懒加载策略,减少初始加载时的计算量。 4. **交互事件**:你可以监听MarkerClusterer的事件,如点击集群,然后显示详细信息或者弹出信息窗口。 ** 示例代码...

    google map demo

    在回调的`onMapReady(GoogleMap googleMap)`方法中,可以设置地图的属性,如中心点、缩放级别、标记、路径等。 6. **定位服务**:启用定位服务可以让应用获取用户的实时位置。通过调用`GoogleMap`对象的`...

    google map api v3源码

    谷歌地图API V3是Google...1. **初始化地图**: 在HTML页面中引入Google Maps API的JavaScript库,然后在JavaScript代码中创建一个地图实例。通常会指定地图容器(如div元素)的ID和初始中心点坐标。 ```javascript ...

    Google Map api V3 (3.9.12)的离线开发包

    在Google Map API V3中,主要知识点包括: 1. **引入API**:在HTML文件中,通过`&lt;script&gt;`标签引入API。离线包中的.js文件就是包含API的核心代码,可以本地引用,例如: ```html (3.16.2)_OfflinePack/...

    GoogleMap和location

    在集成GoogleMap时,你需要在Google Cloud Console中创建一个项目,获取API密钥,并将其添加到AndroidManifest.xml文件中的meta-data标签中。这样,用户就可以在应用中看到实时的地理信息了。 Location服务则是一个...

    Google-Map-Api.rar_google map_google map api

    在使用谷歌地图API前,你需要在Google Cloud Console上创建项目并获取API密钥。这个密钥是你调用API时的身份凭证,确保你的请求被正确识别和计费。 3. **JavaScript API** - **加载API**:首先要在HTML页面中引入...

    googlemap实例工程

    在处理大量数据或复杂交互时,需要注意性能优化,如使用分块加载(clustering)标记,或者利用缓存机制提高响应速度。 9. **响应式设计** 确保你的地图在不同设备和屏幕尺寸上都能正常显示,需要考虑响应式设计。...

    wpf google map v3 示例

    4. **在C#中处理点击事件**:在C#代码中,通过`WebBrowser.Document.InvokeScript`方法接收JavaScript传递的坐标,然后创建一个新的标记实例`google.maps.Marker`,设置其位置并添加到地图上。 5. **显示标记**:...

    google map

    标题 "google map" 涉及到的是 Google Maps API 的使用和开发,这是一个广泛应用于网站和应用程序中的地理信息系统。Google Maps 提供了丰富的地图、卫星图像、街景以及导航功能,开发者可以利用其开放的接口来集成...

    谷歌地图开发包GoogleMap

    谷歌地图开发包GoogleMap是一个专为开发者设计的工具,它提供了丰富的API和功能,使得开发者可以集成谷歌地图服务到自己的应用程序中,无论是Web应用、移动应用还是其他平台的应用。这个开发包是谷歌地图服务的重要...

    android移动版GoogleMap

    首先,你需要在Google Cloud Console中创建一个项目,并启用Google Maps Android API。接着,获取API密钥,这是连接你的应用和Google Maps服务的关键。将API密钥添加到AndroidManifest.xml文件中的meta-data标签内...

    GoogleMapsMarkerClustering:如何在 Google 地图中使用标记聚类实用程序的示例

    7. **性能优化**:在处理大量标记时,考虑使用`GroundOverlay`代替`Marker`,或者只在视图范围内的标记进行渲染,以提高性能。 8. **动态加载和更新**:如果你的数据集是动态变化的,你需要在数据更新后重新计算和...

    Google Map V3 API

    **Google Map V3 API**是谷歌提供的一种用于在网页中集成地图功能的接口,它允许开发者利用JavaScript语言创建交互式的地图应用。这个API是Google Maps API的第三个主要版本,提供了更多的功能、更好的性能以及更...

    Google Map API基本源码

    在使用Google Map API之前,你需要在Google Cloud Platform上注册项目,并获取API密钥。这个密钥用于验证你的应用,防止滥用Google的服务。 2. **HTML和JavaScript引入**: 基本源码会展示如何在HTML页面中引入...

    google map 源码

    2. API接口:谷歌地图提供了丰富的API,包括JavaScript API、Android API和iOS SDK等,允许开发者在网页或移动应用中嵌入地图、标记、路线规划等功能。通过研究源码,我们可以了解如何调用这些API,以及它们背后的...

    google map 定位搜索

    在IT行业中,Google Map是一个广泛使用的地图服务,它提供了丰富的功能,包括定位、搜索和模式选择等。这个项目显然涉及到如何在应用中集成并利用Google Maps API来实现这些功能。以下是对这些知识点的详细说明: 1...

Global site tag (gtag.js) - Google Analytics