16

I need to select multiple markers in a map. Something like this: Box/Rectangle Draw Selection in Google Maps but with Leaflet and OSM.

I think it could be done by modifying the zoom box that appears when you shift click and drag in an OSM map, but I don't know how to do it.

Edit: I rewrote the _onMouseUp function, as L. Sanna suggested and ended up with something like this:

_onMouseUp: function (e) {

    this._finish();

    var map = this._map,
    layerPoint = map.mouseEventToLayerPoint(e);

    if (this._startLayerPoint.equals(layerPoint)) { return; }

    var bounds = new L.LatLngBounds(
    map.layerPointToLatLng(this._startLayerPoint),
    map.layerPointToLatLng(layerPoint));

    var t=0;
    var selected = new Array();

    for (var i = 0; i < addressPoints.length; i++) {
        var a = addressPoints[i];
        pt = new L.LatLng(a[0], a[1]);

        if (bounds.contains(pt) == true) {
            selected[t] = a[2];
            t++;
        }
    }

    alert(selected.join('\n'))
},
pepelu
  • 368
  • 1
  • 3
  • 18

4 Answers4

8

I think it could be easy modificating the zoom box that appears when you shift clic and drag in an osm map, but I don't know how to do it

Good idea. The zoom Box is actually a functionality of leaflet.

Here is the code.

Just rewrite the _onMouseUp function to fit your needs.

L. Sanna
  • 6,482
  • 7
  • 33
  • 47
  • 1
    That's it, I rewrote that function and it works. I'll update my question with the code. Thanks – pepelu Jul 18 '13 at 08:59
7

Have you tried something like this?

markers is an array of L.latLng() coordinates

map.on("boxzoomend", function(e) {
  for (var i = 0; i < markers.length; i++) {
    if (e.boxZoomBounds.contains(markers[i].getLatLng())) {
      console.log(markers[i]);
    }
  }
});
Community
  • 1
  • 1
gotnull
  • 26,454
  • 22
  • 137
  • 203
  • Could you add more detail about how to use this? – Matt May 09 '15 at 23:18
  • @Matt: There's not much to it. `markers` is just an `Array` of `L.latlng()` coordinates that when you SHIFT drag an area on the map it calls the `boxzoomend` method and shows the `markers` you've selected provided they're in the array. It's just checking to see whether the markers exist within the selected boundaries. – gotnull May 10 '15 at 23:51
  • You have to add .getLatLng() to your marker on iteration : if (e.boxZoomBounds.contains(markers[i].getLatLng())) – rafa226 Mar 28 '22 at 12:21
3

Not enough points to comment, but in order to override the _onMouseUp function like OP posted in their edit, the leaflet tutorial gives a good explanation. Additionally, this post was very helpful and walks you through every step.

nymks
  • 45
  • 1
  • 7
2

A bit late to the party but it's also possible to achieve this using the leaflet-editable plugin.

// start drawing a rectangle
 function startSelection() {
    const rect = new L.Draw.Rectangle(this.map);
    rect.enable();

   this.map.on('draw:created', (e) => {
    // the rectangle will not be added to the map unless you
    // explicitly add it as a layer
    // get the bounds of the rect and check if your points
    // are contained in it
   });
}

Benefits of using this method

  1. Allow selection with any shape (polygon, circle, path, etc.)
  2. Allow selection using a button/programmatically (does not require holding down the shift key, which may be unknown to some users).
  3. Does not change the zoom box functionality
dev7
  • 6,259
  • 6
  • 32
  • 65