-
Notifications
You must be signed in to change notification settings - Fork 448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
intersects on 0-length linestring returns incorrect result #345
Comments
As a side note - I firstly found this strange behaviour in postgis (ST_Intersects), so geos is probably also concerned. |
The short answer to this is that JTS considers 0-length linestrings to be invalid, so the result of operations on it is undefined. I did this originally because I thought I read the OCG SFS specification ( 99-009 ) to say that Curves and thus LineStrings were not allowed to be zero-length. (See section 2.1.5). But reading it now I can't see anything that implies that. So perhaps the JTS semantics are fundamentally wrong in this respect! What the specification does say is that a LineString is closed if the endpoints are equal, and that a closed LineString has no boundary (only an interior). So this means that LINESTRING( x y, x y) is topologically equal to POINT (x y) - as you would expect. So perhaps this means that zero-length linestrings can simple be changed into points internally. This can possibly be done in Can you try that out and see what happens? For consistency, fixing this also requires a change in the isValid semantics as well. And associated unit tests. I can't think of anywhere else affected - but that's not a 100% guarantee. |
By the way, in general JTS operations do not throw for invalid inputs, since that could require expensive validity checks. |
Actually allowing zero-length lines leads to another nasty question. Topologically they are equivalent to Points, which have dimension = 0. But the spec states that "Curves are dimension-1 geometries". And in JTS LineStrings are assigned dimension 1 statically. So this might lead to some oddness in the IntersectionMatrix calculations. |
Hi, |
I agree that returning a consistent result or an exception is a worth goal, but as I mentioned, this would require expensive validity checks. So I don't think that's practical. But it's possible to widen the scope of what results are consistent where this doesn't incur too much overhead. Handling zero-length linestrings is likely one of those cases. |
Perhaps it would be possible to handle zero-area polygons in a similar way? (I.e. reducing them to a point). Of course then the question is whether polygons which collapse to a line should be handled too. That's substantially more expensive to test, however. |
On a different tack, In fact, |
Polygon is probably more difficult to handle. Would it be possible to consider that polygons with a 0-length boundary have dimension 0 and polygons with a boundary > 0 but an area = 0 have dimension 1 ? Or length/area are not strict enough to make such conclusion ? I did not know about PreparedGeometry.intersects ;-) Interesting. I will test it. Any reason why geometry.intersects use relate instead of PreparedGeometry.intersects in this case ? |
It is probably better to avoid tying subtle relationship logic to length and area, because they are subject to precision issues. Also, that logic is getting a bit complex. Perhaps it's enough to detect polygons with only a single point and handle that in the same way as LineStrings. |
PeparedGeometry uses a different algorithm which allows caching and fast evaluation of the simpler predicates (intersects and covers - which conveniently happen to be the most useful ones). Also, that code was written some time after the original relate code. I haven't had time to work on wiring it up for the geometry predicates yet. |
This will be fixed by the forthcoming |
Intersecting a 0-length linestring should either throw an exception or returns the same result as if it was a point.
test case :
line = wktreader.read("LINESTRING(10 20,10 20)");
line.intersects(line) ==> returns false !!
line.intersects(line.buffer(1)) ==> returns false !!
RelateOp is quite complex, and I did not find an easy way to fix it. I noticed that :
One solution is to throw an exception, but I'd rather process the relateOp as if input geometry was a Point. I don't know if it is possible to substitute input geometry by a point somewhere in the algorithm.
Any thought about it ?
The text was updated successfully, but these errors were encountered: