-
Notifications
You must be signed in to change notification settings - Fork 43
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
Failures with GEOS master / 3.10 #233
Comments
|
So for the WKB issue, in my example above, |
|
The WKB issue is already fixed by @pramsey: libgeos/geos@fa24fb2 |
|
The issue was somewhat describe in GEOS Trac #1048. I haven't had a chance to investigate the new behaviour yet... |
|
Note that the second issue mentioned above (the dimensionality in WKB roundtrips) is already fixed, see the commit I linked to above (I reported it on the GEOS chat channel, and Paul promptly fixed it) The first issue is while before this raised an error. This relates to this code in pygeos: Lines 1491 to 1503 in 2e65c2d
and Lines 26 to 31 in 2e65c2d
So before, this raised an error if you tried to create a Point with a 4 dimensional coord sequence, or when trying to create a 4 dimensional coord sequence (not directly sure which of the two raised the error) So it might be related to the changes that were done to fix the WKB/WKT dimensionality issues, but it is not about WKB/WKT itself. |
|
So with GEOS 3.8, the error we currently get is: This error comes from |
|
Ah, got it. libgeos/geos@8e29f76 accidentally changed the error return value for Should be an easy fix, can do a PR in a few days unless someone already wants to give it a go (would ideally add a test for the GEOS C API as well): --- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -2164,7 +2164,7 @@ extern "C" {
GEOSCoordSeq_setOrdinate_r(GEOSContextHandle_t extHandle, CoordinateSequence* cs,
unsigned int idx, unsigned int dim, double val)
{
- return execute(extHandle, 1, [&]() {
+ return execute(extHandle, 0, [&]() {
cs->setOrdinate(idx, dim, val);
return 1;
}); |
|
I made a small PR to fix the above explained issue: libgeos/geos#354 But, we have a new bunch of failures: a large part of the STRtree tests are failing with GEOS master (which is about to be released). See eg https://github.com/pygeos/pygeos/runs/1465460418#step:9:86 I mailed geos-devel about it: https://lists.osgeo.org/pipermail/geos-devel/2020-November/009870.html |
|
@jorisvandenbossche This is solved right? |
|
We still have a few failures on GEOS master: For the doctests, we could maybe limit ourselves to run the doctests on a single GEOS / Python combo, eg latest versions (printing precision changed in GEOS 3.10?). For the geos version string failures, see also #262 (comment) The empty point / nan failures is something to further look into |
This seems wrong to me. It confuses the WKB representation of a thing (two nans for empty) with the thing itself (POINT EMPTY). While yes, Nan != Nan, that's not what should be tested. POINT EMPTY == POINT EMPTY. Just like LINESTRING EMPTY == LINESTRING EMPTY. |
|
Indeed POINT EMPTY should equal POINT EMPTY. But I assume the test was supposed to check POINT(nan nan) != POINT(nan nan) (which I think is expected?), and something changed in the construction of POINT(nan nan). |
|
Yes, it's possible that WKB logic leaked into the constructor, I had to wrestle with POINT EMPTY WKB issues earlier. |
|
So with GEOS 3.8 (and I assume 3.9 as well), we have: But with GEOS master the above results in empty points Or possibly related with libgeos/geos@693c1aa? Which makes that POINT(nan nan) is regarded as empty |
|
The change came from a pygeos/shapely ticket... https://trac.osgeo.org/geos/ticket/1049 I dunno. It's a stupid thing to spend too much time on, as a Point(nan nan) is a fundamentally useless thing. Do we want to be able to represent it with fidelity? Do we really care how it behaves? |
|
I am comfortable with making POINT (nan nan) convert automatically to POINT EMPTY in the constructor. Completely agree with the fact that we should not spend to much time on this. I will have a look at fixing our tests. |
|
Yeah, sorry for the slow reply, and to be clear @pramsey I didn't mean to say that you should spend more time on this topic ;). I was just trying to understand what changed. |
|
We have one failure left on GEOS master: Seems to be a rounding difference, maybe just in the representation. |
|
Hard to tell without seeing the whole object, but you might want to ensure the result and the expected are both normalized so you don't have failures just because of things like ordinate order. |
|
We have a bunch of new failures with GEOS master related to the creation of LinearRings, especially with too few coordinates: With GEOS 3.9.1, we get: while with GEOS master this actually creates an (invalid?) LinearRing: Was this a deliberate change in GEOS? (in which case we probably can easily check the length ourselves and still raise an error if we want) |
|
@pramsey this changed in libgeos/geos@5156001#diff-41827735da42696d53e556926e2a31c49970245de846ac5b4169f506bcdc7f81R65 (the commit porting the new MakeValid implementation) because
That seems quite deliberate ;) |
|
It seems we have a whole bunch of failures with GEOS dev branch (in latest CI run it was using the beta3 tag). Groups of failures:
Pytest output: |
|
Making the changes between GEOS 3.9.1 and GEOS 3.10.0 a bit more visible (compared to the test output). Summary seems to be that most of them are precision issues in our tests, only the
>>> pygeos.set_precision(pygeos.Geometry("LINESTRING (0 0, 0.1 0.1)"), grid_size=1)
<pygeos.Geometry LINESTRING EMPTY> # <-- with GEOS 3.9.1
<pygeos.Geometry LINESTRING (0 0, 0 0)> # <-- with GEOS 3.10.0
>>> pygeos.set_precision(pygeos.Geometry("POLYGON ((0 0, 0.1 0, 0.1 0.1, 0 0.1, 0 0))"), grid_size=1)
<pygeos.Geometry POLYGON EMPTY> # <-- with GEOS 3.9.1
<pygeos.Geometry POLYGON ((0 0, 0 0, 0 0, 0 0, 0 0))> # <-- with GEOS 3.10.0I don't really know if one or the other is preferred, but one consequence of the new result is that those returned geometries are no longer "valid" geometries. Changes in "crosses" and "touches" >>> line = pygeos.Geometry("LINESTRING (1 1, 2 2)")
>>> poly = pygeos.buffer(pygeos.Geometry("POINT (2 1)"), 1)
>>> pygeos.crosses(poly, line)
True # <-- with GEOS 3.9.1
False # <-- with GEOS 3.10.0This could also be due to slight changes in the output of the buffer operation. >>> import math
>>> line = pygeos.Geometry("LINESTRING (1 1, 2 2)")
>>> poly = pygeos.buffer(pygeos.Geometry("POINT (2 1)"), math.sqrt(2) / 2)
>>> pygeos.touches(poly, line)
False # <-- with GEOS 3.9.1
True # <-- with GEOS 3.10.0Similarly here (the test actually mentions that there is no overlap due to precision issues) So I suppose those two were corner cases / non-robust test cases due to crossing or not touching only because of precision issues. Changes in The same seems to be true for the >>> import math
>>> poly = pygeos.buffer(pygeos.points(2.5, 2.5), math.sqrt(2) / 2)
>>> points = pygeos.points(np.arange(10), np.arange(10))
>>> points
array([<pygeos.Geometry POINT (0 0)>, <pygeos.Geometry POINT (1 1)>,
<pygeos.Geometry POINT (2 2)>, <pygeos.Geometry POINT (3 3)>,
<pygeos.Geometry POINT (4 4)>, <pygeos.Geometry POINT (5 5)>,
<pygeos.Geometry POINT (6 6)>, <pygeos.Geometry POINT (7 7)>,
<pygeos.Geometry POINT (8 8)>, <pygeos.Geometry POINT (9 9)>],
dtype=object)
>>> pygeos.distance(poly, points)
array([2.82842712e+00, 1.41421356e+00, 0.00000000e+00, 3.69350335e-16, # <-- with GEOS 3.9.1
1.41421356e+00, 2.82842712e+00, 4.24264069e+00, 5.65685425e+00,
7.07106781e+00, 8.48528137e+00])
array([2.82842712, 1.41421356, 0. , 0. , 1.41421356, # <-- with GEOS 3.10.0
2.82842712, 4.24264069, 5.65685425, 7.07106781, 8.48528137])So the distance to |
|
How are you handling that second argument in It's the argument that determines if collapses will be kept or not. The enum in GEOS is this: And the argument is the bitwise OR of those values together... If the python wrapper is exposing the CAPI directly, maybe that '1' in the test should be a '2'? Or maybe the wrapper has its own internal mapping? |
|
That second argument is actually the grid_size (I updated the code snippet to be explicit about that). But I was also just checking how we deal with those flags. With GEOS 3.10.0 I see: >>> pygeos.set_precision(pygeos.Geometry("LINESTRING (0 0, 0.1 0.1)"), grid_size=1, preserve_topology=False)
<pygeos.Geometry LINESTRING (0 0, 0 0)>
>>> pygeos.set_precision(pygeos.Geometry("LINESTRING (0 0, 0.1 0.1)"), grid_size=1, preserve_topology=True)
<pygeos.Geometry LINESTRING Z EMPTY>This We currently don't set the Lines 2048 to 2052 in 01e02cd
(I don't exactly remember the reasoning for this) |
|
The behaviour is tested in https://github.com/libgeos/geos/blob/main/tests/unit/capi/GEOSGeom_setPrecisionTest.cpp, and seems to be "according to plan". |
|
There's unfortunately a poor mapping between what the old and new routines do for collapses, and the behaviour you see is (a) on purpose but (b) not exactly as before but (c) a little closer to what the worlds "collapse" and "topology" might be construed to mean. I'd generally get rid of "preserve topology" as an option, because what it means in entirely unclear and go with just "preserve collapsed" since that's a good deal more obvious and as a bonus will neatly match behaviour. |
|
I patched pygeos for a moment to let the and with GEOS 3.9.1: So we were using
Would you recommend to still set the |
I don't recommend setting GEOS_PREC_NO_TOPO as the default, since it is likely to output invalid geometries. (Not just in this case, but in general - it reduces pointwise, which can cause polygons to self-intersect). You can think of GEOS_PREC_NO_TOPO as GEOS_PREC_MAY_BE_INVALID, if that helps :) |
|
Thanks for the feedback! Looking back at the original PR adding this to PyGEOS (#257), it seems we went with a default of We should probably switch the default, and maybe even reconsider whether it is useful at all to expose the option to ask for |
|
Right, we went with those defaults to match |
|
Here's some clarification of the
Notes
|
|
I've added these to the doxygen, which will be more visible online shortly. |
|
I propose exposing the 3 different modes directly to the user, with (as recommended) 0 as default option. This will be an API breakage, which is fine by me as we are still doing “experimental” releases in pygeos. The tests should then be examined and possibly be made GEOS version dependent where the output of GEOS changed. |
|
@pramsey Do you have an estimate of the planned release date of GEOS 3.10? |
|
Today or maybe a couple days, depending on how bloody-minded I am with the demands of packagers. |
I was testing with GEOS master (in light of the new OverlayNG), and next to 2 failures related to the new overlay implementation (which I am fixing in #232), there are also 2 other failures:
The first case now seems to ignore the 4th dimension, and create a POINT Z:
In the second case, the WKB of an empty polygon differs depending on whether the empty polygon was created from WKT or WKB:
The text was updated successfully, but these errors were encountered: