Shapely deals with geometric objects, not features or collections of features. See the manual on shape().
Your code (with JSON) could be:
import json
from shapely.geometry import shape
f = open('wijken.json', 'r')
js = json.load(f)
f.close()
for f in js['features']:
s = shape(f['geometry'])
...
A MultiLineString is a list of lines:
from shapely.geometry import MultiLineString, mapping, shape
coords = [((0, 0), (1, 1)), ((-1, 0), (1, 0))]
lines = MultiLineString(coords)
print lines
MULTILINESTRING ((0 0, 1 1), (-1 0, 1 0))
for line in lines:
print line
LINESTRING (0 0, 1 1)
LINESTRING (-1 0, 1 0)
# convert to GeoJSON format:
print mapping(lines)
{'type': 'MultiLineString', 'coordinates': (((0.0, 0.0), (1.0, 1.0)), ((-1.0, 0.0), (1.0, 0.0)))}
# convert from GeoJSON to shapely
print shape(mapping(lines))
MULTILINESTRING ((0 0, 1 1), (-1 0, 1 0))
It is the same when you read a shapefile with Fiona:
import fiona
from shapely.geometry import shape
with fiona.open(path_to_road_network_shapefile) as copy_shpfile:
for feature in copy_shpfile:
geom = feature['geometry'])
# geom in GeoJSON format -> {'type': 'MultiLineString', 'coordinates': (((0.0, 0.0), (1.0, 1.0)), ((-1.0, 0.0), (1.0, 0.0)))}
if geom['type'] == 'MultiLineString':
# convert to shapely geometry
shapely_geom = shape(geom) # = MULTILINESTRING ((0 0, 1 1), (-1 0, 1 0))
for lines in shapely_geom:
print lines
New
A shapefile has no MultiLineString schema geometries: a shapefile that indicates LineString in its schema may yield either LineString or MultiLineString features (simple list of LineStrings)
However, it is the same algorithm:
# open the original shapefile
with fiona.open('multiline.shp') as source:
# create the new shapefile
with fiona.open('lines.shp','w', driver='ESRI Shapefile',crs=source.crs,schema=source.schema) as ouput:
# iterate the features of the original shapefile
for elem in source:
# iterate the list of geometries in one element (split the MultiLineString)
for line in shape(elem['geometry']):
# write the line to the new shapefile
ouput.write({'geometry':mapping(line),'properties':elem['properties']})
Best Answer
Dumping a list of features directly does not create a valid GeoJSON file.
To create valid GeoJSON:
e.g.
Output: