diff options
author | Kevin Albertson <kevin.albertson@10gen.com> | 2015-08-05 15:21:56 -0400 |
---|---|---|
committer | Kevin Albertson <kevin.albertson@10gen.com> | 2015-08-05 15:21:56 -0400 |
commit | 53ead9a708208978228de918fafa7835655e0632 (patch) | |
tree | 45d32b61501bf913e5575546309124088737ff1a /src/mongo/db/geo | |
parent | 6d5fd302c9be9d1d33c06d4a1344b1b4583fa7c3 (diff) | |
download | mongo-53ead9a708208978228de918fafa7835655e0632.tar.gz |
SERVER-15204 Skip unnecessary validation on indexed polygons and lines
Diffstat (limited to 'src/mongo/db/geo')
-rw-r--r-- | src/mongo/db/geo/geometry_container.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/geo/geometry_container.h | 6 | ||||
-rw-r--r-- | src/mongo/db/geo/geoparser.cpp | 63 | ||||
-rw-r--r-- | src/mongo/db/geo/geoparser.h | 18 | ||||
-rw-r--r-- | src/mongo/db/geo/geoparser_test.cpp | 71 |
5 files changed, 108 insertions, 68 deletions
diff --git a/src/mongo/db/geo/geometry_container.cpp b/src/mongo/db/geo/geometry_container.cpp index f3bfca36cfb..3ae63e40690 100644 --- a/src/mongo/db/geo/geometry_container.cpp +++ b/src/mongo/db/geo/geometry_container.cpp @@ -36,8 +36,6 @@ namespace mongo { using mongoutils::str::equals; -GeometryContainer::GeometryContainer() {} - bool GeometryContainer::isSimpleContainer() const { return NULL != _point || NULL != _line || NULL != _polygon; } @@ -864,7 +862,7 @@ bool GeometryContainer::intersects(const S2Polygon& otherPolygon) const { return false; } -Status GeometryContainer::parseFromGeoJSON(const BSONObj& obj) { +Status GeometryContainer::parseFromGeoJSON(const BSONObj& obj, bool skipValidation) { GeoParser::GeoJSONType type = GeoParser::parseGeoJSONType(obj); if (GeoParser::GEOJSON_UNKNOWN == type) { @@ -879,10 +877,10 @@ Status GeometryContainer::parseFromGeoJSON(const BSONObj& obj) { status = GeoParser::parseGeoJSONPoint(obj, _point.get()); } else if (GeoParser::GEOJSON_LINESTRING == type) { _line.reset(new LineWithCRS()); - status = GeoParser::parseGeoJSONLine(obj, _line.get()); + status = GeoParser::parseGeoJSONLine(obj, skipValidation, _line.get()); } else if (GeoParser::GEOJSON_POLYGON == type) { _polygon.reset(new PolygonWithCRS()); - status = GeoParser::parseGeoJSONPolygon(obj, _polygon.get()); + status = GeoParser::parseGeoJSONPolygon(obj, skipValidation, _polygon.get()); } else if (GeoParser::GEOJSON_MULTI_POINT == type) { _multiPoint.reset(new MultiPointWithCRS()); status = GeoParser::parseMultiPoint(obj, _multiPoint.get()); @@ -891,19 +889,19 @@ Status GeometryContainer::parseFromGeoJSON(const BSONObj& obj) { } } else if (GeoParser::GEOJSON_MULTI_LINESTRING == type) { _multiLine.reset(new MultiLineWithCRS()); - status = GeoParser::parseMultiLine(obj, _multiLine.get()); + status = GeoParser::parseMultiLine(obj, skipValidation, _multiLine.get()); for (size_t i = 0; i < _multiLine->lines.size(); ++i) { regions.push_back(_multiLine->lines[i]); } } else if (GeoParser::GEOJSON_MULTI_POLYGON == type) { _multiPolygon.reset(new MultiPolygonWithCRS()); - status = GeoParser::parseMultiPolygon(obj, _multiPolygon.get()); + status = GeoParser::parseMultiPolygon(obj, skipValidation, _multiPolygon.get()); for (size_t i = 0; i < _multiPolygon->polygons.size(); ++i) { regions.push_back(_multiPolygon->polygons[i]); } } else if (GeoParser::GEOJSON_GEOMETRY_COLLECTION == type) { _geometryCollection.reset(new GeometryCollection()); - status = GeoParser::parseGeometryCollection(obj, _geometryCollection.get()); + status = GeoParser::parseGeometryCollection(obj, skipValidation, _geometryCollection.get()); // Add regions for (size_t i = 0; i < _geometryCollection->points.size(); ++i) { @@ -1014,7 +1012,7 @@ Status GeometryContainer::parseFromQuery(const BSONElement& elem) { // // "elem" is the element that contains geo data. e.g. "location": [1, 2] // We need the type information to determine whether it's legacy point. -Status GeometryContainer::parseFromStorage(const BSONElement& elem) { +Status GeometryContainer::parseFromStorage(const BSONElement& elem, bool skipValidation) { if (!elem.isABSONObj()) { return Status(ErrorCodes::BadValue, str::stream() << "geo element must be an array or object: " << elem); @@ -1034,7 +1032,7 @@ Status GeometryContainer::parseFromStorage(const BSONElement& elem) { } else { // GeoJSON // { location: { type: "Point", coordinates: [...] } } - status = parseFromGeoJSON(elem.Obj()); + status = parseFromGeoJSON(elem.Obj(), skipValidation); } if (!status.isOK()) return status; diff --git a/src/mongo/db/geo/geometry_container.h b/src/mongo/db/geo/geometry_container.h index 0d7cea0e7c4..eebe59e7cd1 100644 --- a/src/mongo/db/geo/geometry_container.h +++ b/src/mongo/db/geo/geometry_container.h @@ -43,7 +43,7 @@ public: /** * Creates an empty geometry container which may then be loaded from BSON or directly. */ - GeometryContainer(); + GeometryContainer() = default; /** * Loads an empty GeometryContainer from query. @@ -53,7 +53,7 @@ public: /** * Loads an empty GeometryContainer from stored geometry. */ - Status parseFromStorage(const BSONElement& elem); + Status parseFromStorage(const BSONElement& elem, bool skipValidation = false); /** * Is the geometry any of {Point, Line, Polygon}? @@ -126,7 +126,7 @@ public: private: class R2BoxRegion; - Status parseFromGeoJSON(const BSONObj& obj); + Status parseFromGeoJSON(const BSONObj& obj, bool skipValidation = false); // Does 'this' intersect with the provided type? bool intersects(const S2Cell& otherPoint) const; diff --git a/src/mongo/db/geo/geoparser.cpp b/src/mongo/db/geo/geoparser.cpp index 1f374f42215..12831f640bc 100644 --- a/src/mongo/db/geo/geoparser.cpp +++ b/src/mongo/db/geo/geoparser.cpp @@ -170,7 +170,9 @@ static Status isLoopClosed(const vector<S2Point>& loop, const BSONElement loopEl return Status::OK(); } -static Status parseGeoJSONPolygonCoordinates(const BSONElement& elem, S2Polygon* out) { +static Status parseGeoJSONPolygonCoordinates(const BSONElement& elem, + bool skipValidation, + S2Polygon* out) { if (Array != elem.type()) { return BAD_VALUE("Polygon coordinates must be an array"); } @@ -212,7 +214,7 @@ static Status parseGeoJSONPolygonCoordinates(const BSONElement& elem, S2Polygon* // 2. All vertices must be unit length. Guaranteed by parsePoints(). // 3. Loops are not allowed to have any duplicate vertices. // 4. Non-adjacent edges are not allowed to intersect. - if (!loop->IsValid(&err)) { + if (!skipValidation && !loop->IsValid(&err)) { return BAD_VALUE("Loop is not valid: " << coordinateElt.toString(false) << " " << err); } // If the loop is more than one hemisphere, invert it. @@ -237,7 +239,7 @@ static Status parseGeoJSONPolygonCoordinates(const BSONElement& elem, S2Polygon* // 1. If a loop contains an edge AB, then no other loop may contain AB or BA. // 2. No loop covers more than half of the sphere. // 3. No two loops cross. - if (!S2Polygon::IsValid(loops.vector(), &err)) + if (!skipValidation && !S2Polygon::IsValid(loops.vector(), &err)) return BAD_VALUE("Polygon isn't valid: " << err << " " << elem.toString(false)); // Given all loops are valid / normalized and S2Polygon::IsValid() above returns true. @@ -246,6 +248,9 @@ static Status parseGeoJSONPolygonCoordinates(const BSONElement& elem, S2Polygon* // Transfer ownership of the loops and clears loop vector. out->Init(&loops.mutableVector()); + if (skipValidation) + return Status::OK(); + // Check if every loop of this polygon shares at most one vertex with // its parent loop. if (!out->IsNormalized(&err)) @@ -365,20 +370,25 @@ static Status parseGeoJSONCRS(const BSONObj& obj, CRS* crs, bool allowStrictSphe // Parse "coordinates" field of GeoJSON LineString // e.g. "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] // Or a line in "coordinates" field of GeoJSON MultiLineString -static Status parseGeoJSONLineCoordinates(const BSONElement& elem, S2Polyline* out) { +static Status parseGeoJSONLineCoordinates(const BSONElement& elem, + bool skipValidation, + S2Polyline* out) { vector<S2Point> vertices; Status status = parseArrayOfCoordinates(elem, &vertices); if (!status.isOK()) return status; eraseDuplicatePoints(&vertices); - if (vertices.size() < 2) - return BAD_VALUE( - "GeoJSON LineString must have at least 2 vertices: " << elem.toString(false)); + if (!skipValidation) { + if (vertices.size() < 2) + return BAD_VALUE( + "GeoJSON LineString must have at least 2 vertices: " << elem.toString(false)); - string err; - if (!S2Polyline::IsValid(vertices, &err)) - return BAD_VALUE("GeoJSON LineString is not valid: " << err << " " << elem.toString(false)); + string err; + if (!S2Polyline::IsValid(vertices, &err)) + return BAD_VALUE("GeoJSON LineString is not valid: " << err << " " + << elem.toString(false)); + } out->Init(vertices); return Status::OK(); } @@ -470,7 +480,7 @@ Status GeoParser::parseGeoJSONPoint(const BSONObj& obj, PointWithCRS* out) { } // { "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] } -Status GeoParser::parseGeoJSONLine(const BSONObj& obj, LineWithCRS* out) { +Status GeoParser::parseGeoJSONLine(const BSONObj& obj, bool skipValidation, LineWithCRS* out) { Status status = Status::OK(); // "crs" status = parseGeoJSONCRS(obj, &out->crs); @@ -478,14 +488,16 @@ Status GeoParser::parseGeoJSONLine(const BSONObj& obj, LineWithCRS* out) { return status; // "coordinates" - status = parseGeoJSONLineCoordinates(obj[GEOJSON_COORDINATES], &out->line); + status = parseGeoJSONLineCoordinates(obj[GEOJSON_COORDINATES], skipValidation, &out->line); if (!status.isOK()) return status; return Status::OK(); } -Status GeoParser::parseGeoJSONPolygon(const BSONObj& obj, PolygonWithCRS* out) { +Status GeoParser::parseGeoJSONPolygon(const BSONObj& obj, + bool skipValidation, + PolygonWithCRS* out) { const BSONElement coordinates = obj[GEOJSON_COORDINATES]; Status status = Status::OK(); @@ -497,7 +509,7 @@ Status GeoParser::parseGeoJSONPolygon(const BSONObj& obj, PolygonWithCRS* out) { // "coordinates" if (out->crs == SPHERE) { out->s2Polygon.reset(new S2Polygon()); - status = parseGeoJSONPolygonCoordinates(coordinates, out->s2Polygon.get()); + status = parseGeoJSONPolygonCoordinates(coordinates, skipValidation, out->s2Polygon.get()); } else if (out->crs == STRICT_SPHERE) { out->bigPolygon.reset(new BigSimplePolygon()); status = parseBigSimplePolygonCoordinates(coordinates, out->bigPolygon.get()); @@ -527,7 +539,7 @@ Status GeoParser::parseMultiPoint(const BSONObj& obj, MultiPointWithCRS* out) { return Status::OK(); } -Status GeoParser::parseMultiLine(const BSONObj& obj, MultiLineWithCRS* out) { +Status GeoParser::parseMultiLine(const BSONObj& obj, bool skipValidation, MultiLineWithCRS* out) { Status status = Status::OK(); status = parseGeoJSONCRS(obj, &out->crs); if (!status.isOK()) @@ -545,7 +557,7 @@ Status GeoParser::parseMultiLine(const BSONObj& obj, MultiLineWithCRS* out) { // Iterate array while (it.more()) { lines.push_back(new S2Polyline()); - status = parseGeoJSONLineCoordinates(it.next(), lines.back()); + status = parseGeoJSONLineCoordinates(it.next(), skipValidation, lines.back()); if (!status.isOK()) return status; } @@ -555,7 +567,9 @@ Status GeoParser::parseMultiLine(const BSONObj& obj, MultiLineWithCRS* out) { return Status::OK(); } -Status GeoParser::parseMultiPolygon(const BSONObj& obj, MultiPolygonWithCRS* out) { +Status GeoParser::parseMultiPolygon(const BSONObj& obj, + bool skipValidation, + MultiPolygonWithCRS* out) { Status status = Status::OK(); status = parseGeoJSONCRS(obj, &out->crs); if (!status.isOK()) @@ -572,7 +586,7 @@ Status GeoParser::parseMultiPolygon(const BSONObj& obj, MultiPolygonWithCRS* out // Iterate array while (it.more()) { polygons.push_back(new S2Polygon()); - status = parseGeoJSONPolygonCoordinates(it.next(), polygons.back()); + status = parseGeoJSONPolygonCoordinates(it.next(), skipValidation, polygons.back()); if (!status.isOK()) return status; } @@ -650,7 +664,9 @@ Status GeoParser::parseCenterSphere(const BSONObj& obj, CapWithCRS* out) { // } // ] // } -Status GeoParser::parseGeometryCollection(const BSONObj& obj, GeometryCollection* out) { +Status GeoParser::parseGeometryCollection(const BSONObj& obj, + bool skipValidation, + GeometryCollection* out) { BSONElement coordElt = obj.getFieldDotted(GEOJSON_GEOMETRIES); if (Array != coordElt.type()) return BAD_VALUE("GeometryCollection geometries must be an array"); @@ -679,19 +695,20 @@ Status GeoParser::parseGeometryCollection(const BSONObj& obj, GeometryCollection status = parseGeoJSONPoint(geoObj, &out->points.back()); } else if (GEOJSON_LINESTRING == type) { out->lines.mutableVector().push_back(new LineWithCRS()); - status = parseGeoJSONLine(geoObj, out->lines.vector().back()); + status = parseGeoJSONLine(geoObj, skipValidation, out->lines.vector().back()); } else if (GEOJSON_POLYGON == type) { out->polygons.mutableVector().push_back(new PolygonWithCRS()); - status = parseGeoJSONPolygon(geoObj, out->polygons.vector().back()); + status = parseGeoJSONPolygon(geoObj, skipValidation, out->polygons.vector().back()); } else if (GEOJSON_MULTI_POINT == type) { out->multiPoints.mutableVector().push_back(new MultiPointWithCRS()); status = parseMultiPoint(geoObj, out->multiPoints.mutableVector().back()); } else if (GEOJSON_MULTI_LINESTRING == type) { out->multiLines.mutableVector().push_back(new MultiLineWithCRS()); - status = parseMultiLine(geoObj, out->multiLines.mutableVector().back()); + status = parseMultiLine(geoObj, skipValidation, out->multiLines.mutableVector().back()); } else if (GEOJSON_MULTI_POLYGON == type) { out->multiPolygons.mutableVector().push_back(new MultiPolygonWithCRS()); - status = parseMultiPolygon(geoObj, out->multiPolygons.mutableVector().back()); + status = parseMultiPolygon( + geoObj, skipValidation, out->multiPolygons.mutableVector().back()); } else { // Should not reach here. invariant(false); diff --git a/src/mongo/db/geo/geoparser.h b/src/mongo/db/geo/geoparser.h index 91cdb6649ea..be0e6359ed7 100644 --- a/src/mongo/db/geo/geoparser.h +++ b/src/mongo/db/geo/geoparser.h @@ -39,8 +39,8 @@ namespace mongo { // // This class also parses the ad-hoc geo formats that MongoDB introduced. // -// parse* methods may do some more validation than the is* methods; they return false if they -// encounter invalid geometry and true if the geometry is parsed successfully. +// parse methods where validation is time consuming optimize to skip +// validation if the BSONObj was previously validated. class GeoParser { public: // Geospatial specifier after $geoWithin / $geoIntersects predicates. @@ -80,13 +80,17 @@ public: static Status parseLegacyCenter(const BSONObj& obj, CapWithCRS* out); static Status parseLegacyPolygon(const BSONObj& obj, PolygonWithCRS* out); static Status parseCenterSphere(const BSONObj& obj, CapWithCRS* out); - static Status parseGeoJSONPolygon(const BSONObj& obj, PolygonWithCRS* out); + static Status parseGeoJSONPolygon(const BSONObj& obj, bool skipValidation, PolygonWithCRS* out); static Status parseGeoJSONPoint(const BSONObj& obj, PointWithCRS* out); - static Status parseGeoJSONLine(const BSONObj& obj, LineWithCRS* out); + static Status parseGeoJSONLine(const BSONObj& obj, bool skipValidation, LineWithCRS* out); static Status parseMultiPoint(const BSONObj& obj, MultiPointWithCRS* out); - static Status parseMultiLine(const BSONObj& obj, MultiLineWithCRS* out); - static Status parseMultiPolygon(const BSONObj& obj, MultiPolygonWithCRS* out); - static Status parseGeometryCollection(const BSONObj& obj, GeometryCollection* out); + static Status parseMultiLine(const BSONObj& obj, bool skipValidation, MultiLineWithCRS* out); + static Status parseMultiPolygon(const BSONObj& obj, + bool skipValidation, + MultiPolygonWithCRS* out); + static Status parseGeometryCollection(const BSONObj& obj, + bool skipValidation, + GeometryCollection* out); // For geo near static Status parseQueryPoint(const BSONElement& elem, PointWithCRS* out); diff --git a/src/mongo/db/geo/geoparser_test.cpp b/src/mongo/db/geo/geoparser_test.cpp index 201416e076b..a8fc1397659 100644 --- a/src/mongo/db/geo/geoparser_test.cpp +++ b/src/mongo/db/geo/geoparser_test.cpp @@ -99,27 +99,31 @@ TEST(GeoParser, parseGeoJSONLine) { LineWithCRS polyline; ASSERT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4]]}"), false, &polyline)); ASSERT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[0,-90], [0,90]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[0,-90], [0,90]]}"), false, &polyline)); ASSERT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[180,-90], [-180,90]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[180,-90], [-180,90]]}"), false, &polyline)); ASSERT_NOT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[180.1,-90], [-180.1,90]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[180.1,-90], [-180.1,90]]}"), + false, + &polyline)); ASSERT_NOT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[0,-91], [0,90]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[0,-91], [0,90]]}"), false, &polyline)); ASSERT_NOT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[0,-90], [0,91]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[0,-90], [0,91]]}"), false, &polyline)); ASSERT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]}"), false, &polyline)); ASSERT_NOT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[1,2]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[1,2]]}"), false, &polyline)); ASSERT_NOT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[['chicken','little']]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[['chicken','little']]}"), false, &polyline)); ASSERT_NOT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[1,2, 3, 4]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[1,2, 3, 4]}"), false, &polyline)); ASSERT_OK(GeoParser::parseGeoJSONLine( - fromjson("{'type':'LineString', 'coordinates':[[1,2, 3], [3,4, 5], [5,6]]}"), &polyline)); + fromjson("{'type':'LineString', 'coordinates':[[1,2, 3], [3,4, 5], [5,6]]}"), + false, + &polyline)); } TEST(GeoParser, parseGeoJSONPolygon) { @@ -127,37 +131,44 @@ TEST(GeoParser, parseGeoJSONPolygon) { ASSERT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]] ]}"), + false, &polygon)); // No out of bounds points ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,91],[0,5],[0,0]] ]}"), + false, &polygon)); ASSERT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[180,0],[5,5],[0,5],[0,0]] ]}"), + false, &polygon)); ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[181,0],[5,5],[0,5],[0,0]] ]}"), + false, &polygon)); // And one with a hole. ASSERT_OK(GeoParser::parseGeoJSONPolygon( fromjson( "{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]]," " [[1,1],[4,1],[4,4],[1,4],[1,1]] ]}"), + false, &polygon)); // Latitudes must be OK ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon( fromjson( "{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,91],[0,91],[0,0]]," " [[1,1],[4,1],[4,4],[1,4],[1,1]] ]}"), + false, &polygon)); // First point must be the same as the last. ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon( - fromjson("{'type':'Polygon', 'coordinates':[ [[1,2],[3,4],[5,6]] ]}"), &polygon)); + fromjson("{'type':'Polygon', 'coordinates':[ [[1,2],[3,4],[5,6]] ]}"), false, &polygon)); // Extra elements are allowed ASSERT_OK(GeoParser::parseGeoJSONPolygon( fromjson( "{'type':'Polygon', 'coordinates':[ [[0,0,0,0],[5,0,0],[5,5,1]," " [0,5],[0,0]] ]}"), + false, &polygon)); // Test functionality of polygon @@ -168,6 +179,7 @@ TEST(GeoParser, parseGeoJSONPolygon) { PolygonWithCRS polygonA; ASSERT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]] ]}"), + false, &polygonA)); ASSERT_TRUE(polygonA.s2Polygon->Contains(point.point)); @@ -176,6 +188,7 @@ TEST(GeoParser, parseGeoJSONPolygon) { fromjson( "{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]]," " [[1,1],[1,4],[4,4],[4,1],[1,1]] ]}"), + false, &polygonB)); // We removed this in the hole. ASSERT_FALSE(polygonB.s2Polygon->Contains(point.point)); @@ -185,6 +198,7 @@ TEST(GeoParser, parseGeoJSONPolygon) { PolygonWithCRS polygonC; ASSERT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[0,5],[5,5],[5,0],[0,0]] ]}"), + false, &polygonC)); ASSERT_TRUE(polygonC.s2Polygon->Contains(point.point)); @@ -193,6 +207,7 @@ TEST(GeoParser, parseGeoJSONPolygon) { fromjson( "{'type':'Polygon', 'coordinates':[ [[0,0],[0,5],[5,5],[5,0],[0,0]]," " [[1,1],[1,4],[4,4],[4,1],[1,1]] ]}"), + false, &polygonD)); // Also removed in the loop. ASSERT_FALSE(polygonD.s2Polygon->Contains(point.point)); @@ -205,6 +220,7 @@ TEST(GeoParser, parseGeoJSONPolygon) { PolygonWithCRS polygonBad; ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon( fromjson("{'type':'Polygon', 'coordinates':[[ [0,0], [0,0], [5,5], [5,5], [0,0] ]]}"), + false, &polygonBad)); } @@ -231,21 +247,21 @@ TEST(GeoParser, parseGeoJSONCRS) { "[[0,0],[5,0],[5,5],[0,5],[0,0]]," " [[1,1],[1,4],[4,4],[4,1],[1,1]] ]," + goodCRS1 + "}"); - ASSERT_OK(GeoParser::parseGeoJSONPolygon(polygon1, &polygon)); + ASSERT_OK(GeoParser::parseGeoJSONPolygon(polygon1, false, &polygon)); BSONObj polygon2 = fromjson( "{'type':'Polygon', 'coordinates':[ " "[[0,0],[5,0],[5,5],[0,5],[0,0]]," " [[1,1],[1,4],[4,4],[4,1],[1,1]] ]," + badCRS2 + "}"); - ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon(polygon2, &polygon)); + ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon(polygon2, false, &polygon)); LineWithCRS line; BSONObj line1 = fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]," + goodCRS2 + "}"); - ASSERT_OK(GeoParser::parseGeoJSONLine(line1, &line)); + ASSERT_OK(GeoParser::parseGeoJSONLine(line1, false, &line)); BSONObj line2 = fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]," + badCRS1 + "}"); - ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(line2, &line)); + ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(line2, false, &line)); } TEST(GeoParser, parseLegacyPoint) { @@ -311,6 +327,7 @@ TEST(GeoParser, parseMultiLine) { fromjson( "{'type':'MultiLineString','coordinates':[ [[1,1],[2,2],[3,3]]," "[[4,5],[6,7]]]}"), + false, &ml)); ASSERT_EQUALS(ml.lines.size(), (size_t)2); @@ -318,28 +335,30 @@ TEST(GeoParser, parseMultiLine) { GeoParser::parseMultiLine(fromjson( "{'type':'MultiLineString','coordinates':[ [[1,1],[2,2]]," "[[4,5],[6,7]]]}"), + false, &ml)); ASSERT_EQUALS(ml.lines.size(), (size_t)2); ASSERT_OK(GeoParser::parseMultiLine( - fromjson("{'type':'MultiLineString','coordinates':[ [[1,1],[2,2]]]}"), &ml)); + fromjson("{'type':'MultiLineString','coordinates':[ [[1,1],[2,2]]]}"), false, &ml)); ASSERT_EQUALS(ml.lines.size(), (size_t)1); ASSERT_OK( GeoParser::parseMultiLine(fromjson( "{'type':'MultiLineString','coordinates':[ [[1,1],[2,2]]," "[[2,2],[1,1]]]}"), + false, &ml)); ASSERT_EQUALS(ml.lines.size(), (size_t)2); ASSERT_NOT_OK(GeoParser::parseMultiLine( - fromjson("{'type':'MultiLineString','coordinates':[ [[1,1]]]}"), &ml)); + fromjson("{'type':'MultiLineString','coordinates':[ [[1,1]]]}"), false, &ml)); ASSERT_NOT_OK(GeoParser::parseMultiLine( - fromjson("{'type':'MultiLineString','coordinates':[ [[1,1]],[[1,2],[3,4]]]}"), &ml)); + fromjson("{'type':'MultiLineString','coordinates':[ [[1,1]],[[1,2],[3,4]]]}"), false, &ml)); ASSERT_NOT_OK(GeoParser::parseMultiLine( - fromjson("{'type':'MultiLineString','coordinates':[ [[181,1],[2,2]]]}"), &ml)); + fromjson("{'type':'MultiLineString','coordinates':[ [[181,1],[2,2]]]}"), false, &ml)); ASSERT_NOT_OK(GeoParser::parseMultiLine( - fromjson("{'type':'MultiLineString','coordinates':[ [[181,1],[2,-91]]]}"), &ml)); + fromjson("{'type':'MultiLineString','coordinates':[ [[181,1],[2,-91]]]}"), false, &ml)); } TEST(GeoParser, parseMultiPolygon) { @@ -352,6 +371,7 @@ TEST(GeoParser, parseMultiPolygon) { "[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]," "[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]" "]}"), + false, &mp)); ASSERT_EQUALS(mp.polygons.size(), (size_t)2); @@ -361,6 +381,7 @@ TEST(GeoParser, parseMultiPolygon) { "[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]," "[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]" "]}"), + false, &mp)); ASSERT_EQUALS(mp.polygons.size(), (size_t)1); } @@ -373,7 +394,7 @@ TEST(GeoParser, parseGeometryCollection) { "{ 'type': 'Point','coordinates': [100.0,0.0]}," "{ 'type': 'LineString', 'coordinates': [ [101.0, 0.0], [102.0, 1.0] ]}" "]}"); - ASSERT_OK(GeoParser::parseGeometryCollection(obj, &gc)); + ASSERT_OK(GeoParser::parseGeometryCollection(obj, false, &gc)); ASSERT_FALSE(gc.supportsContains()); } @@ -388,7 +409,7 @@ TEST(GeoParser, parseGeometryCollection) { "]}"); mongo::GeometryCollection gc; - ASSERT_OK(GeoParser::parseGeometryCollection(obj, &gc)); + ASSERT_OK(GeoParser::parseGeometryCollection(obj, false, &gc)); ASSERT_TRUE(gc.supportsContains()); } @@ -403,7 +424,7 @@ TEST(GeoParser, parseGeometryCollection) { "]}" "]}"); mongo::GeometryCollection gc; - ASSERT_NOT_OK(GeoParser::parseGeometryCollection(obj, &gc)); + ASSERT_NOT_OK(GeoParser::parseGeometryCollection(obj, false, &gc)); } { @@ -418,7 +439,7 @@ TEST(GeoParser, parseGeometryCollection) { "]}"); mongo::GeometryCollection gc; - ASSERT_OK(GeoParser::parseGeometryCollection(obj, &gc)); + ASSERT_OK(GeoParser::parseGeometryCollection(obj, false, &gc)); ASSERT_TRUE(gc.supportsContains()); } } |