radius filtering is more efficient now and works for other type of

objects as well
This commit is contained in:
Nandor Kracser 2012-01-11 19:56:06 +01:00
parent 35a4d9d202
commit 870b7261cc
2 changed files with 31 additions and 11 deletions

View File

@ -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:
<pre>
<code>
// 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
}
}
</code>

View File

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