I have files with line segments that cover road network of towns. The issue is that each street with specific name consists of smaller segments that I need to merge into one line covering the whole street.
What I tried in the code below is to read a shapefile, create dictionaries where under a streetId are all of the street's segments and then merge it using ops.linemerge. The problem I have is when saving to the file in the following line
w.line(merged_line)
The error shown is
w.line(merged_line)
File "C:\OSGeo4W64\apps\Python37\lib\site-packages\shapefile.py", line 1977, in line
self._shapeparts(parts=lines, shapeType=shapeType)
File "C:\OSGeo4W64\apps\Python37\lib\site-packages\shapefile.py", line 2062, in _shapeparts
for part in parts:
TypeError: 'LineString' object is not iterable
What object should I provide to the writer's line method? Is there any better way to merge the segments into streets?
import shapefile as shp
from shapely import geometry, ops
from shapely.geometry import shape
sf = shp.Reader("shapefiles/town1")
streetShapeDictionary = {}
streetSegmentDictionary = {}
shapes = sf.shapes()
records = sf.records()
fields = sf.fields
recordIndex = 0;
for record in records:
streetId = record[0]
feature = sf.shapeRecords()[recordIndex].shape.__geo_interface__
linestringShape = shape(feature)
if streetId in streetSegmentDictionary:#add street segment to the list
streetSegmentDictionary[streetId].append(record)
streetShapeDictionary[streetId].append(linestringShape)
else:#add new key to the street dictionary
streetSegmentDictionary[streetId] = [record]
streetShapeDictionary[streetId] = [linestringShape]
recordIndex = recordIndex + 1
w = shp.Writer('shapefiles/whole_streets')
w.field('name', 'C')
streetShapesArray = []
for street in streetSegmentDictionary:
for shape in streetShapeDictionary[street]:
streetShapesArray.append(shape)
multiline = geometry.MultiLineString([*streetShapesArray])
merged_line = ops.linemerge(multiline)
w.line(merged_line)
w.record('streetName1')
streetShapesArray = []
w.close()
merged_line
is a Shapely geometry that you cannot use directly with Pyshp. Usew.line(list(merged_line.coords)list(merged_line.coords))
line = LineString([(0, 0), (1, 1)])
->list(line.coords)
->[(0.0, 0.0), (1.0, 1.0)]