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 stackoverfl
I use this - https://github.com/jawj/OverlappingMarkerSpiderfier
See a demo here - http://jawj.github.io/OverlappingMarkerSpiderfier/demo.html
You can use the MarkerClusterer from google maps utility library.
Here is a step by step example: 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
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.
Example: http://waveneyramblers.org.uk/walks/next_eight_days
View source to see the JavaScript.
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!
<!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>
Here is a solution without using any libraries but just simple javascript as a workaround for the overlapping issue.
It opens an infowindow only on the markers which has more then 1 markers at the same lat and lng
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"
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 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));
}
}
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 a demo.