javascript - google Maps JS APi v3 - 简单多标记例子

  显示原文与译文双语对照的内容

谷歌地图 Api相当新。 我有一个数据数组,我想在地图上循环和 plot 。 看起来相当简单,但我发现的所有multi-marker教程都相当复杂。

让我们使用来自谷歌站点的数据数组为例:


var locations = [
 ['Bondi Beach', -33.890542, 151.274856, 4],
 ['Coogee Beach', -33.923036, 151.259052, 5],
 ['Cronulla Beach', -34.028249, 151.157507, 3],
 ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
 ['Maroubra Beach', -33.950198, 151.259302, 1]
];

我只想 plot的所有这些点,并有一个infoWindow弹出,当点击显示名称。

我们感激任何方式的协助。

时间:

这是我可以减少到的最简单的:


<!DOCTYPE html>
<html> 
<head> 
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
 <title>Google Maps Multiple Markers</title> 
 <script src="http://maps.google.com/maps/api/js?sensor=false" 
 type="text/javascript"></script>
</head> 
<body>
 <div id="map" style="width: 500px; height: 400px;"></div>

 <script type="text/javascript">
 var locations = [
 ['Bondi Beach', -33.890542, 151.274856, 4],
 ['Coogee Beach', -33.923036, 151.259052, 5],
 ['Cronulla Beach', -34.028249, 151.157507, 3],
 ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
 ['Maroubra Beach', -33.950198, 151.259302, 1]
 ];

 var map = new google.maps.Map(document.getElementById('map'), {
 zoom: 10,
 center: new google.maps.LatLng(-33.92, 151.25),
 mapTypeId: google.maps.MapTypeId.ROADMAP
 });

 var infowindow = new google.maps.InfoWindow();

 var marker, i;

 for (i = 0; i <locations.length; i++) { 
 marker = new google.maps.Marker({
 position: new google.maps.LatLng(locations[i][1], locations[i][2]),
 map: map
 });

 google.maps.event.addListener(marker, 'click', (function(marker, i) {
 return function() {
 infowindow.setContent(locations[i][0]);
 infowindow.open(map, marker);
 }
 })(marker, i));
 }
 </script>
</body>
</html>

屏幕截图:

Google Maps Multiple Markers

将回调参数传递给 addListener 方法时,出现了一些关闭魔术。 如果你不熟悉闭包的工作方式,这可能是一个棘手的话题。 如果是这种情况,我建议你查看以下Mozilla文章以获得简要介绍:

下面是使用独特的titleinfoWindow 文本加载多个标记的另一个例子。 使用最新的谷歌地图 API V3.11 测试


<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 <title>Multiple Markers Google Maps</title>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
 <script src="https://maps.googleapis.com/maps/api/js?v=3.11&sensor=false" type="text/javascript"></script>
 <script type="text/javascript">
//check DOM Ready
 $(document).ready(function() {
//execute
 (function() {
//map options
 var options = {
 zoom: 5,
 center: new google.maps.LatLng(39.909736, -98.522109),//centered US
 mapTypeId: google.maps.MapTypeId.TERRAIN,
 mapTypeControl: false
 };

//init map
 var map = new google.maps.Map(document.getElementById('map_canvas'), options);

//NY and CA sample Lat/Lng
 var southWest = new google.maps.LatLng(40.744656, -74.005966);
 var northEast = new google.maps.LatLng(34.052234, -118.243685);
 var lngSpan = northEast.lng() - southWest.lng();
 var latSpan = northEast.lat() - southWest.lat();

//set multiple marker
 for (var i = 0; i <250; i++) {
//init markers
 var marker = new google.maps.Marker({
 position: new google.maps.LatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random()),
 map: map,
 title: 'Click Me ' + i
 });

//process multiple info windows
 (function(marker, i) {
//add click event
 google.maps.event.addListener(marker, 'click', function() {
 infowindow = new google.maps.InfoWindow({
 content: 'Hello, World!!'
 });
 infowindow.open(map, marker);
 });
 })(marker, i);
 }
 })();
 });
 </script>
 </head>
 <body>
 <div id="map_canvas" style="width: 800px; height:500px;"></div>
 </body>
</html>

250标记的屏幕截图

Google Maps API V3.11 with Multiple Markers

它将自动随机化纬度/lng,使之唯一。 如果你想测试 500,1000,xxx标记和性能,示例将非常有用。

我想我应该把它放在这里,因为它是那些开始使用 谷歌地图的流行的登陆点 客户端呈现多个标记可能是许多映射应用程序性能的下降。 很难进行基准测试,修复和在某些情况下甚至建立一个问题( 由于浏览器实现的差异,可以供客户端,移动设备和列表使用的硬件) 。

解决这个问题的最简单方法是使用标记群集解决方案。 基本的想法是将地理相似的位置分组成一个组,其中显示了点数。 当用户放大地图时,这些组展开以显示下面的单个标记。

也许最简单的实现是 markerclusterer 库。 基本实现如下( 库导入后):


<script type="text/javascript">
 function initialize() {
 var center = new google.maps.LatLng(37.4419, -122.1419);

 var map = new google.maps.Map(document.getElementById('map'), {
 zoom: 3,
 center: center,
 mapTypeId: google.maps.MapTypeId.ROADMAP
 });

 var markers = [];
 for (var i = 0; i <100; i++) {
 var location = yourData.location[i];
 var latLng = new google.maps.LatLng(location.latitude,
 location.longitude);
 var marker = new google.maps.Marker({
 position: latLng
 });
 markers.push(marker);
 }
 var markerCluster = new MarkerClusterer(map, markers);
 }
 google.maps.event.addDomListener(window, 'load', initialize);
</script>

将标记添加到映射中而不是直接添加到映射中。 这里数组随后被传递到库,该库处理复杂的计算并附加到映射。

不仅这些实现大规模增加客户端性能,但在许多情况下他们也导致ui更简单、更简洁和容易消化在大尺度下的数据。

其他实现 web 可以从谷歌获得。

希望这有助于一些新的映射细节。

地图API示例:


function initialize() {
 var myOptions = {
 zoom: 10,
 center: new google.maps.LatLng(-33.9, 151.2),
 mapTypeId: google.maps.MapTypeId.ROADMAP
 }
 var map = new google.maps.Map(document.getElementById("map_canvas"),
 myOptions);

 setMarkers(map, beaches);
}

/**
 * Data for the markers consisting of a name, a LatLng and a zIndex for
 * the order in which these markers should display on top of each
 * other.
 */
var beaches = [
 ['Bondi Beach', -33.890542, 151.274856, 4],
 ['Coogee Beach', -33.923036, 151.259052, 5],
 ['Cronulla Beach', -34.028249, 151.157507, 3],
 ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
 ['Maroubra Beach', -33.950198, 151.259302, 1]
];

function setMarkers(map, locations) {
//Add markers to the map

//Marker sizes are expressed as a Size of X,Y
//where the origin of the image (0,0) is located
//in the top left of the image.

//Origins, anchor positions and coordinates of the marker
//increase in the X direction to the right and in
//the Y direction down.
 var image = new google.maps.MarkerImage('images/beachflag.png',
//This marker is 20 pixels wide by 32 pixels tall.
 new google.maps.Size(20, 32),
//The origin for this image is 0,0.
 new google.maps.Point(0,0),
//The anchor for this image is the base of the flagpole at 0,32.
 new google.maps.Point(0, 32));
 var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
//The shadow image is larger in the horizontal dimension
//while the position and offset are the same as for the main image.
 new google.maps.Size(37, 32),
 new google.maps.Point(0,0),
 new google.maps.Point(0, 32));
//Shapes define the clickable region of the icon.
//The type defines an HTML &lt;area&gt; element 'poly' which
//traces out a polygon as a series of X,Y points. The final
//coordinate closes the poly by connecting to the first
//coordinate.
 var shape = {
 coord: [1, 1, 1, 20, 18, 20, 18, 1],
 type: 'poly'
 };
 for (var i = 0; i <locations.length; i++) {
 var beach = locations[i];
 var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
 var marker = new google.maps.Marker({
 position: myLatLng,
 map: map,
 shadow: shadow,
 icon: image,
 shape: shape,
 title: beach[0],
 zIndex: beach[3]
 });
 }
}

异步版本:


<script type="text/javascript">
 function initialize() {
 var locations = [
 ['Bondi Beach', -33.890542, 151.274856, 4],
 ['Coogee Beach', -33.923036, 151.259052, 5],
 ['Cronulla Beach', -34.028249, 151.157507, 3],
 ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
 ['Maroubra Beach', -33.950198, 151.259302, 1]
 ];

 var map = new google.maps.Map(document.getElementById('map'), {
 zoom: 10,
 center: new google.maps.LatLng(-33.92, 151.25),
 mapTypeId: google.maps.MapTypeId.ROADMAP
 });

 var infowindow = new google.maps.InfoWindow();

 var marker, i;

 for (i = 0; i <locations.length; i++) { 
 marker = new google.maps.Marker({
 position: new google.maps.LatLng(locations[i][1], locations[i][2]),
 map: map
 });

 google.maps.event.addListener(marker, 'click', (function(marker, i) {
 return function() {
 infowindow.setContent(locations[i][0]);
 infowindow.open(map, marker);
 }
 })(marker, i));
 }
}

function loadScript() {
 var script = document.createElement('script');
 script.type = 'text/javascript';
 script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +
 'callback=initialize';
 document.body.appendChild(script);
}

window.onload = loadScript;
 </script>

This is the working example map image


var arr = new Array();
 function initialize() { 
 var i; 
 var Locations = [
 {
 lat:48.856614, 
 lon:2.3522219000000177, 
 address:'Paris',
 gval:'25.5',
 aType:'Non-Commodity',
 title:'Paris',
 descr:'Paris' 
 }, 
 {
 lat: 55.7512419, 
 lon: 37.6184217,
 address:'Moscow',
 gval:'11.5',
 aType:'Non-Commodity',
 title:'Moscow',
 descr:'Moscow Airport' 
 }, 

 {
 lat:-9.481553000000002, 
 lon:147.190242, 
 address:'Port Moresby',
 gval:'1',
 aType:'Oil',
 title:'Papua New Guinea',
 descr:'Papua New Guinea 123123123' 
 },
 {
 lat:20.5200,
 lon:77.7500,
 address:'Indore',
 gval:'1',
 aType:'Oil',
 title:'Indore, India',
 descr:'Airport India'
 }
 ];

 var myOptions = {
 zoom: 2,
 center: new google.maps.LatLng(51.9000,8.4731),
 mapTypeId: google.maps.MapTypeId.ROADMAP
 };

 var map = new google.maps.Map(document.getElementById("map"), myOptions);

 var infowindow = new google.maps.InfoWindow({
 content: ''
 });

 for (i = 0; i <Locations.length; i++) {
 size=15; 
 var img=new google.maps.MarkerImage('marker.png', 
 new google.maps.Size(size, size),
 new google.maps.Point(0,0),
 new google.maps.Point(size/2, size/2)
 );

 var marker = new google.maps.Marker({
 map: map,
 title: Locations[i].title,
 position: new google.maps.LatLng(Locations[i].lat, Locations[i].lon), 
 icon: img
 });

 bindInfoWindow(marker, map, infowindow,"<p>" + Locations[i].descr +"</p>",Locations[i].title); 

 }

}

function bindInfoWindow(marker, map, infowindow, html, Ltitle) { 
 google.maps.event.addListener(marker, 'mouseover', function() {
 infowindow.setContent(html); 
 infowindow.open(map, marker); 

 });
 google.maps.event.addListener(marker, 'mouseout', function() {
 infowindow.close();

 }); 
} 

完全工作示例你只需复制粘贴并使用。

这是另一个版本我写保存地图房地产、地方infowindow指针在实际lat和长标记,虽然暂时隐藏标记infowindow时显示。

它还去掉了标准的'标记'赋值并通过在标记创建的标记数组中直接分配新标记加速处理。 但是注意,附加属性已经添加到标记和infowindow中,所以这种方法有点非常规。 那就是我 !

中没有提到这些infowindow问题,标准infowindow不是放在标记点的纬度和液化天然气,而顶部的标志形象。 必须隐藏标记可见性才能使它的正常工作,否则映射API将把infowindow锚推回标记图像的顶部。

对'标记'数组中的标记的引用在标记声明中立即创建,用于任何可能需要的额外处理任务。 这保存了将标记对象分配给'标记'的额外步骤,然后将'标记'推送到标记数组。。 我的书中大量不必要的处理。

无论如何,对infowindows有一个不同的选择,希望它能帮助你和激发你的灵感。


 var locations = [
 ['Bondi Beach', -33.890542, 151.274856, 4],
 ['Coogee Beach', -33.923036, 151.259052, 5],
 ['Cronulla Beach', -34.028249, 151.157507, 3],
 ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
 ['Maroubra Beach', -33.950198, 151.259302, 1]
 ];
 var map;
 var markers = [];

 function init(){
 map = new google.maps.Map(document.getElementById('map_canvas'), {
 zoom: 10,
 center: new google.maps.LatLng(-33.92, 151.25),
 mapTypeId: google.maps.MapTypeId.ROADMAP
 });

 var num_markers = locations.length;
 for (var i = 0; i <num_markers; i++) { 
 markers[i] = new google.maps.Marker({
 position: {lat:locations[i][1], lng:locations[i][2]},
 map: map,
 html: locations[i][0],
 id: i,
 });

 google.maps.event.addListener(markers[i], 'click', function(){
 var infowindow = new google.maps.InfoWindow({
 id: this.id,
 content:this.html,
 position:this.getPosition()
 });
 google.maps.event.addListenerOnce(infowindow, 'closeclick', function(){
 markers[this.id].setVisible(true);
 });
 this.setVisible(false);
 infowindow.open(map);
 });
 }
 }

google.maps.event.addDomListener(window, 'load', init);

这是一个工作JSFiddle编辑器

额外注意
在这个给定的例子中,你会注意到'位置'数组中的第四个位置有一个数字。 在本例中,你还可以使用这个值来代替当前循环值的标记标识,这样。


var num_markers = locations.length;
for (var i = 0; i <num_markers; i++) { 
 markers[i] = new google.maps.Marker({
 position: {lat:locations[i][1], lng:locations[i][2]},
 map: map,
 html: locations[i][0],
 id: locations[i][3],
 });
};

...