Cómo crear un shapefile de punto / línea / polígono con Python y Fiona - Tutorial

frame1200x900xdiag.png

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.

 

Suscríbete a nuestro boletín electrónico

Suscríbase a nuestro boletín gratuito para recibir noticias, datos interesantes y fechas de nuestros cursos en recursos hídricos.

 

Posted on June 21, 2021 and filed under TutorialPython, TutorialQGIS, Tutorial.