Chciałbym zbudować plik kształtu z ramki danych Pandas przy użyciu wierszy lon i lat.
Mam plik csv i przetwarzam go za pomocą pand, aby utworzyć ramkę danych, która jest łatwiejsza w obsłudze
Czy można to zrobić bez tworzenia pętli linia po linii?
Chciałbym zbudować plik kształtu z ramki danych Pandas przy użyciu wierszy lon i lat.
Mam plik csv i przetwarzam go za pomocą pand, aby utworzyć ramkę danych, która jest łatwiejsza w obsłudze
Czy można to zrobić bez tworzenia pętli linia po linii?
Odpowiedzi:
Trochę spóźniony, ale może też przydatny dla innych. Tak, można to zrobić za pomocą shapely
i geopandas
.
Załóżmy, że twoja ramka danych pand wygląda tak:
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
Po pierwsze, upewnij się, że geopandas
i shapely
są poprawnie zainstalowane, co czasem nie jest łatwe, ponieważ mają pewne zależności (np. GEOS i GDAL). Jeśli nie działa za pierwszym razem, spróbuj pip install geopandas shapely
wyszukać błąd w Google lub StackOverflow / Gis.Stackexchange, ponieważ najprawdopodobniej będzie dostępna odpowiedź rozwiązująca ten problem.
Następnie wystarczy utworzyć nową kolumnę geometrii w ramce danych, która łączy wartości lat i lon w shapely Point()
obiekt. Zauważ, że Point()
konstruktor oczekuje krotności wartości zmiennoprzecinkowych, więc konwersja musi zostać uwzględniona, jeśli typy kolumn kolumny ramki danych nie są jeszcze ustawione na 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)
Teraz przekonwertuj pandy DataFrame na GeoDataFrame
. Konstruktor geopandas oczekuje kolumny geometrii, która może składać się z kształtnych obiektów geometrii, więc stworzona przez nas kolumna jest w porządku:
import geopandas
df = geopandas.GeoDataFrame(df, geometry='geometry')
Aby zrzucić ten GeoDataFrame do pliku kształtu, użyj to_file()
metody geopandas (inne sterowniki obsługiwane przez Fiona, takie jak GeoJSON
powinny również działać):
df.to_file('MyGeometries.shp', driver='ESRI Shapefile')
I tak wygląda wynikowy plik kształtu, gdy jest wizualizowany za pomocą QGIS :
W przypadku ArcMap musisz zdefiniować Projekcję przed eksportowaniem do Shapefile.
import geopandas
df = geopandas.GeoDataFrame(df, geometry='geometry')
# proj WGS84
df.crs= "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
df.to_file('MyGeometries.shp', driver='ESRI Shapefile')
df.crs= "+init=epsg:27700"
z projektu mojego pliku kształtu zgodnie z British National Grid. Jednak po otwarciu go w ArcGIS układ współrzędnych jest nieznany. Co ja robię źle?