0

I'm having a problem with grouping(clustering) markers

I have a list GeoJSON features that I display as markers in the leaflet. And it looks like this:

MapMarkers

These points are saved in my Database and are located on my Geoserver.

And when fetch them from DB I get it like this, then I loop over them and add them as markers.

const points = [
  { lat: 48.371768, lng: 16.723857 },
  { lat: 48.354206, lng: 16.703258 },
  { lat: 48.401474, lng: 16.727156 },
  { lat: 48.283497, lng: 16.545787 },
  { lat: 48.361275, lng: 16.699054 },
  { lat: 48.283497, lng: 16.545787 },
];

The problem that I'm having is that I have to summarize points within a specific radius and group (cluster) them automatically.

I have to expand points for some specific radius say 100 meters

Like in Turf js buffer option:

https://turfjs.org/

Like here:

enter image description here

And in Points where those circles intersect with each other, add an additional marker with those I already have

I have tried with Leaflet Clustering marker

https://github.com/Leaflet/Leaflet.markercluster

But haven't had any luck, markers are not displayed at all.

Here is my code so far:

var markers = L.markerClusterGroup({
  maxClusterRadius: function (zoom) {
    return 10;
  },
});

points.forEach((point) => {
  const location = { latlng: { lat: point, point: event.lng } };
  var marker = L.marker(location.latlng);
  markers.addLayer(marker);
  this.layers.markersLayer.instance.addLayer(markers);
});

And that works fine, but I would like to cluster points by distance in meters instead of pixels like in maxClusterRadius.

4
  • You should (1) Look for errors in your browser's console (2) Re-read the Leaflet.Markercluster documentation and (3) Realize that the maxClusterRadius option should be a Number but your're passing a Function and expecting it to magically work. Commented Oct 20, 2020 at 10:49
  • @IvanSanchez It is also working with function, is there any way I could convert meters to pexel in this case for maxClusterRadius option
    – Loki
    Commented Oct 20, 2020 at 10:52
  • 4
    Yeah, that'd be the inverse of map.distance() - get the map width from map.getSize(), calculate the length (in meters) of a horizontal line crossing the map center just as L.Control.Scale does, and do a bit of math to get the meter-to-pixel ratio for the current zoom level and latitude. Commented Oct 20, 2020 at 10:58
  • 1
    @IvanSanchez could you this post as a full answer so I can accept it +1
    – Loki
    Commented Oct 20, 2020 at 11:02

1 Answer 1

0

Incase it helps anyone:

function getPixelsForDistance(map, distanceInMeters) {
    const centerPoint = map.latLngToContainerPoint(map.getCenter());
    const targetLatLng = map.containerPointToLatLng([centerPoint.x + distanceInMeters, centerPoint.y]);
    const targetPoint = map.latLngToContainerPoint(targetLatLng);
    return Math.abs(targetPoint.x - centerPoint.x);
}

and then call with

const clusterGroup = L.markerClusterGroup({
   maxClusterRadius: getPixelsForDistance(map, 50),
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.