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) {