Más

La forma más rápida de unir muchos puntos a muchos polígonos en Python

La forma más rápida de unir muchos puntos a muchos polígonos en Python


Necesito atribuir un área geográfica (basada en polígonos de shapefile) a 8 millones de puntos GPS. Hay 405 polígonos. Actualmente tengo el código a continuación, y una extrapolación rápida me dice que tomará 84 horas calcularlo.

Soy nuevo en SIG, pero intuitivamente, siento que tiene que haber una forma más inteligente de evitar esto que, para cada punto, probar aleatoriamente cada polígono con una función de punto en polígono hasta que haya una coincidencia. Por ejemplo, simplemente colocando los puntos y polígonos en 2 grupos (como "Este" y "Oeste") simplemente basándose en su longitud más oriental / más occidental puede dividir por dos el número de operaciones a realizar por casi 2.

¿Existen realmente algoritmos tan eficientes? ¿Alguno de ellos se puede implementar fácilmente en Python?

de shapely.geometry importar forma, Point, Polygon importar pandas como pd de mpl_toolkits.basemap import importar mapa base matplotlib.pyplot como plt de matplotlib.colors importar LinearSegmentedColormap plt.figure (figsize = (16,16)) m = mapa base (proyección = 'merc', llcrnrlat = 15, urcrnrlat = 55, llcrnrlon = 70, urcrnrlon = 140, lat_ts = 20, resolution = 'c') m.readshapefile (china_shapefile, 'prefectures', drawbounds = True) print len ​​(m.prefectures ) #get data china_shapefile = "C: / Users /… / CHN_adm2_SIMPLIFIED / CHN_adm2" points_csv = "C: / Users /… /sample_map_data.csv" points = pd.read_csv (points_csv) points = points.dropna () lat = points ["Latitud"]. Tolist () lon = puntos ["Longitud"]. Tolist () coordenadas = zip (lat, lon) para coordenadas en coordenadas: para información, forma en zip (m.prefectures_info, m.prefectures): poly = Polygon (shape) #print info ["NAME_1"], info ["NAME_2"] xpt, ypt = m (coordenada [1], coordenada [0]) punto1 = Punto (xpt, ypt) if point1.within ( poli): imprimir coordenadas, información ["NAME_1"], información ["NAME_2"] #, información ["NAME_3"] descanso

Como dice blord-castillo, puedes usar un índice espacial. Hay muchos módulos en Python para eso (PiPy: índice espacial, R-tree, Quad-Ttree, Kd-tree, Interval-tree,…).

El método más utilizado para indexar datos espaciales es el índice de árbol R (también utilizado por QGIS o PyQGIS según lo establecido por GeoJohn, ver geoprocesamiento en múltiples capas vectoriales QGIS2 por ejemplo)

El más rápido es Rtree (rtree python polygon index) porque es un contenedor Python simple de la biblioteca C libspatialindex. Se utiliza en uniones espaciales más eficientes en Python sin QGIS, ArcGIS, PostGIS, etc., por ejemplo (con Fiona, Shapely y Rtree).

En lugar de usar Pandas, debe usar GeoPandas que incluye opcionalmente rtree como una dependencia (uniones espaciales, índices espaciales para marcos de datos geográficos y series o uniones espaciales más eficientes en Python sin QGIS, ArcGIS, PostGIS, etc. con GeoPandas)

Esta referencia le brinda 2 soluciones para su problema (unión espacial entre puntos y polígonos) con las limitaciones del procedimiento:

  • Sin un índice, debe recorrer todas las geometrías (polígonos y puntos).
  • Con un índice espacial delimitador (Spatial Index RTree), itera solo a través de las geometrías que tienen la posibilidad de cruzarse con su geometría actual ('filtro' que puede ahorrar una cantidad considerable de cálculos y tiempo ...)
  • Pero un índice espacial no es una varita mágica. Cuando se debe recuperar una gran parte del conjunto de datos, un índice espacial no puede ofrecer ningún beneficio de velocidad.

Ver el vídeo: BODY SHIELD PRO - Καθαριστικό σετ αυτοκινήτου