6 votos

Cómo actualizar los valores de atributo de puntos fuera de un área?

Tengo dos conjuntos de datos en PostGIS 1.5 (en Postgres 9.1) uno de los polígonos y uno de los puntos.

Estoy con la esperanza de crear un comando SQL que se seleccione todos los puntos de un conjunto de datos que no están dentro del polígono características y asignar un valor de -9999 a una de las columnas. En este caso el límite es un continente -9999 define una característica fuera de la península.

Tengo varios cientos de miles de características y han tratado de lograr este más o menos de forma manual en QGIS. Sin embargo, una vez que las características son seleccionados no puedo interactuar con QGIS sin que se caiga.

ACTUALIZACIÓN

Saludos para info Nicklas.

Teniendo un par de problemas con el rendimiento que tiene esta función toma de 96 horas y contando. Traté de detener previamente y establecer un LÍMITE de 100 en la selección y era todavía un par de horas.

Esto es con la Esencia y el Árbol de la indización.

Traté de correr, SELECCIONA en point_id, sólo que sin la función de ACTUALIZACIÓN y obtuvo resultados similares.

Previamente en QGIS se toma cerca de 16 horas para seleccionar todos los puntos dentro de los polígonos.

Veremos algunos de optimización de rendimiento y vuelva a intentarlo un poco más tarde

2ª ACTUALIZACIÓN

Estoy 99% seguro de Índice, pero siempre hay un poco de espacio para la duda =D

Resultado de la primera consulta

PLAN DE CONSULTA
Bucle anidado Left Join (cost=0.00..12955070.02 filas=1 width =4)
Filtro de combinación _st_intersects(point_table.the_geom, polygon_table.the_geom)
Filtro: (polygon_table.polygon_id ES NULO)
-> Seq Scan on point_table (cost=0.00..209494.58 filas=1562658 width=104)
-> Index Scan utilizando poly_table_geom_idx en polygon_table (cost=0.00..7.89 filas=1 width=22520) Índice de Cond: (point_table.the_geom && the_geom)
(6 Filas)

Resultado de la segunda consulta es

suma
59257303
(1 fila)

Resultado de la comparación de las dos consultas con el LÍMITE de 1000 es que la primera toma alrededor de 15 minutos y el segundo todavía se está ejecutando después de una hora.

He dividido las características de uso de ST_Dump y en la actualidad estoy configurando la Indexación, las Llaves, etc para que.

EDITAR
Tenemos una completa ST_Dump

Bucle anidado costo aumentó a 13142577, Seq Scan quedado en el mismo, el Índice de ancho de Escaneo aumentó a 1162940

Capa de punto contiene 1728921 puntos

4voto

Lars Mæhlum Puntos 4569

editar:
Los tiempos han tenido que parece extraño. Algo no es como se esperaba.

Es el de los índices usa realmente? ¿Que es el texto el resultado de:

EXPAIN
SELECT point_id FROM 
point_table LEFT JOIN polygon_table 
ON ST_Intersects(point_table.geom, polygon_table.geom)
WHERE polygon_id IS NULL;

Cuántos vértices puntos de su polígono conjunto de datos? ¿Cuál es el resultado de:

SELECT SUM(ST_NPoints(the_geom)) FROM polygon_table;

Para analizar lo que está sucediendo, creo que la más sencilla es ejecutar partes de la consulta a ver cómo se comporta, como si han hecho con "límite de 100".

Por lo tanto, si usted ejecute las siguientes consultas y estudiar el tiempo debería dar una pista acerca de lo que podría ser el problema:

SELECT count(*) 
FROM point_table INNER JOIN polygon_table 
ON point_table.geom && polygon_table.geom LIMIT 1000;

comparar el calendario y resultado de la ejecución de la real ST_Intersects función:

SELECT count(*) 
FROM point_table INNER JOIN polygon_table 
ON ST_Intersects(point_table.geom,polygon_table.geom) 
LIMIT 1000;

Si el resultado de la consulta 1 es un número mucho mayor que la de consulta 2 consulta y 2 lleva mucho más tiempo que el de la consulta 1, el problema es que el índice de selectividad. Si es Multipolígonos en el conjunto de datos en el primer caso, lo mejor es dividir los Polígonos con ST_Dump y construir un nuevo índice en el resultado.

Hay más cosas que se pueden hacer como dividir el más grande de los polígonos con una cuadrícula, pero que es más complejo.

Empezar con eso para ver si esa es la parte lenta. Si no es el momento de continuar las pruebas con el LEFT JOIN y el "polygon_id no es nulo".

dejar de editar

Sí, esta es una de PostGIS tarea.

No he probado la de abajo y no estoy seguro de que es la forma más eficiente de hacer la actualización, pero la subconsulta debe ser bastante rápida. La idea es encontrar todos los puntos de intersección con los polígonos y, a continuación, pedir a los puntos que no se encuentran en los polígonos. Algo como esto debería funcionar:

UPDATE point_table SET p_id=-9999 WHERE point_id IN
(SELECT point_id FROM point_table LEFT JOIN polygon_table 
ON ST_Intersects(point_table.geom, polygon_table.geom)
WHERE polygon_id IS NULL);

Poner gist índices en el geoemtry columnas y btree índice en el id de punto.

HTH

Nicklas

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X