Reputation: 323
I'm building an application in Java where I have to store GeoJson Polygons in MongoDB, and then I have to query to check a Point with how many of those polygons it intersects with $geoIntersects
.
I have a few questions regarding GeoJson Polygons which I didn't find the answers online.
The standard (https://www.rfc-editor.org/rfc/rfc7946) says:
A linear ring MUST follow the right-hand rule with respect to the area it bounds, i.e., exterior rings are counterclockwise, and holes are clockwise.
But I did a test where I save 2 circles as polygons, one clockwise and another counterclockwise, and if I query for a point inside, it seems to work fine in both cases.
# Clockwise:
"polygon": {
"type": "Polygon",
"coordinates": [
[
[-58.3816, -34.51386847158805 ], [-58.317506306149276, -34.531008005363724 ], [-58.27783822235179, -34.57589660852675 ], [-58.27776882904558, -34.631415496391675 ], [-58.317394025120045, -34.6763584216405 ], [-58.3816, -34.69353152841195 ], [-58.445805974879946, -34.6763584216405 ], [-58.48543117095441, -34.631415496391675 ], [-58.4853617776482, -34.57589660852675 ], [-58.44569369385072, -34.531008005363724 ], [-58.3816, -34.51386847158805 ] ]
]
}
# Counterclockwise
"polygon": {
"type": "Polygon",
"coordinates": [
[
[-58.3816, -34.51386847158805 ], [-58.44569369385072, -34.531008005363724 ], [-58.4853617776482, -34.57589660852675 ], [-58.48543117095441, -34.631415496391675 ], [-58.445805974879946, -34.6763584216405 ], [-58.3816, -34.69353152841195 ], [-58.317394025120045, -34.6763584216405 ], [-58.27776882904558, -34.631415496391675 ], [-58.27783822235179, -34.57589660852675 ], [-58.317506306149276, -34.531008005363724 ], [-58.3816, -34.51386847158805 ] ]
]
}
Thanks!
Upvotes: 4
Views: 928
Reputation: 323
After some searching and testing, I think I have the answer. I found this guide that took me to this ticket that eventualy sent me to this blog post.
- How do I check if a given polygon is in the right order?
The thing about the order of the points is that it defines wich side of the polygon is the one that you are intrested in, inner or outter. "MongoDB deterministically chooses the area that is the "smallest of the two".", unless you use "Big Polygon", where you define what order you are using.
If you really want to check the order, I found this function that I took from this validator:
function isRingClockwise (coords) {
var area = 0;
if (coords.length > 2) {
var p1, p2;
for (var i = 0; i < coords.length - 1; i++) {
p1 = coords[i];
p2 = coords[i + 1];
area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1])));
}
}
return area >= 0;
}
- Is there a java library that will check if my polygon is valid?
- What happens if the list of points that I'm saving has intersecctions?
There is actually no need for this.
If the field has a 2dindex, then Mongo will not let you save polygons that self intersect or that are not closed. It will throw an exception: WriteConcernException: Write failed with error code 16755 and error message 'Can't extract geo keys:
, and then something like Edges 1 and 3 cross
.
If the field does not have an index, those wrong polygons (self intersecting or open) will not intersect with any point.
The old and obsolete GeoJson specifications didn't talk about order of coordinates, but the new one does.
The links that I found have dates prior to the new specifications.
I don't know if this could make Mongo change it's default about considering the smaller part of the line as the polygon, but up to version 4.0 of MongoDB, it still works this way.
Upvotes: 4