问题
I am creating a google map that is populated with markers based upon information from my database. I have followed the tutorial provided from Google in this first step.
The map works fine, however since some of my markers are close together, I would like to take advantage of marker clustering. I’ve followed what I can from Google's tutorial on marker clustering.
However, I cannot find a way to get it to work. My markers just show up the way they are, without any clustering. I think I have followed all of the steps, linking the JS file to my HTML, downloading and uploading the marker icons and JS file to my hosting site, etc.
How can I continue to create markers from my database, but also cluster the markers?
I have tested the exact code from the google marker clusterer tutorial, and everything works fine. (However the markers are not in the locations I need.)
A simplified version of my HTML(PHP) webpage is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Website</title>
<style>
map {
height: 400px;
width: 98%;
border: 5px outset SteelBlue;
}
</style>
</head>
<body>
<!-- Google Map -->
<div id='map'>
</div>
<!-- Google MAPS API & Custom Maps JS-->
<!-- This is my personal file that houses the main Javascript code -->
<script src="findermap.js"></script>
<!-- A link to download this file is provided by the Google tutorial -->
<script src="markerclusterer.js"></script>
<!-- Basic Google Maps API key link -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MY-KEY-IS-USED-HERE&callback=initMap">
</script>
</body>
</html>
Here is basically the JavaScript file I use, "findermap.js"
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(0, 0),
zoom: 1
});
var customIcons = {
type1: {
icon: 'icon_type1.png'
},
type2: {
icon: 'icon_type2.png'
},
type3: {
icon: 'icon_type3.png'
},
type4: {
icon: 'icon_type4.png'
}
};
var markers = [];
var infoWindow = new google.maps.InfoWindow;
// Change this depending on the name of your PHP or XML file
downloadUrl('https://my-website.com/getinfo.php', function(data) {
var xml = data.responseXML;
var markers2 = xml.documentElement.getElementsByTagName('marker');
Array.prototype.forEach.call(markers2, function(markerElem) {
var name = markerElem.getAttribute('name');
var address = markerElem.getAttribute('address');
var type = markerElem.getAttribute('type');
var point = new google.maps.LatLng(
parseFloat(markerElem.getAttribute('lat')),
parseFloat(markerElem.getAttribute('lng')));
var infowincontent = document.createElement('div');
var strong = document.createElement('strong');
strong.textContent = name
infowincontent.appendChild(strong);
infowincontent.appendChild(document.createElement('br'));
var text = document.createElement('text');
text.textContent = address
infowincontent.appendChild(text);
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
label: icon.label
});
marker.addListener('click', function() {
infoWindow.setContent(infowincontent);
infoWindow.open(map, marker);
});
markers.push(marker);
});
});
var options = {
imagePath: '/clustericons/m'
};
// Add a marker clusterer to manage the markers.
var markerCluster = new MarkerClusterer(map, markers, options);
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('getinfo.php') :
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() {}
回答1:
I Found it! Here is the solution. This is the updated javascript file:
var customIcons = {
type1: {
icon: 'icon_type1.png'
},
type2: {
icon: 'icon_type2.png'
},
type3: {
icon: 'icon_type3.png'
},
type4: {
icon: 'icon_type4.png'
}
};
function initMap() {
var cluster = [];
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(0, 0),
zoom: 1,
mapTypeId: 'roadmap'
});
var infowindow = new google.maps.InfoWindow();
// Change this depending on the name of your PHP file
downloadUrl('https://my-website.com/the-sweet-sweet-xml-info.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 point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html= "<b>" +
markers[i].getAttribute("name") +
"</b> <br/>" +
markers[i].getAttribute("address");
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(
"<b>" +
markers[i].getAttribute("name") +
"</b> <br/>" +
markers[i].getAttribute("address")
);
infowindow.open(map, marker);
//This sends information from the clicked icon back to the serverside code
document.getElementById("setlatlng").innerHTML = markers[i].getAttribute("name");
}
})(marker, i));
cluster.push(marker);
}
var options = {
imagePath: '/location-of-cluster-icons/m'
};
var mc = new MarkerClusterer(map,cluster,options);
});
}
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('the-sweet-sweet-xml-info.php') :
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() {}
回答2:
thankyou for the answer it is really helpful. also i want to add another feature, which is marker clusterer calculator. i find it on the other page also. so basicly it helps to make the clustering color more even by the total amount of data that you guys stored in database.
A simplified version of script is as follows:
<script>
var customIcons = {
type1: {
icon: 'icon_type1.png'
},
type2: {
icon: 'icon_type2.png'
},
type3: {
icon: 'icon_type3.png'
},
type4: {
icon: 'icon_type4.png'
}
};
function initMap() {
var cluster = [];
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(-7.952361, 110.619003),
zoom: 10,
mapTypeId: 'roadmap'
});
var infowindow = new google.maps.InfoWindow();
// Change this depending on the name of your PHP file
downloadUrl('http://localhost/try/dashboard/examples/xml.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 point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html= "<b>" +
markers[i].getAttribute("name") +
"</b> <br/>" +
markers[i].getAttribute("address");
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(
"<b>" +
markers[i].getAttribute("name") +
"</b> <br/>" +
markers[i].getAttribute("address")
);
infowindow.open(map, marker);
//This sends information from the clicked icon back to the serverside code
document.getElementById("setlatlng").innerHTML = markers[i].getAttribute("name");
}
})(marker, i));
cluster.push(marker);
}
var options = {
imagePath: '/location-of-cluster-icons/m'
};
var markerCluster = new MarkerClusterer(map, cluster,
{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
// For Cluster Calculator
markerCluster.setCalculator(function(markers, numStyles){
//create an index for icon styles
var index = 0,
//Count the total number of markers in this cluster
count = markers.length,
//Set total to loop through (starts at total number)
total = count;
/**
* While we still have markers, divide by a set number and
* increase the index. Cluster moves up to a new style.
*
* The bigger the index, the more markers the cluster contains,
* so the bigger the cluster.
*/
while (total !== 0) {
//Create a new total by dividing by a set number
total = parseInt(total / 5, 10);
//Increase the index and move up to the next style
index++;
}
/**
* Make sure we always return a valid index. E.g. If we only have
* 5 styles, but the index is 8, this will make sure we return
* 5. Returning an index of 8 wouldn't have a marker style.
*/
index = Math.min(index, numStyles);
//Tell MarkerCluster this clusters details (and how to style it)
return {
text: count,
index: index
};
});
// END OF CLUSTER CALCULATOR
});
}
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('the-sweet-sweet-xml-info.php') :
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>
来源:https://stackoverflow.com/questions/43104209/cluster-markers-with-google-maps-api-locations-from-database