Немного поздно, но, возможно, также полезно для других. Да, это можно сделать с помощью shapely
и geopandas
.
Предполагается, что ваш фрейм данных выглядит так:
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
Во-первых, убедитесь, что geopandas
и shapely
установлены правильно, что иногда непросто, потому что они имеют некоторые зависимости (например, GEOS и GDAL). Если сначала не получается, попробуйте pip install geopandas shapely
выполнить поиск через Google или StackOverflow / Gis.Stackexchange, потому что, скорее всего, найдется ответ, который решит эту проблему за вас.
Затем, это просто вопрос создания нового столбца геометрии в вашем фрейме данных, который объединяет значения lat и lon в shapely Point()
объект. Обратите внимание, что Point()
конструктор ожидает кортеж значений с плавающей запятой, поэтому преобразование должно быть включено, если dtypes столбца элемента данных еще не установлены в 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)
Теперь преобразуйте DataFrame для панд в GeoDataFrame
. Конструктор Geopandas ожидает геометрический столбец, который может состоять из объектов геометрической формы, поэтому созданный нами столбец просто отлично:
import geopandas
df = geopandas.GeoDataFrame(df, geometry='geometry')
Чтобы выгрузить этот GeoDataFrame в шейп-файл, используйте to_file()
метод геопандаса (другие драйверы, поддерживаемые Fiona, например, также GeoJSON
должны работать):
df.to_file('MyGeometries.shp', driver='ESRI Shapefile')
Вот как выглядит получившийся шейп-файл при визуализации с помощью QGIS :