php Google Maps V3 在确切位置上重叠标记
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19821198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Google Maps V3 Overlapping Markers on exact Location
提问by Learning
I am having issues with markers overlapping, please do not down vote as I am not highly schooled in javascript also I have looked at the different answers offered on stackoverflow but have not been able to use them to find a solution so please help! The code is grabbing php for lat and long based on static points I have given I would simply like to list all of the information in the same marker rather than have it overlap markers any help would be highly appreciated here is the code:
我遇到了标记重叠的问题,请不要投反对票,因为我在 javascript 方面没有受过高等教育,我也看过 stackoverflow 上提供的不同答案,但无法使用它们来找到解决方案,所以请帮忙!代码根据我给出的静态点抓取 php 纬度和经度 我只想在同一个标记中列出所有信息,而不是让它重叠标记任何帮助都将受到高度赞赏,这里是代码:
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<META HTTP-EQUIV="refresh" >
<title>Operations</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=APIKEY&sensor=false"></script>
<script src="oms.min.js"></script>
<script type="text/javascript">
//<![CDATA[
var customIcons = {
restaurant: { icon: 'mm_20_blue.png' },
bar: { icon: 'mm_20_blue.png' }
};
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(32.298342, -64.791098),
zoom: 17,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
var infoWindow = new google.maps.InfoWindow;
// Change this depending on the name of your PHP file
downloadUrl("genxml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var id = markers[i].getAttribute("permitnumber");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address + "<br/>" + '<a href="http://server/editform.php?find=' + id + '" >More Info</a> <br/> <form action="del.php" method="post" enctype="multipart/form-data"> <input type="checkbox" name="checkbox" id="checkbox" value="' + id +'"> <input name="delete" type="submit" id="delete" value="Delete"> ' ;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow,
animation: google.maps.Animation.BOUNCE
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
//]]>
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js" type="text/javascript"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-24568877-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google- analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body onload="load()" bgcolor="#A8F748" >
<div id="map" style="margin:auto; width: 90%; height: 470px"></div>
</body>
采纳答案by Learning
I have found a solution through much searching and thanks to posts by @geocodezip , I am still having one small problem when zooming into the markers any marker thats directly on another will stay in clustered mode, I would like to achieve the infoWindow sharing both markers content any help would be awesome , thanks again geocodezip for your posts!
我通过大量搜索找到了一个解决方案,感谢@geocodezip 的帖子,在放大标记时我仍然遇到一个小问题,任何直接在另一个标记上的标记都将保持集群模式,我想实现信息窗口共享两个标记内容任何帮助都会很棒,再次感谢 geocodezip 的帖子!
<!DOCTYPE html >
<head>
<meta charset="utf-8"/>
<title>Google Maps API V3 with Marker Manager</title>
<meta name="description" content="Google Maps API V3 with MarkerCluster, Coincident Markers Share Infowindow" />
<meta name="keywords" content="google maps api v3, markerclusterer, markers, infowindow" />
<meta name="author" content="Casey P. Thomas" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://maps.caseypthomas.org/markerclusterer.js"></script>
<script type="text/javascript">
//<![CDATA[
var map;
//marker clusterer
var mc;
var mcOptions = {gridSize: 20, maxZoom: 17};
var markers;
//global infowindow
var infowindow = new google.maps.InfoWindow();
//geocoder
var geocoder = new google.maps.Geocoder();
var customIcons = {
restaurant: {
icon: 'mm_20_blue.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
},
bar: {
icon: 'mm_20_blue.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
}
};
function load() {
var cluster = [];
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(32.298342, -64.791098),
zoom: 13,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
var infowindow = new google.maps.InfoWindow();
// Change this depending on the name of your PHP file
downloadUrl("genxml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var id = markers[i].getAttribute("permitnumber");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address + "<br/>" + '<a href="http://server/editform.php?find=' + id + '" >More Info</a> <br/> <form action="del.php" method="post" enctype="multipart/form-data"> <input type="checkbox" name="checkbox" id="checkbox" value="' + id +'"> <input name="delete" type="submit" id="delete" value="Delete"> ' ;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow,
animation: google.maps.Animation.BOUNCE
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
var id = markers[i].getAttribute("permitnumber");
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
infowindow.setContent("<b>" + name + "</b> <br/>" + address + "<br/>" + '<a href="http://server/editform.php?find=' + id + '" >More Info</a> <br/> <form action="del.php" method="post" enctype="multipart/form-data"> <input type="checkbox" name="checkbox" id="checkbox" value="' + id +'"> <input name="delete" type="submit" id="delete" value="Delete"> ');
infowindow.open(map, marker);
}
})(marker, i));
cluster.push(marker);
}
var mc = new MarkerClusterer(map,cluster);
});
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
//]]>
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js" type="text/javascript"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-24568877-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google- analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body onload="load()" bgcolor="#A8F748" >
<div id="map" style="margin:auto; width: 90%; height: 470px"></div>
</body>
</html>
回答by Wayne Whitty
If you don't want markers overlapping, you'll probably need to use google-maps-utility-library-v3. It has a feature called Marker Clusterer, which basically allows you to put nearby markers into one singular marker. It can be configured so that these markers reappear as separate entities once the user has zoomed in far enough. Here's an advanced demo.
如果您不希望标记重叠,则可能需要使用google-maps-utility-library-v3。它有一项称为 Marker Clusterer 的功能,它基本上允许您将附近的标记放入一个单一的标记中。可以对其进行配置,以便一旦用户放大到足够远,这些标记就会作为单独的实体重新出现。这是一个高级演示。
回答by Vince Lowe
回答by MazarD
You can use the MarkerClusterer from google maps utility library.
您可以使用谷歌地图实用程序库中的 MarkerClusterer。
Here is a step by step example: https://developers.google.com/maps/documentation/javascript/marker-clustering
这是一个分步示例:https: //developers.google.com/maps/documentation/javascript/marker-clustering
And you can download the library from the google maps github repo: https://github.com/googlemaps/v3-utility-library/tree/master/markerclusterer
您可以从 google maps github repo 下载库:https: //github.com/googlemaps/v3-utility-library/tree/master/markerclusterer
回答by Neil Bauers
Add small random numbers to the marker latitude and longitude.
向标记纬度和经度添加小的随机数。
This displaces the overlapping markers around their correct position. When zoomed in, the markers will separate. Smaller random numbers improve accuracy but more zooming in is needed. Also alter the marker icon or label to indicate it's overlapping.
这会在正确位置周围移动重叠标记。放大时,标记将分开。较小的随机数提高了准确性,但需要更多的放大。还要更改标记图标或标签以指示其重叠。
In this example, four different markers are used. If there are more than 4 overlapping points, the slight randomization is added.
在本例中,使用了四种不同的标记。如果重叠点超过 4 个,则添加轻微随机化。
Example: http://waveneyramblers.org.uk/walks/next_eight_days
示例:http: //waveneyramblers.org.uk/walks/next_eight_days
View source to see the JavaScript.
查看源代码以查看 JavaScript。
回答by Sitaram
Here is a solution without using any libraries but just simple javascript as a workaround for the overlapping issue.
这是一个不使用任何库的解决方案,而只是简单的 javascript 作为重叠问题的解决方法。
It opens an infowindow only on the markers which has more then 1 markers at the same lat and lng
它仅在标记上打开一个信息窗口,该标记在相同的纬度和经度上有超过 1 个标记
var maplocations = [["1200", "52.50752849999999", "13.471243500000014", "96063", "No", 1],
["12", "52.50752849999999", "13.471243500000014", "198866", "No", 1],
["12", "52.504747174113696", "13.420449523925754", "228262", "No", 1],
["888", "52.5024031", "13.377901000000065", "228317", "No", 1]]
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(52.530339,13.347451),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
groupedMapList=[];
for(var i=0;i<maplocations.length;i++){
if(!groupedMapList.find(item => item[1] == maplocations[i][1] && item[2]== maplocations[i][2])){
groupedMapList.push(maplocations[i])
}else{
let valueIndex = groupedMapList.findIndex(item => item[1] == maplocations[i][1] && item[2]== maplocations[i][2]);
groupedMapList[valueIndex][5] = groupedMapList[valueIndex][5] + 1;
}
}
You will get a grouped list which needs to be mapped on the map. Add infowindow only to the items which are more than 1 - "groupedMapList[i][5]>1"
您将获得需要在地图上映射的分组列表。仅向大于 1 的项目添加信息窗口 - “groupedMapList[i][5]>1”
var groupedMapList = [ ["1200", "52.50752849999999", "13.471243500000014", "96063", "No", 2], ["12", "52.504747174113696", "13.420449523925754", "228262", "No", 1], ["888", "52.5024031", "13.377901000000065", "228317", "No", 1]]
var groupedMapList = [ ["1200", "52.50752849999999", "13.471243500000014", "96063", "No", 2], ["12", "52.5047471741130000014", "No", 2], ["12", "52.5047471741130000014", "No", 25, 52.50474717411300000014"2007"236"24295" ]、[“888”、“52.5024031”、“13.377901000000065”、“228317”、“否”、1]]
var infowindow = new google.maps.InfoWindow();
// var bounds = new google.maps.LatLngBounds();
var marker, i;
var prevId;
var prevMarker;
for(i=0;i<groupedMapList.length;i++){
marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(groupedMapList[i][1]), parseFloat(groupedMapList[i][2])),
label: {text: groupedMapList[i][0], color: "black"},
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
//reset previous marker
if(prevMarker)
{
var label = prevMarker.getLabel();
label.color="black";
prevMarker.setLabel(label);
prevMarker.setZIndex();
infowindow.close();
}
if(groupedMapList[i][5] > 1){
let contentString = '<div id="content">'+ '<b>'+ groupedMapList[i][5] +' Apartments</b></div>'
infowindow.setContent(contentString);
infowindow.open(map, marker);
}
prevId = groupedMapList[i][3];
prevMarker = this;
var label = this.getLabel();
label.color="white";
this.setLabel(label);
this.setZIndex(1001);
}
})(marker, i));
}
}