Jonathan Lam
Jonathan Lam

Reputation: 1328

How to display polygons that are within a specific range (circle) using Leaflet

I am trying find a solution on how to display polygons that are only within a specific range, a circle with radius using leaflet.

Polygons screenshots

Before, I have ask for help regarding on the display of points within a specific range but this time, since a polygon have many nodes/coordinates, i don't have any idea of how it can be done for polygons; a foreach statement?

Any solution? Thanks for the help!

Similar problem solved for displaying points within a specific range

Upvotes: 0

Views: 775

Answers (1)

iH8
iH8

Reputation: 28678

Since you're using MongoDB, the best solution here is (if that's possible), to handle this in the database. Put 2dsphere indexes on your document's loc field and use a $geoWithin query in combination with $centerSphere:

The following example queries grid coordinates and returns all documents within a 10 mile radius of longitude 88 W and latitude 30 N. The query converts the distance to radians by dividing by the approximate radius of the earth, 3959 miles:

db.places.find( {
    loc: { $geoWithin: { $centerSphere: [ [ -88, 30 ], 10/3959 ] } }
} )

2dsphere reference: http://docs.mongodb.org/manual/core/2dsphere/

$geoWithin reference: http://docs.mongodb.org/manual/reference/operator/query/geoWithin/

$centerSphere reference: http://docs.mongodb.org/manual/reference/operator/query/centerSphere/

If you really want to do this clientside (which i absolutely wouldn't recommend) and you don't want to build your on solution (which is possible) you could take a look at GeoScript.

GeoScript's geom.Geometry() class has a contains method:

Tests if this geometry contains the other geometry (without boundaries touching).

Geom.geometry reference: http://geoscript.org/js/api/geom/geometry.html

EDIT: Here's the pure JS/Leaflet solution as requested in the comments, this is quick-n-dirty, but it should work. Here the containsPolygon method returns true when all of the polygon's points are within the circle:

L.Circle.include({
    'containsPoint': function (latLng) {
        return this.getLatLng().distanceTo(latLng) < this.getRadius();
    },
    'containsPolygon': function (polygon) {
        var results = [];
        polygon.getLatLngs().forEach(function (latLng) {
            results.push(this.containsPoint(latLng));
        }, this);
        return (results.indexOf(false) === -1);
     }
});

Here's a working example: http://plnkr.co/edit/JlFToy?p=preview

If you want to return true if one or more of the polygon's points are within the circle than you must change the return statement to this:

return (results.indexOf(true) !== -1);

Upvotes: 3

Related Questions