Open alkra opened 1 year ago
I can confirm the issue. The issue does occur for both positive or negative line offset depending on the direction of the closed line (clockwise / counterclockwise). It seems to me it is related to the GEOS version used by QGIS on a system rather than the QGIS version.
It seems to me it is related to the GEOS version used by QGIS on a system rather than the QGIS version.
See:
QGIS 3.16 using GEOS 3.8.1
QGIS 3.16 using GEOS 3.11.1
Wanted to report a related side-effect. In "standard" QGIS 3.16, a self-intersecting polyline could have an offset with no issue. In 3.22 and 3.28, the offset is not drawn in those cases.
To further support the GEOS library case, in 3.22.10, with GEOS GEOS version 3.10.3-CAPI-1.16.1
the issue is not seen, but in 3.22.14 with GEOS 3.11.1 the issue is seen.
The image below shows what the output "should" be in case of self intersecting lines (and what is seen in 3.16 / 3.22.10:
The black centerline is the polygon. The Red line is an offset line in the stle with possitive offset and the green one has negative offsets.
I compiled geos and tested both versions 3.10.4 and 3.11.1 with geosop
.
In the table below, LINESTRING(0 0,10 0,10 10,0 10,0 0) will be abreviated [ccw] (for counterclockwise) and LINESTRING(0 0,0 10,10 10,10 0,0 0) [cw].
command | result-3.10 | 3.10 reversed? | result-3.11 | 3.11 reversed? | QGIS offset sign | QGIS regress? |
---|---|---|---|---|---|---|
geosop -a [ccw] -f wkt offsetCurve 2 | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | N | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | N | - | N |
geosop -a [ccw] -f wkt offsetCurve N-2 | LINESTRING (-2 0,-2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | Y | LINESTRING (0 -2, 10 -2, [...], 12 0, 12 10, [...], -2 10, -2 0) | N | + | Y |
geosop -a [cw] -f wkt offsetCurve 2 | LINESTRING (-2 0, -2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | N | LINESTRING (-2 0, -2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | N | - | Y |
geosop -a [cw] -f wkt offsetCurve N-2 | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | Y | LINESTRING (2 2, 2 8, 8 8, 8 2, 2 2) | N | + | N |
So, it seems that:
a. GEOS does not drop points, but its behaviour changed
b. QGIS offsets are signed in the opposite way as GEOS offsets
c. QGIS fails when the curve orientation has the same sign as the QGIS offset
Open questions:
Where in the code is QGIS dropping the start and end nodes? Does it call a function which drops duplicated nodes?
Why does QGIS only drops duplicated nodes when the curve orientation has the same sign as the offset?
I found the related source code in QGIS, but I can't attach a debugger on my system, and I do not quite understand it.
@garci66: are you able to run geosop
on your system? Does GEOS do the right thing? Does it depend on the line orientation? Your test case seems to support question 1., i.e. QGIS is performing a validation somewhere.
I have never tested geosp... im really not familar with it. I can take a look though and see. I also opened an issue on the GEOS side:
https://github.com/libgeos/geos/issues/816
But in particular it seems related to changes rasised by this issue: https://github.com/libgeos/geos/issues/477
and this merged PR seems to be the main change https://github.com/libgeos/geos/pull/530
in my case, the main problem is with self intersecting polygons such as the following: LINESTRING(0 0,10 0, 10 -5 ,0 10)
where the difference between versions is very significant:
geosop -a "LINESTRING(0 0,10 0, 10 -5 ,0 10)" -f wkt offsetCurve 2
With GEOSOP 3.10 the result is
MULTILINESTRING ((7.73703418364266 2, 10 2, 10.390180644032256 1.9615705608064609, 10.76536686473018 1.8477590650225735, 11.111140466039204 1.6629392246050905, 11.414213562373096 1.414213562373095, 11.66293922460509 1.1111404660392044, 11.847759065022574 0.7653668647301796, 11.96157056080646 0.3901806440322565, 12 0, 12 -5, 11.961539159351426 -5.390338476621126, 11.847635873669098 -5.765664207293921, 11.662670959072994 -6.111541848899666, 11.413758321668972 -6.414668656580661, 11.110471350739644 -6.663386118490374, 10.764474718144712 -6.848128351959778, 10.38907574523535 -6.961790015386345, 9.99871259208827 -6.999999585645174, 9.60839895373173 -6.96128749054329, 9.23314662081353 -6.847142629801578, 8.88738811351304 -6.66195511071988, 8.584421594682436 -6.412847400959701, 8.335899411324313 -6.109400392450459, 5.596299149690674 -2), (0 2, 2.9296324830240073 2, -1.6641005886756874 8.890599607549541))
(the multilinestring was expected, as the loop figure has to be cut)
while with GEOSOP 3.11.1:
LINESTRING (0 2, 2.9296324830240073 2, -1.6641005886756874 8.890599607549541)
which is clearly different (misses the "looped over itself" part)
while the other option (negative offset)
geosop -a "LINESTRING(0 0,10 0, 10 -5 ,0 10)" -f wkt offsetCurve N-2
the result for 3.10 is
MULTILINESTRING ((1.6641005886756874 11.109400392450459, 7.73703418364266 2), (5.596299149690674 -2, 0 -2))
and for 3.11 its even worse:
LINESTRING (0 -2, 5.596299149690674 -2)
as its only doing an offset for the first segment of the line and nothing else!
the image below is not the linestring drawn above but its a similar example:
you can see that one of the offsets gets truncated in the first segment
Another test case in https://github.com/qgis/QGIS/issues/51750.
With issue: Artifact from MinGW64 Windows build (https://github.com/qgis/QGIS/commit/d0a9f1249448c5dbde370052852220179df1ee8f)
https://github.com/qgis/QGIS/suites/10798239191/artifacts/543108183
QGIS version | 3.29.0-Master | QGIS code branch | master |
---|---|---|---|
Qt version | 5.15.8 | ||
Python version | 3.11.1 | ||
GDAL/OGR version | 3.6.2 | ||
PROJ version | 9.1.1 | ||
EPSG Registry database version | v10.076 (2022-08-31) | ||
GEOS version | 3.11.1-CAPI-1.17.1 | ||
SQLite version | 3.36.0 | ||
PostgreSQL client version | unknown | ||
SpatiaLite version | 5.0.1 | ||
QWT version | 6.2.0 | ||
QScintilla2 version | 2.13.0 | ||
OS version | Windows 10 Version 2009 | ||
This copy of QGIS writes debugging output. | | | Active Python plugins db_manager | 0.1.20 grassprovider | 2.12.99 MetaSearch | 0.3.6 processing | 2.12.99
No issue:
QGIS version | 3.29.0-Master | QGIS code revision | d0a9f12494 |
---|---|---|---|
Qt version | 5.15.3 | ||
Python version | 3.10.6 | ||
GDAL/OGR version | 3.7.0dev-6bdeb5623b | ||
PROJ version | 8.2.1 | ||
EPSG Registry database version | v10.041 (2021-12-03) | ||
GEOS version | 3.10.2-CAPI-1.16.0 | ||
SQLite version | 3.37.2 | ||
PostgreSQL client version | unknown | ||
SpatiaLite version | 5.0.1 | ||
QWT version | 6.1.4 | ||
QScintilla2 version | 2.11.6 | ||
OS version | Ubuntu 22.04.1 LTS | ||
Active Python plugins grassprovider | 2.12.99 MetaSearch | 0.3.6 processing | 2.12.99 db_manager | 0.1.20
From https://github.com/qgis/QGIS/issues/51750:
Sometimes, if the line is not fully visible on the canvas, there is no issue:
GEOS behavior has changed but it looks like we are mixing two different issues here:
yes... sorry about that. At first I thought they could be related since both seemed to stem from the change in libgeos version. But I can open a separate issue tracking the upstream GEOS issue
No worries, just wanted to point that out because it wasn't clear for me on a first sight.
For me there's no need to open a separate issue - @agiudiceandrea what do you think?
2. GEOSOffsetCurve_r behaviour has changed on self-intersecting lines libgeos/geos#816 -> Upstream GEOS issue
@pathmapper, it seems such issue has been allegedly fixed in GEOS 3.12 with https://github.com/libgeos/geos/commit/7561b50f943305b1419bd655e10e7dcad2cb9492.
1. Missing first and last segment of a closed linestring with offset -> the issue seems to be a changed orientation of the GEOS output for some cases -> possibly fixable on QGIS side
This one is still an issue: https://github.com/qgis/QGIS/issues/55050.
@pathmapper, it seems such issue has been allegedly fixed in GEOS 3.12 with libgeos/geos@7561b50.
Given that one issue is already fixed upstrean and second has a separate ticket should we close this?
The QGIS project highly values your report and would love to see it addressed. However, this issue has been left in feedback mode for the last 14 days and is being automatically marked as "stale". If you would like to continue with this issue, please provide any missing information or answer any open questions. If you could resolve the issue yourself meanwhile, please leave a note for future readers with the same problem and close the issue. In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this issue. If there is no further activity on this issue, it will be closed in a week.
@alexbruy ... I understand the fix is already in upstream but, pardon my ignorance, do we known when / how it will be integrated into the main QGIS builds? can we get a view of which LTS versions would get the fix? just to be sure so we can test it. Thanks!
Also.. seems like #55050 was auto-closed... and not sure its fixed yet
The QGIS project highly values your report and would love to see it addressed. However, this issue has been left in feedback mode for the last 14 days and is being automatically marked as "stale". If you would like to continue with this issue, please provide any missing information or answer any open questions. If you could resolve the issue yourself meanwhile, please leave a note for future readers with the same problem and close the issue. In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this issue. If there is no further activity on this issue, it will be closed in a week.
I compiled QGIS against GEOS 3.12.1. Same erroneous behaviour.
QGIS version: 3.35.0-Master QGIS code revision: 8677bc2f18 Qt version: 5.15.10 Python version: 3.11.7 GDAL/OGR version: 3.8.2 PROJ version: 9.3.1 EPSG Registry database version: v10.098 (2023-11-24) GEOS version: 3.12.1-CAPI-1.18.1 SQLite version: 3.44.2 PostgreSQL client version: 16.1 (Debian 16.1-1) SpatiaLite version: 5.1.0 QWT version: 6.1.4 QScintilla2 version: 2.14.1 OS version: Debian GNU/Linux trixie/sid
I tested geosopt
on 3.12.1:
command | result-3.10 | 3.10 reversed? | result-3.11 | 3.11 reversed? | result-3.12 | 3.12 reversed? | QGIS offset sign | QGIS regress? |
---|---|---|---|---|---|---|---|---|
geosop -a [ccw] -f wkt offsetCurve 2 | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | N | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | N | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | N | - | N |
geosop -a [ccw] -f wkt offsetCurve N-2 | LINESTRING (-2 0,-2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | Y | LINESTRING (0 -2, 10 -2, [...], 12 0, 12 10, [...], -2 10, -2 0) | N | LINESTRING (0 -2, 10 -2, [...], 12 0, 12 10, [...], -2 10, -2 0) | N | + | Y |
geosop -a [cw] -f wkt offsetCurve 2 | LINESTRING (-2 0, -2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | N | LINESTRING (-2 0, -2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | N | LINESTRING (-2 0, -2 10, [...], 0 12, 10 12, [...], 10 -2, 0 -2) | N | - | Y |
geosop -a [cw] -f wkt offsetCurve N-2 | LINESTRING (2 2, 8 2, 8 8, 2 8, 2 2) | Y | LINESTRING (2 2, 2 8, 8 8, 8 2, 2 2) | N | LINESTRING (2 2, 2 8, 8 8, 8 2, 2 2) | N | + | N |
The visible behaviour of GEOS has not changed in 3.12. GEOS is still working as expected.
From #51750:
Sometimes, if the line is not fully visible on the canvas, there is no issue:
I can confirm that, when the duplicated node lies outside of the canvas, the offset works as expected. (does QGIS sends only part of the linestring to GEOS? Or is the resulting closed offset curve truncated before QGIS deletes the duplicated node?)
Given that one issue is already fixed upstrean and second has a separate ticket should we close this?
#55050 is being closed as a duplicate of this bug.
What is the bug or the crash?
On a Linestring dataset, I use a Simple Line symbology with a positive offset of 0.5 mm. When the dataset contains closed linestrings, on the closed linestrings the first and last segment are not displayed. See the attached project files (rename to .qgs):
test_3_10.qgs test_3_22.qgs
This bug appears only for positive offsets. I tested with millimeters and map units, same behaviour. I tested geographic (EPSG:4326) and projected (EPSG:2154) CRS, same behaviour. I tested various join style and cap style, same behaviour. I tested two file format versions for the QGIS project file, same behaviour.
Steps to reproduce the issue
Versions
I tested several versions.
Not affected versions: 3.10.10 (8b051b9a43, tested on Windows), 3.16.16 (f5778a89df, tested on Windows), 3.22.14 (Release 3.22, tested on Debian GNU/Linux 11 (bullseye))
Affected versions: 3.22.14 (4cde646c, tested on Windows), 3.28.2 (b47e00ba601, tested on Windows), and master (91886a22e, tested on Debian GNU/Linux sid)
Some of the About tables, by order of citation:
3.16.16 not affected
Version de QGIS | 3.16.16-Hannover | Révision du code | f5778a89df -- | -- | -- | -- Compilé avec Qt | 5.11.2 | Utilisant Qt | 5.11.2 Compilé avec GDAL/OGR | 3.1.4 | Utilisé avec GDAL/OGR | 3.1.4 Compilé avec GEOS | 3.8.1-CAPI-1.13.3 | Utilisé avec GEOS | 3.8.1-CAPI-1.13.3 Compilé avec SQLite | 3.29.0 | Fonctionne avec SQLite | 3.29.0 Version du client PostgreSQL | 11.5 | Version de SpatiaLite | 4.3.0 Version de QWT | 6.1.3 | Version de QScintilla2 | 2.10.8 Compilé avec PROJ | 6.3.2 | Fonctionne avec PROJ | Rel. 6.3.2, May 1st, 2020 Version de l'OS | Windows 10 (10.0) Extensions Python actives | processing3.22.14 not affected
QGIS version 3.22.14-Białowieża QGIS code branch Release 3.22 Qt version 5.15.2 Python version 3.9.2 GDAL/OGR version 3.2.2 PROJ version 7.2.1 EPSG Registry database version v10.008 (2020-12-16) GEOS version 3.9.0-CAPI-1.16.2 SQLite version 3.34.1 PostgreSQL client version 13.9 (Debian 13.9-0+deb11u1) SpatiaLite version 5.0.1 QWT version 6.1.4 QScintilla2 version 2.11.6 OS version Debian GNU/Linux 11 (bullseye)
Active Python plugins processing 2.12.99 grassprovider 2.12.99 sagaprovider 2.12.99
3.22.14 affected
Version de QGIS | 3.22.14-Białowieża | Révision du code | 4cde646c -- | -- | -- | -- Version de Qt | 5.15.3 Version de Python | 3.9.5 Compilé avec GDAL/OGR | 3.6.1 | Utilisé avec GDAL/OGR | 3.6.2 Version de Proj | 9.1.1 Version de la base de données du registre EPSG | v10.076 (2022-08-31) Version de GEOS | 3.11.1-CAPI-1.17.1 Version de SQLite | 3.39.4 Version de PDAL | 2.4.3 Version du client PostgreSQL | 14.3 Version de SpatiaLite | 5.0.1 Version de QWT | 6.1.6 Version de QScintilla2 | 2.13.1 Version de l'OS | Windows 10 Version 2009 | | | Extensions Python actives grassprovider | 2.12.99 processing | 2.12.99master affected
QGIS version 3.29.0-Master QGIS code revision 91886a22e Qt version 5.15.8 Python version 3.11.1 GDAL/OGR version 3.6.2 PROJ version 9.1.1 EPSG Registry database version v10.076 (2022-08-31) GEOS version 3.11.1-CAPI-1.17.1 SQLite version 3.40.1 PostgreSQL client version unknown SpatiaLite version 5.0.1 QWT version 6.1.4 QScintilla2 version 2.13.3 OS version Debian GNU/Linux bookworm/sid
This copy of QGIS writes debugging output.
Active Python plugins
Supported QGIS version
New profile
Additional context
The real dataset is a road graph with loops.
Github reports more than 5000 commits between the affected 3.22.14 master and the unaffected 3.22.14 release 3.22 . I don't have tools to handle such a large diff.
I do not know the QGIS source code well enough to localise what may cause this strange behaviour. I may be able to test your ideas, though.