You can use the shape function of Shapely:
from shapely.geometry import shape
c = fiona.open('data/boroughs/boroughs_n.shp')
pol = c.next()
geom = shape(pol['geometry'])
and a MultiPolygon is a list of Polygons,so
Multi = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('data/boroughs/boroughs_n.shp')])
Example with one of my data:
# the dictionaries
for pol in fiona.open('poly.shp'):
print pol['geometry']
{'type': 'Polygon', 'coordinates': [[(249744.23153029341, 142798.16434689672), (250113.79108725351, 142132.95714436853), (250062.62130244367, 141973.76225829343), (249607.77877080048, 141757.71205576291), (249367.77424759799, 142304.68402918623), (249367.77424759799, 142304.68402918623), (249744.23153029341, 142798.16434689672)]]}
{'type': 'Polygon', 'coordinates': [[(249175.78991730965, 142292.53526406409), (249367.77424759799, 142304.68402918623), (249607.77877080048, 141757.71205576291), (249014.45396077307, 141876.13484290778), (249175.78991730965, 142292.53526406409)]]}
{'type': 'Polygon', 'coordinates': [[(249026.74622412826, 142549.13626160321), (249223.42243781092, 142496.89414234375), (249175.78991730965, 142292.53526406409), (249026.74622412826, 142549.13626160321)]]}
...
and
# MultiPolygon from the list of Polygons
Multi = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('poly.shp')])
Multi.wkt
'MULTIPOLYGON (((249744.2315302934148349 142798.1643468967231456, 250113.7910872535139788 142132.9571443685272243, 250062.6213024436729029 141973.7622582934272941, 249607.7787708004761953 141757.7120557629095856, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249744.2315302934148349 142798.1643468967231456)), ((249175.7899173096520826 142292.5352640640921891, 249367.7742475979903247 142304.6840291862317827, 249607.7787708004761953 141757.7120557629095856, 249014.4539607730694115 141876.1348429077770561, 249175.7899173096520826 142292.5352640640921891)), ((249026.7462241282628383 142549.1362616032129154, 249223.4224378109211102 142496.8941423437499907, 249175.7899173096520826 142292.5352640640921891, 249026.7462241282628383 142549.1362616032129154)), ((249244.9338986824732274 142733.5202119307068642, 249744.2315302934148349 142798.1643468967231456, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249175.7899173096520826 142292.5352640640921891, 249223.4224378109211102 142496.8941423437499907, 249244.9338986824732274 142733.5202119307068642)), ((249870.8182051893090829 142570.3083320840960369, 250034.3015973484434653 142613.6706442178401630, 250152.6146321419219021 142438.5058914067049045, 250015.3392731740023009 142310.1704097116598859, 249870.8182051893090829 142570.3083320840960369)))'
see also Append support for MultiPolygons in shapefiles
Then I put every record in the rows of a pandas.DataFrame
Why ?
If you only want to copy the original attributes (LineString) to the new shapefile (Points), after computing the centroid, you don't need Pandas:
import fiona
from shapely.geometry import shape, mapping
with fiona.open("polyline.shp") as input:
# change only the geometry of the schema: LineString -> Point
input.schema['geometry'] = "Point"
# write the Point shapefile
with fiona.open('centroid.shp', 'w', 'ESRI Shapefile', input.schema.copy(), input.crs) as output:
for elem in input:
# GeoJSON to shapely geometry
geom = shape(elem['geometry'])
# shapely centroid to GeoJSON
elem['geometry'] = mapping(geom.centroid)
output.write(elem)
If you absolutely want to use Pandas, use GeoPandas which "mix" Pandas, Fiona and shapely.
import geopandas as gp
input = gp.read_file('polyline.shp')
print type(input)
<class 'geopandas.geodataframe.GeoDataFrame'> -> a GeoDataFrame
print input['geometry']
0 LINESTRING (266351.05107 161433.039507, 266362...
....
# only change the geometry of the dataframe
input['geometry'] = input['geometry'].centroid
print input['geometry']
0 POINT (266369.1881962401 161457.6017265563)
....
# save resulting shapefile
input.to_file("centroids.shp")
Best Answer
I don't really understand your problem. Some explanations: for example, we want to
modify the original schema: for that, it's easier to just copy things to a new shapefile and make the changes as you copy
1) Open the original shapefile:
2) As it is a dictionary, it is easy to add new fields/keys in the properties:
3) Now we create a new shapefile copying myshp.shp with the new schema :
If you don't want to modify the shapefile, it is easier with schema.copy() that is only used to get a copy of the original schema (no definition here)