Estoy intentando hacer una unión espacial como en el ejemplo aquí: ¿Hay una opción de python para "unir atributos por ubicación"? . Sin embargo, ese enfoque parece realmente ineficiente / lento. Incluso ejecutar esto con unos modestos 250 puntos lleva casi 2 minutos y falla completamente en archivos de forma con> 1,000 puntos. ¿Hay un mejor enfoque? Me gustaría hacer esto completamente en Python sin usar ArcGIS, QGIS, etc.
También me interesaría saber si es posible SUMAR atributos (es decir, población) de todos los puntos que se encuentran dentro de un polígono y unir esa cantidad al archivo de forma del polígono.
Aquí está el código que estoy tratando de convertir. Me sale un error en la línea 9:
poly['properties']['score'] += point['properties']['score']
que dice:
TypeError: tipos de operando no admitidos para + =: 'NoneType' y 'float'.
Si reemplazo el "+ =" con "=" funciona bien pero eso no suma los campos. También intenté hacerlos como enteros, pero eso también falla.
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']})
fuente
Respuestas:
Fiona devuelve los diccionarios de Python y no se puede usar
poly['properties']['score']) += point['properties']['score'])
con un diccionario.Ejemplo de suma de atributos usando las referencias dadas por Mike T:
Ahora, podemos usar dos métodos, con o sin un índice espacial:
1) sin
2) con un índice R-tree (puede usar pyrtree o rtree )
Resultado con las dos soluciones:
Cuál es la diferencia ?
Después:
Para ir más lejos, mira Uso de la indexación espacial Rtree con OGR, Shapely, Fiona
fuente
Además, las geopandas ahora se incluyen opcionalmente
rtree
como una dependencia, consulte el repositorio de GithubEntonces, en lugar de seguir todo el código (muy bueno) anterior, simplemente podría hacer algo como:
Para obtener esta funcionalidad elegante, asegúrese de instalar primero la biblioteca C libspatialindex
EDITAR: importaciones de paquetes corregidos
fuente
rtree
era opcional. ¿No significa eso que necesita instalarrtree
tan bien como lalibspatialindex
biblioteca C?rtree
cuando había instalado primerolibspatialindex
... que han hecho una versión bastante importante ya que por lo que estoy seguro que las cosas han cambiado un pocoUse Rtree como índice para realizar las uniones mucho más rápidas, luego Shapely para hacer los predicados espaciales para determinar si un punto está realmente dentro de un polígono. Si se hace correctamente, esto puede ser más rápido que la mayoría de los otros SIG.
Ver ejemplos aquí o aquí .
La segunda parte de su pregunta sobre 'SUMA', use un
dict
objeto para acumular poblaciones usando una identificación de polígono como clave. Aunque, este tipo de cosas se hace mucho mejor con PostGIS.fuente
Esta página web muestra cómo usar una búsqueda de punto en el polígono de Bounding Box antes de la consulta espacial Dentro más costosa de Shapely.
http://rexdouglass.com/fast-spatial-joins-in-python-with-a-spatial-index/
fuente