¿Existe una opción de python para "unir atributos por ubicación"?

9

Estoy tratando de realizar la función join attributes by locationque se encuentra en el menú QGIS Vector> Herramientas de administración de datos. Estoy buscando una opción de python de código abierto para esto. Sé que arcpy tiene una spatial joinfunción, pero estoy tratando de realizar esto fuera del entorno ESRI.

mal
fuente
1
Sugeriría mirar el código fuente del Join attributes by locationcomando real desde el fToolscomplemento: doSpatialJoin.pyparticularmente el compute()método. No debería ser demasiado difícil eliminar ningún código de interfaz de usuario de eso y despojarlo a una función de python simple.
Lukas Graf
Hola, tengo un problema un poco diferente, ¡quiero comprobar si hay una unión entre dos capas! Estoy buscando una opción de código abierto de Python para esto. Quiero probar si se ha utilizado la función s.join y estoy intentando realizar esto fuera del entorno ESRI. ¿Alguien puede ayudarme por favor?
Rania ben othmen

Respuestas:

8

Es posible que desee echar un vistazo a Shapely y Fiona . Fiona es un contenedor de gdal para facilitar la importación y exportación de archivos espaciales. Shapely proporciona funcionalidad de geometría. Aquí hay un ejemplo muy simple para darle la idea. Une atributos de polígono a todos los puntos dentro de ese polígono.

Los datos de ejemplo que he usado son estos polígonos y estos puntos .

import fiona
from shapely.geometry import shape
from copy import deepcopy

with fiona.open("planning_neighborhoods.shp", "r") as n: 

    with fiona.open("Schools_Private_Pt.shp", "r") as s:

        # create a schema for the attributes
        outSchema =  deepcopy(s.schema)
        outSchema['properties'].update(n.schema['properties'])

        with fiona.open ("Schools_withNbhd.shp", "w", s.driver, outSchema, s.crs) as output:

            for school in s: 
                for neighborhood in n:
                    # check if point is in polygon and set attribute
                    if shape(school['geometry']).within(shape(neighborhood['geometry'])):  
                        school['properties']['neighborho'] = neighborhood['properties']['neighborho'] 
                    # write out
                        output.write({                                 
                            'properties': school['properties'], 
                            'geometry': school['geometry']
                        })
cengel
fuente
Gracias @cengel. ¡Esto parece que me pondrá en el camino correcto! En realidad, estoy interesado en la unión con líneas y polígonos (específicamente para encontrar dónde los ríos se cruzan con las celdas modelo) y creo que funcionará siguiendo su ejemplo.
mishaF
@cengel ¿Las estaciones qgis que usan complementos que emplean estos métodos requieren la instalación de módulos y gdal?
user25976
@ user25976 lo siento, no estoy seguro de entender tu pregunta. Mi ejemplo de código es un script de python independiente. Tanto fiona como bien proporcionado requieren gdal.
cengel
@cengel Disculpe, déjame aclarar (soy nuevo en programación). Con respecto a los scripts de Python independientes: ¿quiere decir que los usuarios de QGIS pueden usar un complemento escrito con fiona e importaciones bien proporcionadas, incluso si no tienen Python o los módulos instalados en su computadora?
user25976
@ user25976 Necesitan los módulos instalados en su computadora. Ver por ejemplo aquí
cengel
2

Aunque todavía es un poco difícil, especialmente cuando se trata de documentación y ejemplos, pero el futuro de las geopandas parece brillante. Básicamente combina el poder de los marcos de datos de pandas con las capacidades geoespaciales de Shapely.

la función que busca se llama sjoin

Asegúrese de que su máquina / instancia tenga suficiente memoria para realizar la operación

import geopandas as gpd
import pandas as pd
import os

gdfLeft = gpd.read_file(os.path.join(PATH,INPUT_FILE_NAME_1))
gdfRight = gpd.read_file(os.path.join(PATH,INPUT_FILE_NAME_2))

gdfJoined = gpd.sjoin(gdfLeft, gdfRight, how="left", op='intersects')
RutgerH
fuente
Este código realiza la unión espacial pero los atributos del archivo de forma unido están vacíos. Cualquier puntero?
abril