Próbuję wykonać sprzężenie przestrzenne podobnie jak tutaj: Czy istnieje opcja Pythona do „łączenia atrybutów według lokalizacji”? . Jednak takie podejście wydaje się naprawdę nieefektywne / powolne. Nawet uruchomienie tego ze skromnymi 250 punktami zajmuje prawie 2 minuty i kończy się niepowodzeniem na plikach kształtu z> 1000 punktów. Czy istnieje lepsze podejście? Chciałbym to zrobić całkowicie w Pythonie bez użycia ArcGIS, QGIS itp.
Chciałbym również wiedzieć, czy możliwe jest SUMOWANIE atrybutów (tj. Populacji) wszystkich punktów, które mieszczą się w wielokącie i łączenie tej ilości z kształtem wielokąta.
Oto kod, który próbuję przekonwertować. W linii 9 pojawia się błąd:
poly['properties']['score'] += point['properties']['score']
który mówi:
TypeError: nieobsługiwane typy operandów dla + =: „NoneType” i „float”.
Jeśli zamieniam „+ =” na „=”, działa dobrze, ale to nie sumuje pól. Próbowałem też tworzyć je jako liczby całkowite, ale to też się nie udaje.
with fiona.open(poly_shp, 'r') as n:
with fiona.open(point_shp,'r') as s:
outSchema = {'geometry': 'Polygon','properties':{'region':'str','score':'float'}}
with fiona.open (out_shp, 'w', 'ESRI Shapefile', outSchema, crs) as output:
for point in s:
for poly in n:
if shape(point['geometry']).within(shape(poly['geometry'])):
poly['properties']['score']) += point['properties']['score'])
output.write({
'properties':{
'region':poly['properties']['NAME'],
'score':poly['properties']['score']},
'geometry':poly['geometry']})
źródło
Odpowiedzi:
Fiona zwraca słowniki w języku Python i nie można ich używać
poly['properties']['score']) += point['properties']['score'])
ze słownikiem.Przykład sumowania atrybutów z wykorzystaniem odniesień podanych przez Mike'a T:
Teraz możemy użyć dwóch metod, z indeksem przestrzennym lub bez:
1) bez
2) z indeksem R-drzewa (możesz użyć Pyrtree lub rtree )
Wynik z dwoma rozwiązaniami:
Jaka jest różnica ?
Po:
Aby pójść dalej, spójrz na Korzystanie z indeksowania przestrzennego Rtree z OGR, Shapely, Fiona
źródło
Dodatkowo - geopandas teraz opcjonalnie obejmuje
rtree
jako zależność, zobacz repozytorium githubZamiast więc postępować zgodnie z powyższym (bardzo ładnym) kodem, możesz po prostu zrobić coś takiego:
Aby uzyskać tę funkcjonalność snazzy należy zainstalować C-biblioteka libspatialindex pierwszy
EDYCJA: poprawiono import pakietów
źródło
rtree
był opcjonalny. Czy to nie znaczy, że musisz zainstalowaćrtree
tak dobrze, jaklibspatialindex
bibliotekę C.rtree
kiedy pierwszy raz zainstalowałemlibspatialindex
... zrobili dość duże wydanie, więc jestem pewien, że wszystko się nieco zmieniłoUżyj Rtree jako indeksu, aby wykonać znacznie szybsze połączenia, a następnie Shapely, aby wykonać predykaty przestrzenne, aby ustalić, czy punkt znajduje się w obrębie wielokąta. Prawidłowo wykonane może być szybsze niż większość innych systemów GIS.
Zobacz przykłady tutaj lub tutaj .
W drugiej części pytania dotyczącego „SUM” użyj
dict
obiektu do gromadzenia populacji, używając klucza wielokąta jako klucza. Chociaż tego typu rzeczy są znacznie ładniejsze w PostGIS.źródło
Ta strona pokazuje, jak korzystać z wyszukiwania punkt-w-wielokącie Bounding Box przed droższym zapytaniem przestrzennym Shapely.
http://rexdouglass.com/fast-spatial-joins-in-python-with-a-spatial-index/
źródło