summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2015-03-10 16:12:08 -0400
committerSiyuan Zhou <siyuan.zhou@mongodb.com>2015-03-12 12:34:28 -0400
commitbd489b1c2c76a7ee84105db758839c4d47ffcbcb (patch)
tree639f1f66cecfa0dde9fae9cbbe227790f1583179
parent9f7cc8a7029cbbdcc080d0f25aa6db35fda8f6b9 (diff)
downloadmongo-bd489b1c2c76a7ee84105db758839c4d47ffcbcb.tar.gz
SERVER-9220 allow more than two values in the coordinate-array when using 2dsphere index
-rw-r--r--src/mongo/db/geo/geoparser.cpp20
-rw-r--r--src/mongo/db/geo/geoparser_test.cpp39
2 files changed, 36 insertions, 23 deletions
diff --git a/src/mongo/db/geo/geoparser.cpp b/src/mongo/db/geo/geoparser.cpp
index 8b8c3aebb63..5fd1c86a741 100644
--- a/src/mongo/db/geo/geoparser.cpp
+++ b/src/mongo/db/geo/geoparser.cpp
@@ -108,11 +108,11 @@ namespace mongo {
return Status::OK();
}
- static Status parseGeoJSONCoodinate(const BSONElement& elem, S2Point* out) {
+ static Status parseGeoJSONCoordinate(const BSONElement& elem, S2Point* out) {
if (Array != elem.type()) { return BAD_VALUE("GeoJSON coordinates must be an array"); }
Point p;
- // Check the object has and only has 2 numbers.
- Status status = parseFlatPoint(elem, &p);
+ // GeoJSON allows extra elements, e.g. altitude.
+ Status status = parseFlatPoint(elem, &p, true);
if (!status.isOK()) return status;
status = coordToPoint(p.x, p.y, out);
@@ -120,13 +120,13 @@ namespace mongo {
}
// "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
- static Status parseArrayOfCoodinates(const BSONElement& elem, vector<S2Point>* out) {
+ static Status parseArrayOfCoordinates(const BSONElement& elem, vector<S2Point>* out) {
if (Array != elem.type()) { return BAD_VALUE("GeoJSON coordinates must be an array of coordinates"); }
BSONObjIterator it(elem.Obj());
// Iterate all coordinates in array
while (it.more()) {
S2Point p;
- Status status = parseGeoJSONCoodinate(it.next(), &p);
+ Status status = parseGeoJSONCoordinate(it.next(), &p);
if (!status.isOK()) return status;
out->push_back(p);
}
@@ -168,7 +168,7 @@ namespace mongo {
// Parse the array of vertices of a loop.
BSONElement coordinateElt = it.next();
vector<S2Point> points;
- status = parseArrayOfCoodinates(coordinateElt, &points);
+ status = parseArrayOfCoordinates(coordinateElt, &points);
if (!status.isOK()) return status;
// Check if the loop is closed.
@@ -269,7 +269,7 @@ namespace mongo {
Status status = Status::OK();
string err;
- status = parseArrayOfCoodinates(coordinates.front(), &exteriorVertices);
+ status = parseArrayOfCoordinates(coordinates.front(), &exteriorVertices);
if (!status.isOK()) return status;
status = isLoopClosed(exteriorVertices, coordinates.front());
@@ -346,7 +346,7 @@ namespace mongo {
// Or a line in "coordinates" field of GeoJSON MultiLineString
static Status parseGeoJSONLineCoordinates(const BSONElement& elem, S2Polyline* out) {
vector<S2Point> vertices;
- Status status = parseArrayOfCoodinates(elem, &vertices);
+ Status status = parseArrayOfCoordinates(elem, &vertices);
if (!status.isOK()) return status;
eraseDuplicatePoints(&vertices);
@@ -425,7 +425,7 @@ namespace mongo {
if (!status.isOK()) return status;
// "coordinates"
- status = parseFlatPoint(obj[GEOJSON_COORDINATES], &out->oldPoint);
+ status = parseFlatPoint(obj[GEOJSON_COORDINATES], &out->oldPoint, true);
if (!status.isOK()) return status;
// Projection
@@ -478,7 +478,7 @@ namespace mongo {
out->points.clear();
BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
- status = parseArrayOfCoodinates(coordElt, &out->points);
+ status = parseArrayOfCoordinates(coordElt, &out->points);
if (!status.isOK()) return status;
if (0 == out->points.size())
diff --git a/src/mongo/db/geo/geoparser_test.cpp b/src/mongo/db/geo/geoparser_test.cpp
index fd863447563..2387696b7be 100644
--- a/src/mongo/db/geo/geoparser_test.cpp
+++ b/src/mongo/db/geo/geoparser_test.cpp
@@ -73,7 +73,7 @@ namespace {
fromjson("{'type':'Point', 'coordhats': [40, -5]}"), &point));
ASSERT_NOT_OK(GeoParser::parseGeoJSONPoint(
fromjson("{'type':'Point', 'coordinates': 40}"), &point));
- ASSERT_NOT_OK(GeoParser::parseGeoJSONPoint(
+ ASSERT_OK(GeoParser::parseGeoJSONPoint(
fromjson("{'type':'Point', 'coordinates': [40, -5, 7]}"), &point));
// Make sure lat is in range
@@ -105,7 +105,8 @@ namespace {
ASSERT_OK(GeoParser::parseGeoJSONLine(
fromjson("{'type':'LineString', 'coordinates':[[180,-90], [-180,90]]}"), &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]]}"),
+ &polyline));
ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(
fromjson("{'type':'LineString', 'coordinates':[[0,-91], [0,90]]}"), &polyline));
ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(
@@ -118,22 +119,27 @@ namespace {
fromjson("{'type':'LineString', 'coordinates':[['chicken','little']]}"), &polyline));
ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(
fromjson("{'type':'LineString', 'coordinates':[1,2, 3, 4]}"), &polyline));
- ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(
- fromjson("{'type':'LineString', 'coordinates':[[1,2, 3], [3,4, 5], [5,6]]}"), &polyline));
+ ASSERT_OK(GeoParser::parseGeoJSONLine(
+ fromjson("{'type':'LineString', 'coordinates':[[1,2, 3], [3,4, 5], [5,6]]}"),
+ &polyline));
}
TEST(GeoParser, parseGeoJSONPolygon) {
PolygonWithCRS polygon;
ASSERT_OK(GeoParser::parseGeoJSONPolygon(
- fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]] ]}"), &polygon));
+ fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]] ]}"),
+ &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]] ]}"), &polygon));
+ fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,91],[0,5],[0,0]] ]}"),
+ &polygon));
ASSERT_OK(GeoParser::parseGeoJSONPolygon(
- fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[180,0],[5,5],[0,5],[0,0]] ]}"), &polygon));
+ fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[180,0],[5,5],[0,5],[0,0]] ]}"),
+ &polygon));
ASSERT_NOT_OK(GeoParser::parseGeoJSONPolygon(
- fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[181,0],[5,5],[0,5],[0,0]] ]}"), &polygon));
+ fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[181,0],[5,5],[0,5],[0,0]] ]}"),
+ &polygon));
// And one with a hole.
ASSERT_OK(GeoParser::parseGeoJSONPolygon(
fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]],"
@@ -145,7 +151,10 @@ namespace {
// 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));
-
+ // 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]] ]}"), &polygon));
// Test functionality of polygon
PointWithCRS point;
@@ -211,17 +220,21 @@ namespace {
ASSERT_NOT_OK(GeoParser::parseGeoJSONPoint(point4, &point));
PolygonWithCRS polygon;
- BSONObj polygon1 = fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]],"
+ BSONObj polygon1 = fromjson("{'type':'Polygon', 'coordinates':[ "
+ "[[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));
- BSONObj polygon2 = fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]],"
+ 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));
LineWithCRS line;
- BSONObj line1 = fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]," + goodCRS2 + "}");
+ BSONObj line1 = fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]," +
+ goodCRS2 + "}");
ASSERT_OK(GeoParser::parseGeoJSONLine(line1, &line));
- BSONObj line2 = fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]," + badCRS1 + "}");
+ BSONObj line2 = fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]," +
+ badCRS1 + "}");
ASSERT_NOT_OK(GeoParser::parseGeoJSONLine(line2, &line));
}