Reputation: 21
i have been useing a map with markers from sql db and would like to add marker clusters as i get more markers.
on it self the code for the map and the code for the marker cluster from https://developers.google.com/maps/documentation/javascript/marker-clustering#maps_marker_clustering-javascript works fine, i have tried to combain them and keep geting a map with no markers .
this is the cluster map from google which works fine
<!DOCTYPE html>
<html>
<head>
<title>Marker Clustering</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCRLmpZiLZ9e-p6wRbwGWH6_1AS5M31vSI&callback=initMap&libraries=&v=weekly"
defer
></script>
<style type="text/css">
/* 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>
<script>
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 2,
center: { lat: -28.024, lng: 140.887 },
});
// Create an array of alphabetical characters used to label the markers.
const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Add some markers to the map.
// Note: The code uses the JavaScript Array.prototype.map() method to
// create an array of markers based on a given "locations" array.
// The map() method here has nothing to do with the Google Maps API.
const markers = locations.map((location, i) => {
return new google.maps.Marker({
position: location,
label: labels[i % labels.length],
});
});
// Add a marker clusterer to manage the markers.
new MarkerClusterer(map, markers, {
imagePath:
"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
});
}
const locations = [
{ lat: -31.56391, lng: 147.154312 },
{ lat: -33.718234, lng: 150.363181 },
{ lat: -33.727111, lng: 150.371124 },
{ lat: -33.848588, lng: 151.209834 },
{ lat: -33.851702, lng: 151.216968 },
{ lat: -34.671264, lng: 150.863657 },
{ lat: -35.304724, lng: 148.662905 },
{ lat: -36.817685, lng: 175.699196 },
{ lat: -36.828611, lng: 175.790222 },
{ lat: -37.75, lng: 145.116667 },
{ lat: -37.759859, lng: 145.128708 },
{ lat: -37.765015, lng: 145.133858 },
{ lat: -37.770104, lng: 145.143299 },
{ lat: -37.7737, lng: 145.145187 },
{ lat: -37.774785, lng: 145.137978 },
{ lat: -37.819616, lng: 144.968119 },
{ lat: -38.330766, lng: 144.695692 },
{ lat: -39.927193, lng: 175.053218 },
{ lat: -41.330162, lng: 174.865694 },
{ lat: -42.734358, lng: 147.439506 },
{ lat: -42.734358, lng: 147.501315 },
{ lat: -42.735258, lng: 147.438 },
{ lat: -43.999792, lng: 170.463352 },
];
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
this is the map i use with db markers and works fine
<?php
include("classes/user-map.php");
?>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link rel="stylesheet" href="css/user-map.css" type="text/css"/>
</head>
<body>
<!-- google API &key= -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript"src="https://maps.googleapis.com/maps/api/js?language=en&key=AIzaSyCRLmpZiLZ9e-p6wRbwGWH6_1AS5M31vSI"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCRLmpZiLZ9e-p6wRbwGWH6_1AS5M31vSI&libraries=places"></script>
<!--top bar-->
<div>
<?php include("header.php");?>
</div>
<div id="map"></div>
<script>
/**
* Create new map
*/
var infowindow;
var map;
var red_icon = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png' ;
var locations = <?php get_confirmed_locations() ?>;
var myOptions = {
zoom: 7,
center: new google.maps.LatLng(31.87916, 35.32910),
mapTypeId: 'roadmap'
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
/**
* Global marker object that holds all markers.
* @type {Object.<string, google.maps.LatLng>}
*/
var markers = {};
/**
* Concatenates given lat and lng with an underscore and returns it.
* This id will be used as a key of marker to cache the marker in markers object.
* @param {!number} lat Latitude.
* @param {!number} lng Longitude.
* @return {string} Concatenated marker id.
*/
var getMarkerUniqueId= function(lat, lng) {
return lat + '_' + lng;
};
/**
* Creates an instance of google.maps.LatLng by given lat and lng values and returns it.
* This function can be useful for getting new coordinates quickly.
* @param {!number} lat Latitude.
* @param {!number} lng Longitude.
* @return {google.maps.LatLng} An instance of google.maps.LatLng object
*/
var getLatLng = function(lat, lng) {
return new google.maps.LatLng(lat, lng);
};
/**
* Binds right click event to given marker and invokes a callback function that will remove the marker from map.
* @param {!google.maps.Marker} marker A google.maps.Marker instance that the handler will binded.
*/
var bindMarkerEvents = function(marker) {
google.maps.event.addListener(marker, "rightclick", function (point) {
var markerId = getMarkerUniqueId(point.latLng.lat(), point.latLng.lng()); // get marker id by using clicked point's coordinate
var marker = markers[markerId]; // find marker
removeMarker(marker, markerId); // remove it
});
};
/**
* loop through (Mysql) dynamic locations to add markers to map.
*/
var i ; var confirmed = 0;
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,
icon : locations[i][4] === '1' ? red_icon : purple_icon,
html: "<div id='window_loc'>\n" +
"<form method='GET' action='question.php'>\n" +
"<table class=\"map1\">\n" +
"<tr>\n" +
"<td><input type='hidden' id='manual_description'/>"+locations[i][3]+"</td></tr>\n" +
"<tr>\n" +
"<td><textarea disabled id='question' placeholder='Question'>"+locations[i][5]+"</textarea></td></tr>\n" +
"<tr>\n" +
"<td><input type='hidden' name='location_id' id='location_id' value="+locations[i][0]+" /></td></tr>\n" +
"<td><input id='button1' name='play' type='submit' value='play'/> </td></tr>\n" +
"</table>\n" +
"</form>\n" +
"</div>"
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow = new google.maps.InfoWindow();
confirmed = locations[i][4] === '1' ? 'checked' : 0;
$("#confirmed").prop(confirmed,locations[i][4]);
$("#location_id").val(locations[i][0]);
$("#description").val(locations[i][3]);
$("#form").show();
infowindow.setContent(marker.html);
infowindow.open(map, marker);
}
})(marker, i));
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
</script>
this is what i have tried - imalementing the db markers in the cluster map with no sucsses
<?php
include("classes/user-map.php");
?>
<html>
<head>
<title>Marker Clustering</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCRLmpZiLZ9e-p6wRbwGWH6_1AS5M31vSI&callback=initMap&libraries=&v=weekly"
defer
></script>
<style type="text/css">
/* 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>
<script>
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 3,
center: { lat: -28.024, lng: 140.887 },
});
// Create an array of alphabetical characters used to label the markers.
const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var locations = <?php get_confirmed_locations() ?>;
// Add some markers to the map.
// Note: The code uses the JavaScript Array.prototype.map() method to
// create an array of markers based on a given "locations" array.
// The map() method here has nothing to do with the Google Maps API.
const markers = locations.map((locations, i) => {
return new google.maps.Marker({
position: locations,
label: labels[i % labels.length],
});
});
// Add a marker clusterer to manage the markers.
new MarkerClusterer(map, markers, {
imagePath:
"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
});
}
var markers = {};
/**
* Concatenates given lat and lng with an underscore and returns it.
* This id will be used as a key of marker to cache the marker in markers object.
* @param {!number} lat Latitude.
* @param {!number} lng Longitude.
* @return {string} Concatenated marker id.
*/
var getMarkerUniqueId= function(lat, lng) {
return lat + '_' + lng;
};
/**
* Creates an instance of google.maps.LatLng by given lat and lng values and returns it.
* This function can be useful for getting new coordinates quickly.
* @param {!number} lat Latitude.
* @param {!number} lng Longitude.
* @return {google.maps.LatLng} An instance of google.maps.LatLng object
*/
var getLatLng = function(lat, lng) {
return new google.maps.LatLng(lat, lng);
};
/**
* Binds right click event to given marker and invokes a callback function that will remove the marker from map.
* @param {!google.maps.Marker} marker A google.maps.Marker instance that the handler will binded.
*/
var bindMarkerEvents = function(marker) {
google.maps.event.addListener(marker, "rightclick", function (point) {
var markerId = getMarkerUniqueId(point.latLng.lat(), point.latLng.lng()); // get marker id by using clicked point's coordinate
var marker = markers[markerId]; // find marker
removeMarker(marker, markerId); // remove it
});
};
/**
* loop through (Mysql) dynamic locations to add markers to map.
*/
var i ; var confirmed = 0;
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,
icon : locations[i][4] === '1' ? red_icon : purple_icon,
html: "<div id='window_loc'>\n" +
"<form method='GET' action='question.php'>\n" +
"<table class=\"map1\">\n" +
"<tr>\n" +
"<td><input type='hidden' id='manual_description'/>"+locations[i][3]+"</td></tr>\n" +
"<tr>\n" +
"<td><textarea disabled id='question' placeholder='Question'>"+locations[i][5]+"</textarea></td></tr>\n" +
"<tr>\n" +
"<td><input type='hidden' name='location_id' id='location_id' value="+locations[i][0]+" /></td></tr>\n" +
"<td><input id='button1' name='play' type='submit' value='play'/> </td></tr>\n" +
"</table>\n" +
"</form>\n" +
"</div>"
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow = new google.maps.InfoWindow();
confirmed = locations[i][4] === '1' ? 'checked' : 0;
$("#confirmed").prop(confirmed,locations[i][4]);
$("#location_id").val(locations[i][0]);
$("#description").val(locations[i][3]);
$("#form").show();
infowindow.setContent(marker.html);
infowindow.open(map, marker);
}
})(marker, i));
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
var markerCluster = new MarkerClusterer(map, markers,
{imagePath: `${path}/m`});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
this is the server php query for locations
<?php
function get_confirmed_locations(){
$con=mysqli_connect ("localhost", 'root', '','');
if (!$con) {
die('Not connected : ' . mysqli_connect_error());
}
// update location with location_status if admin location_status.
$query = mysqli_query($con,"SELECT location_id ,lat,lng,description,location_status,question AS isconfirmed FROM `locations` WHERE location_status = 1 ");
$rows = array();
while($r = mysqli_fetch_assoc($query)) {
$rows[] = $r;
}
$indexed = array_map('array_values', $rows);
$array = array_filter($indexed);
echo json_encode($array);
if (!$rows) {
return null;
}
}
Upvotes: 0
Views: 936
Reputation: 161334
Simplest solution, push your markers into an array when you create them, create a MarkerClusterer
using that array.
create an array to hold the markers (rather than an object), change:
var markers = {};
to:
var markers = [];
in the loop that creates your markers, push them onto that array:
markers.push(marker);
after the loop is complete, create the MarkerClusterer
using that array (the same code as in the example):
// Add a marker clusterer to manage the markers.
new MarkerClusterer(map, markers, {
imagePath: "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
});
code snippet:
/**
* Create new map
*/
var infowindow;
var map;
var red_icon = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png';
var locations = [
["name0", -31.56391, 147.154312], ["name1", -33.718234, 150.363181], ["name2", -33.727111, 150.371124], ["name3", -33.848588, 151.209834], ["name4", -33.851702, 151.216968], ["name5", -34.671264, 150.863657], ["name6", -35.304724, 148.662905], ["name7", -36.817685, 175.699196], ["name8", -36.828611, 175.790222], ["name9", -37.75, 145.116667], ["name10", -37.759859, 145.128708], ["name11", -37.765015, 145.133858], ["name12", -37.770104, 145.143299], ["name13", -37.7737, 145.145187], ["name14", -37.774785, 145.137978], ["name15", -37.819616, 144.968119], ["name16", -38.330766, 144.695692], ["name17", -39.927193, 175.053218], ["name18", -41.330162, 174.865694], ["name19", -42.734358, 147.439506], ["name20", -42.734358, 147.501315], ["name21", -42.735258, 147.438], ["name22", -43.999792, 170.463352]
]
var myOptions = {
zoom: 7,
center: new google.maps.LatLng(31.87916, 35.32910),
mapTypeId: 'roadmap'
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
/**
* Global marker object that holds all markers.
* @type {Object.<string, google.maps.LatLng>}
*/
var markers = [];
/**
* Concatenates given lat and lng with an underscore and returns it.
* This id will be used as a key of marker to cache the marker in markers object.
* @param {!number} lat Latitude.
* @param {!number} lng Longitude.
* @return {string} Concatenated marker id.
*/
var getMarkerUniqueId = function(lat, lng) {
return lat + '_' + lng;
};
/**
* Creates an instance of google.maps.LatLng by given lat and lng values and returns it.
* This function can be useful for getting new coordinates quickly.
* @param {!number} lat Latitude.
* @param {!number} lng Longitude.
* @return {google.maps.LatLng} An instance of google.maps.LatLng object
*/
var getLatLng = function(lat, lng) {
return new google.maps.LatLng(lat, lng);
};
/**
* Binds right click event to given marker and invokes a callback function that will remove the marker from map.
* @param {!google.maps.Marker} marker A google.maps.Marker instance that the handler will binded.
*/
var bindMarkerEvents = function(marker) {
google.maps.event.addListener(marker, "rightclick", function(point) {
var markerId = getMarkerUniqueId(point.latLng.lat(), point.latLng.lng()); // get marker id by using clicked point's coordinate
var marker = markers[markerId]; // find marker
removeMarker(marker, markerId); // remove it
});
};
/**
* loop through (Mysql) dynamic locations to add markers to map.
*/
var i;
var confirmed = 0;
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
// icon: locations[i][4] === '1' ? red_icon : purple_icon,
html: "<div id='window_loc'>\n" +
"<form method='GET' action='question.php'>\n" +
"<table class=\"map1\">\n" +
"<tr>\n" +
"<td><input type='hidden' id='manual_description'/>" + locations[i][3] + "</td></tr>\n" +
"<tr>\n" +
"<td><textarea disabled id='question' placeholder='Question'>" + locations[i][5] + "</textarea></td></tr>\n" +
"<tr>\n" +
"<td><input type='hidden' name='location_id' id='location_id' value=" + locations[i][0] + " /></td></tr>\n" +
"<td><input id='button1' name='play' type='submit' value='play'/> </td></tr>\n" +
"</table>\n" +
"</form>\n" +
"</div>"
});
bounds.extend(marker.getPosition());
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow = new google.maps.InfoWindow();
confirmed = locations[i][4] === '1' ? 'checked' : 0;
$("#confirmed").prop(confirmed, locations[i][4]);
$("#location_id").val(locations[i][0]);
$("#description").val(locations[i][3]);
$("#form").show();
infowindow.setContent(marker.html);
infowindow.open(map, marker);
}
})(marker, i));
markers.push(marker);
}
map.fitBounds(bounds);
// Add a marker clusterer to manage the markers.
new MarkerClusterer(map, markers, {
imagePath: "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
});
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
/* 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;
}
<!DOCTYPE html>
<html>
<head>
<title>Marker Clustering</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=&v=weekly"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
</body>
</html>
Upvotes: 1