I am developing an ArcGIS Pro 3.1.0 toolbox (atbx) and one of the tools I'm creating is selecting a set of polylines (which are river centrelines) and merging them into a single long polyline. Research has pointed me to the shapely unary_union() function as an efficient method for merging the lines into a single polyline. I installed shapely using pip and can confirm that I have shapely '2.0.1' installed and when I import shapely.geos
the version returned for that is '3.11.1-CAPI-1.17.1'
My input data is a UK river network with some polylines selected, so data is in a file geodatabase and the Feature Class is British National Grid, I show a small example below:
I have developed the following code to do the merge:
import shapely
import arcpy
xyresolution = 0.0001 # XY Resolution of Feature CLass
# Read selected polyline geometries into list
lp = list()
with arcpy.da.SearchCursor("Rivers","SHAPE@") as cursor:
for row in cursor:
geom = row[0]
lp.append(geom)
# Convert arcpy geometry into shapely geometry
ls = list()
for geom in lp:
ls.append(shapely.set_precision(shapely.wkb.loads(bytes(geom.WKB)), xyresolution))
# Union lines
aLineString = shapely.unary_union(geometries=ls)
# convert line back into arcpy geometry
newpolyline = arcpy.FromWKB(aLineString.wkb)
# Write out to temporary Feature Class
sr = arcpy.SpatialReference(27700) # BNG
with arcpy.EnvManager(outputCoordinateSystem=sr, addOutputsToMap=True):
arcpy.CopyFeatures_management([newpolyline], r"C:\Scratch\fGDB_Scratch.gdb\fcUnionline")
My initial outputs all came out as MULTILINESTRING which is not what I wanted, I wanted a single linestring so I could convert back into an arcpy polyline. More research hinted towards it being a precision issue hence me using the shapely.set_precision() function in the above code.
But even with that addition when I check the output loaded back into ArcGIS Pro, its clearly multi-part and not in sequence.
If I go down the route of repeating the use of the Union() method of the arcpy polyline on a set of selected river centrelines, it is slow compared to the shapely.unary_union() but the end result is a single polyline, not multipart, flowing in a source to sea direction, just what I wanted.
How do I correctly use the unary_union() function?
It seems to me that it merges the lines into a single line but keeping them as separate parts. I understood the unary_union() would combine them into a single line. For the record I have tried a range of precision values from 10 to 0.00001 and the output is exactly the same.