Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Maps JavaScript API v3 / Data Layer / MarkerClusterer

Can you help me please to create marker cluster with MarkerClustererPlus. I load the data with:

layer = map.data.loadGeoJson('resources/data.geojson');

and the markers are visible, but i have not idea how to create markercluster. Do i have to parse the data.geojson-file into an array? Thanks.

function initialize() {
map = new google.maps.Map(document.getElementById('map'), mapOptions);
layer = map.data.loadGeoJson('resources/data.geojson');

map.data.setStyle({icon: icon});

map.data.addListener('click', function(event) {
var myHTML = event.feature.getProperty('name');
infobox.setContent("<div style='width:150px; text-align: center;'>"+myHTML+"</div>");
infobox.setPosition(event.feature.getGeometry().get());
infobox.setOptions({pixelOffset: new google.maps.Size(0,0)});
infobox.open(map);
});  

google.maps.event.addListener(map, "click", function(){
infobox.close();
});

map.mapTypes.set('map_style', styledMap);
map.setMapTypeId('map_style');
}
google.maps.event.addDomListener(window, 'load', initialize);

Here is a piece of my GeoJson-File (this piece and the whole file is tested by GeoJSONLint.

{
"type": "FeatureCollection",
"icon": "resources/icon.png",
"features": [
{
"type": "Feature","properties": {"name":"Bielefeld"},
"geometry": {"type": "Point","coordinates":[8.528849, 52.030656]}
},
{
"type": "Feature","properties": {"name":"Herford"},
"geometry": {"type": "Point","coordinates":[8.676780, 52.118003]}
},
{
"type": "Feature","properties": {"name":"Guetersloh"},
"geometry": {"type": "Point","coordinates":[8.383353, 51.902917]}
}
]
}
like image 786
armin Avatar asked Aug 12 '14 14:08

armin


People also ask

How do I load a GeoJSON file into Google Maps?

With the Data layer, you can add GeoJSON data to a Google map in just one line of code. map. data. loadGeoJson('google.


2 Answers

  1. create a MarkerClusterer to manage the markers.

     var markerClusterer = new MarkerClusterer();
    
  2. add each marker to it when the data layer fires the addfeature event.

     markerClusterer.addMarker(marker);
    
  3. hide the data layer markers.

     map.data.setMap(null);
    

working jsfiddle

screenshot of resulting map

var markerClusterer = new MarkerClusterer();
function initialize() {
    var mapOptions = {
        center: new google.maps.LatLng(52, 8),
        zoom: 4
    };
    map = new google.maps.Map(document.getElementById('map'), mapOptions);

    markerClusterer.setMap(map);
    google.maps.event.addListener(map.data, 'addfeature', function (e) {
        if (e.feature.getGeometry().getType() === 'Point') {
            var marker = new google.maps.Marker({
                position: e.feature.getGeometry().get(),
                title: e.feature.getProperty('name'),
                map: map
            });
            // open the infoBox when the marker is clicked
            google.maps.event.addListener(marker, 'click', function (marker, e) {
                return function () {

                    var myHTML = e.feature.getProperty('name');
                    boxText.innerHTML = "<div style='text-align: center;'><b>" + myHTML + "</b></div>";
                    infobox.setPosition(e.feature.getGeometry().get());
                    infobox.setOptions({
                        pixelOffset: new google.maps.Size(0, 0)
                    });
                    infobox.open(map);
                };
            }(marker, e));
            markerClusterer.addMarker(marker);
            bounds.extend(e.feature.getGeometry().get());
            map.fitBounds(bounds);
            map.setCenter(e.feature.getGeometry().get());
        }
    });
    layer = map.data.addGeoJson(geoJson);
    map.data.setMap(null);
    google.maps.event.addListener(map, "click", function () {
        infobox.close();
    });
}

code snippet:

var geoJson = {
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "properties": {
      "name": "Bielefeld"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.528849, 52.030656]
    }
  }, {
    "type": "Feature",
    "properties": {
      "name": "Herford"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.676780, 52.118003]
    }
  }, {
    "type": "Feature",
    "properties": {
      "name": "Guetersloh"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.383353, 51.902917]
    }
  }, {
    "type": "Feature",
    "properties": {
      "name": "Guetersloh2"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.38, 51.9]
    }
  }]
};
var map = null;
var bounds = new google.maps.LatLngBounds();

var boxText = document.createElement("div");
boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
var infobox = new InfoBox({
  content: boxText,
  disableAutoPan: false,
  maxWidth: 0,
  pixelOffset: new google.maps.Size(-140, 0),
  zIndex: null,
  boxStyle: {
    background: "url('tipbox.gif') no-repeat",
    opacity: 0.75,
    width: "280px"
  },
  closeBoxMargin: "10px 2px 2px 2px",
  closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
  infoBoxClearance: new google.maps.Size(1, 1),
  isHidden: false,
  pane: "floatPane",
  enableEventPropagation: false
});

var markerClusterer = new MarkerClusterer(null, null, {
  imagePath: "https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m"
});

function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(52, 8),
    zoom: 4
  };
  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  markerClusterer.setMap(map);
  google.maps.event.addListener(map.data, 'addfeature', function(e) {
    if (e.feature.getGeometry().getType() === 'Point') {
      var marker = new google.maps.Marker({
        position: e.feature.getGeometry().get(),
        title: e.feature.getProperty('name'),
        map: map
      });
      google.maps.event.addListener(marker, 'click', function(marker, e) {
        return function() {

          var myHTML = e.feature.getProperty('name');
          boxText.innerHTML = "<div style='text-align: center;'><b>" + myHTML + "</b></div>";
          infobox.setPosition(e.feature.getGeometry().get());
          infobox.setOptions({
            pixelOffset: new google.maps.Size(0, 0)
          });
          infobox.open(map);
        };
      }(marker, e));
      markerClusterer.addMarker(marker);
      bounds.extend(e.feature.getGeometry().get());
      map.fitBounds(bounds);
      map.setCenter(e.feature.getGeometry().get());
    }
  });
  layer = map.data.addGeoJson(geoJson);
  map.data.setMap(null);
  google.maps.event.addListener(map, "click", function() {
    infobox.close();
  });
}
google.maps.event.addDomListener(window, 'load', initialize);
#map {
  width: 500px;
  height: 500px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/infobox.js"></script>
<script src="https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js"></script>
<div id="map"></div>
like image 77
geocodezip Avatar answered Sep 27 '22 21:09

geocodezip


The shapes created for the data-layer are not accessible via the API, but you must have a reference to the markers to be able to add them to the clusterer.

Possible solution:

Observe the addfeature-event of the data and create your own markers. The markers created for the data-layer hide(either via the visible-style set to false or remove the feature completely when you don't need to access it later)

Example:

 var mc=new MarkerClusterer(map);

 map.data.addListener('addfeature',function(e){
  var geo=  e.feature.getGeometry();

  if(geo.getType()==='Point'){

    mc.addMarker(new google.maps.Marker({position:geo.get(),
                                         title   :e.feature.getProperty('name')}));
    map.data.remove(e.feature);
  }
 });

Demo: http://jsfiddle.net/doktormolle/myuua77p/

Of course this solution creates some overhead. When there are only Points inside the FeatureCollection you better parse the geoJSON on your own instead of using the data-layer

like image 32
Dr.Molle Avatar answered Sep 27 '22 20:09

Dr.Molle