8 votos

¿Cómo hacer una unión espacial en PostGIS que devuelva el valor mínimo del punto que intersecta un polígono?

Tengo una tabla de polígonos (buffer) y una tabla de puntos (dem_points), y quiero hacer una unión espacial entre ellas. Necesito unir el punto con la elevación mínima (dn) a su polígono correspondiente espacialmente en PostGIS.

introducir descripción de la imagen aquí

En el ejemplo anterior quiero que mi resultado sea el polígono con osm_id de '1234' unido al punto donde dn=4200. Tengo esta consulta pero algo está mal:

SELECT osm_id, gid, MIN(dn) 
FROM (
      SELECT a.id AS osm_id, b.id AS gid, b.dn AS dn
      FROM 
         buffer AS a, dem_points AS b
      WHERE ST_Within(buffer.geom, dem_points.geom)
     ) AS subquery
GROUP BY (osm_id, gid);

Con esta consulta recibo este error:

ERROR: la subconsulta en FROM debe tener un alias
LÍNEA 2:      FROM (
              ^
SUGERENCIA: Por ejemplo, FROM (SELECT ...) [AS] foo.
ERROR: subconsulta en FROM debe tener un alias
Estado SQL: 42601
Sugerencia: Por ejemplo, FROM (SELECT ...) [AS] foo.
Personaje: 40

¿Cómo debo estructurar mi consulta para unir espacialmente el punto con la elevación mínima al polígono en el que se encuentre?

0 votos

¿Qué es exactamente estar apagado?

0 votos

No estoy seguro, pero recibo este error: ERROR: subconsulta en FROM debe tener un alias LÍNEA 2: FROM ( ^ HINT: Por ejemplo, FROM (SELECT ...) [AS] foo. ********** Error ********** ERROR: subconsulta en FROM debe tener un alias Estado SQL: 42601 Sugerencia: Por ejemplo, FROM (SELECT ...) [AS] foo. Carácter: 40

0 votos

Necesitas poner un AS alias_name después de tu consulta interna, es decir, SELECT osm_id, gid, MIN(dn) FROM (.......) AS g GROUP BY (osm_id, gid);

8voto

BlakeAndMortimer Puntos 171

Primero, utiliza una función de ventana para obtener el rango ordenado de los dem_points. En un segundo paso, filtra el dem_point con el valor dn más bajo por el rango.

SELECT osm_id, gid, dn
FROM   (
         SELECT b.osm_id, p.gid, p.dn,
                row_number() OVER (PARTITION BY osm_id order by dn) as rank
         FROM   buffer b, dem_points p
         WHERE  ST_Within(p.geom, b.geom) 
       ) joined
WHERE  rank = 1

0 votos

Esta consulta no devuelve ningún dato, solo los nombres de las cabeceras de la tabla de osm_id y dn. Pero no están poblados.

0 votos

Los parámetros en ST_Within() estaban en el orden incorrecto. He editado la respuesta en consecuencia.

4voto

brad Puntos 302

Necesitas agrupar los puntos por buffer geométrico, luego encontrar el min(dn) para cada buffer geométrico, y finalmente unirlo de nuevo al original para obtener el gid del punto. Prueba algo como esto (usando la sintaxis WITH para que sea un poco más fácil de seguir):

WITH foo AS (
  SELECT b.osm_id, p.gid, p.dn
  FROM buffer b, dem_points p
  WHERE ST_Within(p.geom, b.geom)
), bar AS (
  SELECT osm_id, min(dn) as dn FROM foo
  GROUP BY osm_id
)
SELECT bar.osm_id, foo.gid, bar.dn 
FROM bar JOIN foo ON foo.osm_id=bar.osm_id AND foo.dn=bar.dn

Ten en cuenta que otra forma de hacer esto es usar la cláusula HAVING de PostgreSQL pero creo que es más difícil de seguir.

0 votos

Esta consulta devuelve el error: ERROR: la columna foo.pid no existe LÍNEA 10: FROM bar JOIN foo ON foo.pid=bar.pid AND foo.dn=bar.dn ^ ********** Error ********** ERROR: la columna foo.pid no existe Estado SQL: 42703 Carácter: 236

0 votos

Corregí el nombre del campo a osm_id

0 votos

La consulta se ejecuta ahora, pero devuelve registros duplicados. Entonces, en lugar de devolver el osm_id con el valor 'dn' más bajo, devuelve un registro de osm_id por cada valor 'dn' contenido en él.

0voto

cbunn Puntos 463

He encontrado una forma alternativa de resolver esta pregunta. Siguiendo este hilo: https://geonet.esri.com/thread/16118. Al realizar una unión de uno a muchos donde los puntos son las entidades de destino y los polígonos son las entidades de unión. Luego ejecutando una consulta de definición contra la nueva capa de esta manera:

dn en (select min(dn) from dn group by osm_id)

Esto ahora solo mostrará aquellos puntos con el valor "dn" mínimo. Todo esto debe realizarse dentro de una geodatabase personal.

0 votos

Pensé que estabas tratando de obtener la elevación mínima? ¿Estás usando la función max en la subconsulta?

0 votos

Oh, tienes razón, he editado mi fórmula para mostrar esto.

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