libgeos / geos

Geometry Engine, Open Source
https://libgeos.org
GNU Lesser General Public License v2.1
1.1k stars 339 forks source link

Union doesn't merge linestrings... #1063

Open theroggy opened 2 months ago

theroggy commented 2 months ago

Is there a particular reason that the union operation doesn't merge multiple linestrings that are touching to a single linestring, but that you need to use linemerge for that?

Sample:

from shapely import LineString, MultiLineString, line_merge, union_all

geoms = [
    LineString([ (355041.15, 6688781.25, 0), (355040.9629213488, 6688781.437078651, 9.7) ]),
    LineString([ (355041.15, 6688781.25, 0), (354841.1500000001, 6688781.25, 0) ])
]

line_merge_result = line_merge(MultiLineString(geoms))
print(line_merge_result)
# LINESTRING Z (354841.1500000001 6688781.25 0, 355041.15 6688781.25 0, 355040.9629213488 6688781.437078651 9.7)

union_all_result = union_all(geoms)
print(union_all_result)
# MULTILINESTRING Z ((355041.15 6688781.25 0, 355040.9629213488 6688781.437078651 9.7), (355041.15 6688781.25 0, 354841.1500000001 6688781.25 0))
dr-jts commented 1 month ago

Yes. It's because merging loses information, and takes slightly more time. So the design decision was to leave the results unmerged, and use a separate call to merge them if required.

theroggy commented 1 month ago

Yes. It's because merging loses information, and takes slightly more time. So the design decision was to leave the results unmerged, and use a separate call to merge them if required.

It is a bit counter-intuitive because for polygons union is the function to remove "redundant" lines between polygons... which also loses information... versus for lines union just collects all input to a MultiLineString...?

dr-jts commented 1 month ago

union on LineStrings does more than just collect them. It nodes lines that cross, and eliminates duplicate sections of linework.