El almacenamiento, la gestión y el análisis de datos vectoriales geoespaciales en shapefiles ESRI es un procedimiento común de los profesionales SIG y relacionados. La generación de estos archivos espaciales se puede realizar no solo en un software de escritorio sino también mediante comandos de Python. Hemos creado un ejemplo aplicado que muestra el procedimiento en Python para crear shapefiles de puntos, líneas y polígonos a partir de un archivo csv mediante el uso de la biblioteca Fiona.
Se recomienda tener los paquetes geoespaciales en un Environment de Conda. Conozca el procedimiento en este enlace.
Tutorial
Código
#import requires packages
import fiona
import pandas as pd
Create point shapefile
#import points from csv file
pointDf = pd.read_csv('../Txt//cropPoints.csv',header=0)
pointDf.head()
X | Y | Name | |
---|---|---|---|
0 | -84.200969 | 9.480966 | Plant1 |
1 | -84.200841 | 9.480931 | Plant2 |
2 | -84.201841 | 9.481167 | Plant3 |
3 | -84.200862 | 9.479898 | Plant4 |
4 | -84.200657 | 9.479586 | Plant5 |
# define schema
schema = {
'geometry':'Point',
'properties':[('Name','str')]
}
# explore available drivers
fiona.supported_drivers
{'AeronavFAA': 'r',
'ARCGEN': 'r',
'BNA': 'rw',
'DXF': 'rw',
'CSV': 'raw',
'OpenFileGDB': 'r',
'ESRIJSON': 'r',
'ESRI Shapefile': 'raw',
'FlatGeobuf': 'rw',
'GeoJSON': 'raw',
'GeoJSONSeq': 'rw',
'GPKG': 'raw',
'GML': 'rw',
'OGR_GMT': 'rw',
'GPX': 'rw',
'GPSTrackMaker': 'rw',
'Idrisi': 'r',
'MapInfo File': 'raw',
'DGN': 'raw',
'PCIDSK': 'rw',
'OGR_PDS': 'r',
'S57': 'r',
'SEGY': 'r',
'SQLite': 'raw',
'SUA': 'r',
'TopoJSON': 'r'}
#structure of fiona object
fiona.open( fp, mode='r', driver=None, schema=None, crs=None, encoding=None, layer=None, vfs=None, enabled_drivers=None, crs_wkt=None, **kwargs, )
#open a fiona object
pointShp = fiona.open('../ShapeOut/cropPoints.shp', mode='w', driver='ESRI Shapefile',
schema = schema, crs = "EPSG:4326")
#iterate over each row in the dataframe and save record
for index, row in pointDf.iterrows():
rowDict = {
'geometry' : {'type':'Point',
'coordinates': (row.X,row.Y)},
'properties': {'Name' : row.Name},
}
pointShp.write(rowDict)
#close fiona object
pointShp.close()
Create line shapefile
#import line vertex from csv file
lineDf = pd.read_csv('../Txt/cropLine.csv',header=0)
lineDf.head()
X | Y | Name | |
---|---|---|---|
0 | -84.201990 | 9.480380 | Row1 |
1 | -84.201928 | 9.480319 | Row1 |
2 | -84.201871 | 9.480261 | Row1 |
3 | -84.201820 | 9.480199 | Row1 |
4 | -84.201756 | 9.480133 | Row1 |
# define schema
schema = {
'geometry':'LineString',
'properties':[('Name','str')]
}
#open a fiona object
lineShp = fiona.open('../ShapeOut/cropLine.shp', mode='w', driver='ESRI Shapefile',
schema = schema, crs = "EPSG:4326")
#get list of points
xyList = []
rowName = ''
for index, row in lineDf.iterrows():
xyList.append((row.X,row.Y))
rowName = row.Name
xyList[:5]
[(-84.2019904893069, 9.48038022019686),
(-84.2019279965972, 9.48031926246447),
(-84.2018711206848, 9.48026145133191),
(-84.2018196550243, 9.48019910289781),
(-84.2017559092017, 9.48013268586072)]
#save record and close shapefile
rowDict = {
'geometry' : {'type':'LineString',
'coordinates': xyList},
'properties': {'Name' : rowName},
}
lineShp.write(rowDict)
#close fiona object
lineShp.close()
Create polygon shapefile
#import line vertex from csv file
polyDf = pd.read_csv('../Txt/cropPoly.csv',header=0)
polyDf.head()
X | Y | Name | |
---|---|---|---|
0 | -84.202396 | 9.480334 | Border1 |
1 | -84.202190 | 9.480555 | Border1 |
2 | -84.201886 | 9.480792 | Border1 |
3 | -84.201529 | 9.481153 | Border1 |
4 | -84.201307 | 9.481303 | Border1 |
#show the last item
polyDf.tail()
X | Y | Name | |
---|---|---|---|
19 | -84.201742 | 9.479385 | Border1 |
20 | -84.201863 | 9.479413 | Border1 |
21 | -84.202157 | 9.479673 | Border1 |
22 | -84.202398 | 9.479917 | Border1 |
23 | -84.202396 | 9.480334 | Border1 |
# define schema
schema = {
'geometry':'Polygon',
'properties':[('Name','str')]
}
#open a fiona object
polyShp = fiona.open('../ShapeOut/cropPoly.shp', mode='w', driver='ESRI Shapefile',
schema = schema, crs = "EPSG:4326")
#get list of points
xyList = []
rowName = ''
for index, row in polyDf.iterrows():
xyList.append((row.X,row.Y))
rowName = row.Name
xyList[:5]
[(-84.20239642444, 9.48033431305493),
(-84.2021899231741, 9.48055508704213),
(-84.2018864783201, 9.48079161161365),
(-84.2015288437831, 9.48115260231102),
(-84.2013071850694, 9.4813034753504)]
#save record and close shapefile
rowDict = {
'geometry' : {'type':'Polygon',
'coordinates': [xyList]}, #Here the xyList is in brackets
'properties': {'Name' : rowName},
}
polyShp.write(rowDict)
#close fiona object
polyShp.close()
Datos de entrada
Puede descargar los datos de entrada desde este enlace.