Un poco tarde pero quizás también útil para otros. Sí, eso se puede hacer con shapely
y geopandas
.
Supongamos que su marco de datos de pandas se ve así:
import pandas as pd
data = [
{'some_attribute': 'abc', 'lat': '50.1234', 'lon': '10.4023'},
{'some_attribute': 'def', 'lat': '40.5678', 'lon': '8.3365'},
{'some_attribute': 'ghi', 'lat': '60.9012', 'lon': '6.2541'},
{'some_attribute': 'jkl', 'lat': '45.3456', 'lon': '12.5478'},
{'some_attribute': 'mno', 'lat': '35.7890', 'lon': '14.3957'},
]
df = pd.DataFrame(data)
print(df)
=>
lat lon some_attribute
0 50.1234 10.4023 abc
1 40.5678 8.3365 def
2 60.9012 6.2541 ghi
3 45.3456 12.5478 jkl
4 35.7890 14.3957 mno
En primer lugar, asegúrese de que geopandas
y shapely
se ha instalado correctamente, que a veces no es fácil, ya que vienen con algunas dependencias (por ejemplo, GEOS y GDAL). Si no funciona en el primer intento pip install geopandas shapely
, busque el error en Google o StackOverflow / Gis.Stackexchange porque lo más probable es que haya una respuesta disponible para resolver ese problema.
Entonces, solo es cuestión de crear una nueva columna de geometría en su marco de datos que combine los valores lat y lon en un shapely Point()
objeto. Tenga en cuenta que el Point()
constructor espera una tupla de valores flotantes, por lo que la conversión debe incluirse si los tipos de columna del marco de datos todavía no están establecidos float
.
from shapely.geometry import Point
# combine lat and lon column to a shapely Point() object
df['geometry'] = df.apply(lambda x: Point((float(x.lon), float(x.lat))), axis=1)
Ahora, convierta el DataFrame de pandas en a GeoDataFrame
. El constructor de geopandas espera una columna de geometría que puede consistir en objetos de geometría bien formados, por lo que la columna que creamos está bien:
import geopandas
df = geopandas.GeoDataFrame(df, geometry='geometry')
Para volcar este GeoDataFrame en un shapefile, use el to_file()
método de geopandas (otros controladores compatibles con Fiona como GeoJSON
también deberían funcionar):
df.to_file('MyGeometries.shp', driver='ESRI Shapefile')
Y así es como se ve el archivo shape resultante cuando se visualiza con QGIS :