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 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.