summaryrefslogtreecommitdiff
path: root/src/mongo/db/geo/shapes.cpp
diff options
context:
space:
mode:
authorGreg Studer <greg@10gen.com>2014-07-18 15:28:37 -0400
committerGreg Studer <greg@10gen.com>2014-07-23 16:52:36 -0400
commit2cbd9f1d77ce6b25e9957d3121fccb521caf848f (patch)
tree98376940b7d7de3f23877f72cbe2e9008a64b8a7 /src/mongo/db/geo/shapes.cpp
parent7174d92cc1ad3dd24430769b72c05b1ee6fbcd74 (diff)
downloadmongo-2cbd9f1d77ce6b25e9957d3121fccb521caf848f.tar.gz
SERVER-5800 changes for geo expression index performance, avoid preprojecting
- additional covering parameters - only project points when required
Diffstat (limited to 'src/mongo/db/geo/shapes.cpp')
-rw-r--r--src/mongo/db/geo/shapes.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/src/mongo/db/geo/shapes.cpp b/src/mongo/db/geo/shapes.cpp
index 9c1e5b80745..14a4fa3de04 100644
--- a/src/mongo/db/geo/shapes.cpp
+++ b/src/mongo/db/geo/shapes.cpp
@@ -563,11 +563,8 @@ namespace mongo {
}
// Technically lat/long bounds, not really tied to earth radius.
- void checkEarthBounds(const Point &p) {
- uassert(14808, str::stream() << "point " << p.toString()
- << " must be in earth-like bounds of long "
- << ": [-180, 180], lat : [-90, 90] ",
- p.x >= -180 && p.x <= 180 && p.y >= -90 && p.y <= 90);
+ bool isValidLngLat(double lng, double lat) {
+ return abs(lng) <= 180 && abs(lat) <= 90;
}
double distance(const Point& p1, const Point &p2) {
@@ -750,4 +747,44 @@ namespace mongo {
return edgesIntersectsWithBox(polygon.points(), box);
}
+ bool ShapeProjection::supportsProject(const PointWithCRS& point, const CRS crs) {
+
+ // Can always trivially project or project from SPHERE->FLAT
+ if (point.crs == crs || point.crs == SPHERE)
+ return true;
+
+ invariant(point.crs == FLAT);
+ // If crs is FLAT, we might be able to upgrade the point to SPHERE if it's a valid SPHERE
+ // point (lng/lat in bounds). In this case, we can use FLAT data with SPHERE predicates.
+ return isValidLngLat(point.oldPoint.x, point.oldPoint.y);
+ }
+
+ void ShapeProjection::projectInto(PointWithCRS* point, CRS crs) {
+ dassert(supportsProject(*point, crs));
+
+ if (point->crs == crs)
+ return;
+
+ if (FLAT == point->crs) {
+ invariant(SPHERE == crs);
+
+ // Note that it's (lat, lng) for S2 but (lng, lat) for MongoDB.
+ S2LatLng latLng =
+ S2LatLng::FromDegrees(point->oldPoint.y, point->oldPoint.x).Normalized();
+ dassert(latLng.is_valid());
+ point->point = latLng.ToPoint();
+ point->cell = S2Cell(point->point);
+ point->crs = SPHERE;
+ }
+ else {
+ invariant(SPHERE == point->crs);
+ invariant(FLAT == crs);
+
+ // Just remove the additional spherical information
+ point->point = S2Point();
+ point->cell = S2Cell();
+ point->crs = FLAT;
+ }
+ }
+
} // namespace mongo