Skip to content
Advertisement

marker cluster locations from database

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.

  1. create an array to hold the markers (rather than an object), change:

     var markers = {};
    

to:

    var markers = [];
  1. in the loop that creates your markers, push them onto that array:

     markers.push(marker);
    
  2. 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",
    });
    

proof of concept fiddle

screenshot of resulting map

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>
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement