javascript - google map api教程
Google Maps JS API v3-简单多标记示例 (8)
Google Maps Api相当新颖。 我有一系列我想循环访问的数据并绘制在地图上。 看起来相当简单,但我发现的所有多标记教程都非常复杂。
举个例子,我们使用谷歌网站的数据数组:
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]
];
我只想绘制所有这些点,并单击显示名称时弹出一个infoWindow。
接受的答案,在ES6中重写:
$(document).ready(() => {
const mapEl = $('#our_map').get(0); // OR document.getElementById('our_map');
// Display a map on the page
const map = new google.maps.Map(mapEl, { mapTypeId: 'roadmap' });
const buildings = [
{
title: 'London Eye, London',
coordinates: [51.503454, -0.119562],
info: 'carousel'
},
{
title: 'Palace of Westminster, London',
coordinates: [51.499633, -0.124755],
info: 'palace'
}
];
placeBuildingsOnMap(buildings, map);
});
const placeBuildingsOnMap = (buildings, map) => {
// Loop through our array of buildings & place each one on the map
const bounds = new google.maps.LatLngBounds();
buildings.forEach((building) => {
const position = { lat: building.coordinates[0], lng: building.coordinates[1] }
// Stretch our bounds to the newly found marker position
bounds.extend(position);
const marker = new google.maps.Marker({
position: position,
map: map,
title: building.title
});
const infoWindow = new google.maps.InfoWindow();
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', () => {
infoWindow.setContent(building.info);
infoWindow.open(map, marker);
})
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
})
})
在你的程序中添加一个标记非常简单。 你只需要添加下面的代码:
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
构建标记时,以下字段特别重要且通常设置:
-
position
(必需)指定标识标记初始位置的LatLng。 检索LatLng的一种方法是使用地理编码服务 。 -
map
(可选)指定放置标记的地图。 如果您未在标记的构造中指定地图,则会创建标记但未附加到地图上(或显示在地图上)。 稍后可以通过调用标记的setMap()
方法来添加标记。
请注意 ,在示例中,标题字段设置标记的标题,该标题将显示为工具提示。
您可以在here查阅Google API文档。
这是在地图中设置一个标记的完整示例。 请注意,您必须使用您的Google API密钥替换YOUR_API_KEY
:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple markers</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
function initMap() {
var myLatLng = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
现在,如果你想在地图上绘制一个数组的标记,你应该这样做:
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]
];
function initMap() {
var myLatLng = {lat: -33.90, lng: 151.16};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: myLatLng
});
var count;
for (count = 0; count < locations.length; count++) {
new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map,
title: locations[count][0]
});
}
}
这个例子给了我以下结果:
你也可以在你的pin中添加一个infoWindow。 你只需要这个代码:
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: 'Hello World!'
});
你可以在here有关infoWindows的Google文档。
现在,当标记为“clik”时,我们可以打开infoWindow:
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: locations [count][0]
});
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
请注意 ,您可以在Google开发人员处获得关于Listener
一些文档。
最后,如果用户点击它,我们可以在标记中绘制一个infoWindow。 这是我完整的代码:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Info windows</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
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]
];
// When the user clicks the marker, an info window opens.
function initMap() {
var myLatLng = {lat: -33.90, lng: 151.16};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: myLatLng
});
var count=0;
for (count = 0; count < locations.length; count++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: locations [count][0]
});
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
}
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
</body>
</html>
通常情况下,你应该有这样的结果:
我想我会把它放在这里,因为它似乎是开始使用Google地图API的人的着名点。 客户端呈现的多个标记可能是许多映射应用程序性能明智的倒台。 很难进行基准测试,修复以及在某些情况下甚至确定存在问题(由于浏览器实施差异,客户端可用的硬件,移动设备,列表不断)。
开始解决这个问题最简单的方法是使用标记群集解决方案。 基本想法是将地理位置相似的位置分组为具有显示点数的组。 随着用户放大地图,这些组将展开以显示下方的各个标记。
也许最简单的实现是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>
这些标记不是直接添加到地图中,而是添加到数组中。 然后将该数组传递给处理复杂计算的库并附加到地图上。
这些实现不仅大大提高了客户端性能,而且在很多情况下还导致了更简单,更简洁的用户界面以及更大规模的数据消化。
其他实现可从Google获得。
希望这可以帮助那些更新的映射的细微差别。
来自Google Map 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 <area> 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]
});
}
}
这是使用独特title
和infoWindow
文本加载多个标记的另一个示例。 使用最新的谷歌地图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标记的屏幕截图:
它会自动将Lat / Lng随机化,使其具有独特性。 如果要测试500,1000,xxx标记和性能,此示例将非常有用。
这是我写的另一个版本,用于保存地图的不动产,将infowindow指针放置在标记的实际经度和长度上,同时临时隐藏标记,同时显示infowindow。
它也不需要标准的“标记”分配,并通过直接将新标记分配给标记创建上的标记数组来加快处理速度。 但是请注意,标记和infowindow都添加了其他属性,因此这种方法是非常规的......但这就是我!
这些infowindow问题中从未提及过,标准infowindow 不是放置在标记点的lat和lng处,而是放置在标记图像的顶部。 标记可见性必须隐藏起来才能起作用,否则Google Maps 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
附加说明
在给定的Google示例数据中,您会注意到'locations'数组中的第四个数字。 在这个例子中,你也可以使用这个值来代替当前循环的标记id,例如...
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],
});
};
这里有一个几乎完整的示例javascript函数,它将允许在JSONObject中定义多个标记。
它只会显示地图边界中的标记。
这很重要,所以你没有做额外的工作。
您还可以设置标记的限制,以便不显示极端数量的标记(如果在您的使用中可能存在某种事物);
如果地图的中心没有改变超过500米,它也不会显示标记。
这很重要,因为如果用户点击标记并意外拖动地图,则不希望地图重新加载标记。
我将此函数附加到地图的空闲事件侦听器,以便标记仅在地图空闲时才会显示,并且会在不同事件之后重新显示标记。
在动作屏幕截图中,屏幕截图有一些变化,显示了infowindow中的更多内容。 从pastbin.com粘贴
<script src="//pastebin.com/embed_js/uWAbRxfg"></script>
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();
});
}
充分的工作例子。 你可以复制,粘贴和使用。