diff --git a/README.textile b/README.textile index aff38d6..d87865b 100755 --- a/README.textile +++ b/README.textile @@ -47,25 +47,21 @@ h2. Point in polygon h2. Radius filtering -WARNING: Only works against points right now. TODO: Lines and polygons - -If you retrieve a bunch of results from a bounding box query (common with R-Tree geo DBs), but you want to filter the rectangular result set by circular radius: +If you retrieve a bunch of results from a bounding box query (common with R-tree geo DBs), but you want to filter the rectangular result set by circular radius:
// get the center of the original bounding box
var center = gju.rectangleCentroid({
"type": "Polygon",
- "coordinates": [[[-122.677, 45.523],[-122.675, 45.524]]]
+ "coordinates": [[[-122.677, 45.523], [-122.675, 45.524]]]
}),
- // draw a circular polygon from the center of
- // the bounding box with a 100 meter radius
- // but only in your head!
+ // radius (in meters)
radius = 100;
-
- for (var point in listOfPointsReturnedFromBoundingBoxQuery) {
- if (gju.pointDistance(point, center) <= radius) {
- // ... do stuff with points inside the circle
+
+ for (var i in geometryObjectsWithinBBox) {
+ if (gju.geometryWithinRadius(geometryObjectsWithinBBox[i], center, radius)) {
+ // ... do stuff with objects inside the circle
}
}
diff --git a/geojson-utils.js b/geojson-utils.js
index 5f1e671..ca84cfb 100755
--- a/geojson-utils.js
+++ b/geojson-utils.js
@@ -99,6 +99,30 @@
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return (6371 * c) * 1000; // returns meters
},
+
+ // checks if geometry lies entirely within a circle
+ // works with Point, LineString, Polygon
+ gju.geometryWithinRadius = function(geometry, center, radius) {
+ if (geometry.type == 'Point') {
+ return gju.pointDistance(geometry, center) <= radius;
+ } else if (geometry.type == 'LineString' || geometry.type == 'Polygon') {
+ var point = {};
+ var coordinates;
+ if (geometry.type == 'Polygon') {
+ // it's enough to check the exterior ring of the Polygon
+ coordinates = geometry.coordinates[0];
+ } else {
+ coordinates = geometry.coordinates;
+ }
+ for (var i in coordinates) {
+ point.coordinates = coordinates[i];
+ if (gju.pointDistance(point, center) > radius) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
// adapted from http://paulbourke.net/geometry/polyarea/javascript.txt
gju.area = function(polygon) {