Подсчет точек в перекрывающихся полигонах с помощью GeoPandas

avatar
Vlad
8 августа 2021 в 17:27
191
0
1

Я преобразовал точечную сетку Большого Лондона размером 200 м x 200 м в мультиполигональный буферный слой радиусом 500 м для каждой точки сетки. Это означает, что у меня более 100 000 перекрывающихся полигонов.

У меня также есть данные о преступлениях за годы в виде точечного слоя с долготой (более 1,1 миллиона преступлений x 12 столбцов данных)

Я пытаюсь найти наиболее эффективный способ подсчета количества точек преступлений в каждом полигональном буфере. Поскольку полигональные буферы перекрываются, точки преступлений также будут перекрываться для всех буферов.

Похоже, что пространственное соединение в геопандах не работает, может быть, из-за того, что полигоны перекрываются? Если я использую «внутреннее» соединение, я просто получаю пустой фрейм данных. Если я использую «левое» соединение, я просто получаю все строки преступлений (1,1 миллиона) со столбцами полигонов буфера справа, все как «нан». И наоборот, если я использую "правильное" соединение - только строки буфера (100 000) со столбцами преступления как nan. См. код ниже:

import pandas as pd
import geopandas as gpd
from geopandas import read_file
from pandas import read_csv
from geopandas import GeoDataFrame, points_from_xy

#import buffer polygon layer
gBuffer = read_file('London Buffer.zip')
df1 = gBuffer.head()

#import crime csv
crime = read_csv('2020-2021 London Crime.csv')

#drop nan rows from coords
crime2 = crime[crime['Longitude'].notna()]
df2 = crime2.head()

#geocode crime points
gCrime = GeoDataFrame(crime2, geometry=points_from_xy(crime2['Longitude'], crime2['Latitude']))
df3 = gCrime.head()

#set equal crs
gCrime.crs = gBuffer.crs

#spatial join data
BufferCrime = gpd.sjoin(gCrime, gBuffer, how="inner")


Другое решение состоит в том, чтобы выполнить итерацию по каждому полигону и подсчитать количество точек, но это займет вечность, учитывая, что необходимо выполнить 100 000 x 1 100 000 итераций

# Loop over polygons with index i.
for i, poly in gBuffer.iterrows():

    #list of points in this poly
    pts_in_this_poly = []

    #loop over all points 
    for j, pt in gCrime.iterrows():
        if poly.geometry.contains(pt.geometry):
            # Add it to the list
            pts_in_this_poly.append(pt.geometry)
    
    pts_in_polys.append(len(pts_in_this_poly))
    
#Add the points
gBuffer['number of Crime points'] = gpd.GeoSeries(pts_in_polys)  

Есть идеи, как лучше всего решить эту проблему?

Источник
Babak Fi Foo
18 августа 2021 в 07:25
0

Вы можете найти ответ на странице обмена стеками ГИС. Я там ответил.

Ответы (0)