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/markerclustererplus@4.0.1/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/markerclustererplus@4.0.1/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; } }
Advertisement
Answer
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/markerclustererplus@4.0.1/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>