diff options
author | Greg Studer <greg@10gen.com> | 2014-07-18 15:28:37 -0400 |
---|---|---|
committer | Greg Studer <greg@10gen.com> | 2014-07-23 16:52:36 -0400 |
commit | 2cbd9f1d77ce6b25e9957d3121fccb521caf848f (patch) | |
tree | 98376940b7d7de3f23877f72cbe2e9008a64b8a7 /src/mongo/db/geo/shapes.cpp | |
parent | 7174d92cc1ad3dd24430769b72c05b1ee6fbcd74 (diff) | |
download | mongo-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.cpp | 47 |
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 |