5 votos

avg dist entre puntos dentro de polígonos

Tengo una tabla de puntos (escuelas t1) y una tabla de pequeños polígonos (edificios t2). Están dentro de los grandes polígonos (p) que representan a los distritos. Estoy tratando de obtener el promedio de la distancia de una escuela para todos los edificios dentro del mismo distrito. Soy realmente nuevo en esto, y encontré un post que parecía tener la respuesta, pero no acabo de conseguirlo. ¿Qué estoy haciendo mal?

WITH SCHOOLS AS (

  SELECT  p.gid, p.cell, t1.name, code2, pub_pri2, enrollment, t1.geom as wkb_geometry 
    FROM mesa.schools2 t1 
    LEFT JOIN mesa.schldist_cellpop p ON ST_CONTAINS (p.geom, t1.geom)
    ORDER BY p.gid), 

DISTANCES AS (
  SELECT p.cell, t1.geom <-> t2.geom as dist FROM 
   (SELECT distinct on(t1.gid) t1.gid, p.cell, t1.geom,
      (SELECT t2.geom FROM mesa.school_pop t2 
           ORDER BY t2.geom<->B.wkb_geometry 
           LIMIT 1) AS other_geometry 
       FROM mesa.schldist_cellpop p, SCHOOLS B, mesa.school_pop t2, mesa.schools2 t1)   AS FOO)

SELECT distinct p.cell,
     count(p.cell) over(partition by p.cell),
     round(avg(distance) over(partition by p.cell)::NUMERIC, 1)
     FROM DISTANCES
     WHERE DISTANCES IS NOT NULL

El error que estoy recibiendo es ERROR: falta DE cláusula de entrada para la tabla "p" LÍNEA 9: SELECCIONE p.celular, t1.geom <-> t2.geom como dist DE

6voto

tobes Puntos 19

El problema es que la línea 9 solo conoce FOO. Ya no tiene acceso a p, t1 o t2. Tratar:

 DISTANCES AS (
  SELECT FOO.cell, FOO.geom <-> FOO.other_geometry as dist FROM 
   (SELECT distinct on(t1.gid) t1.gid, p.cell, t1.geom,
      (SELECT t2.geom FROM mesa.school_pop t2 
           ORDER BY t2.geom<->B.wkb_geometry 
           LIMIT 1) AS other_geometry 
       FROM mesa.schldist_cellpop p, SCHOOLS B, 
            mesa.school_pop t2, mesa.schools2 t1) AS FOO)
 

2voto

Gracias micky De hecho, terminé con algo más simple una vez que me di cuenta de que la zona del distrito # estaba en todas las tablas, que eliminó la necesidad de hacer un límite espacial por el polígono del distrito. Terminé con:

 SELECT DISTINCT t2.gid, name, t2.cell as school_cell, 
  avg(ST_DISTANCE (t1.geom, t2.geom))
  OVER (PARTITION BY name) AS dist_avg_m
FROM n.table1 t1, n.table2 t2
WHERE t1.cell = t2.cell
ORDER BY t2.cell
 

Pero estas son grandes sugerencias y ahora las tengo en mi caja de herramientas.

1voto

jennz0r Puntos 48

Me siento que usted tiene más complicado su consulta para lo que parece que quiere que sea el resultado y, como consecuencia, no le dará los resultados que usted está después.

He creado una pequeña prueba de conjunto de datos para ejecutar la consulta (la incorporación de @underdarks fix) a trabajar de lo que estaba haciendo y los resultados, donde muy extraño.

La consulta devuelve menos filas, baja de la cuenta y lo que aparece a la distancia mínima para el pequeño conjunto de datos de prueba que me genera. Creo que esto es debido a la LIMITed subconsulta y algunas otras partes y piezas.

En lugar de tratar de solucionar su consulta, la siguiente consulta simple debe dar el resultado que usted desea.

SELECT d.cell,
    count(*) num,
    round(avg(s.geom <-> b.geom)::NUMERIC ,1) avg_dist
FROM mesa.schldist_cellpop AS d  -- For each district
    INNER JOIN mesa.schools2 AS s   ON ST_INTERSECTS(d.geom, s.geom) -- join to the school
    INNER JOIN mesa.school_pop AS b ON ST_INTERSECTS(d.geom, b.geom) -- and the buildings
GROUP BY d.cell

He usado cruza en lugar de lo que contiene, ya que si tiene edificios en el límite, pensé que sería mejor incluir en los promedios en ambos lados en lugar de no, en absoluto. Si usted tiene varias escuelas en un distrito tendrá que cambiar la consulta para tratar con ellas en una manera apropiada.

La muestra de datos utilizada fue generado por la siga CTE declaraciones

-- Some Sample data to work on
WITH schools2 AS (
    -- three school points A B and C.  One for each district
    SELECT *
    FROM (VALUES
        (1,'A', 'POINT(5 5)'::Geometry),
        (2,'B', 'POINT(15 5)'::Geometry),
        (3,'C', 'POINT(5 15)'::Geometry)
    ) S(gid,name, geom)
),
    school_pop AS (
    -- some random points as buildings.  Could be polygons, but points will do for the example
    SELECT ('POINT(' || (random()*20) || ' ' || (random()*20)||  ')')::Geometry AS geom
    FROM generate_series(1,20) B(geom)
),
    schldist_cellpop AS (
    -- Three districts each with a school.  2 small, 1 large
    SELECT *
    FROM (VALUES
        (1,'D1','POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'::Geometry),
        (2,'D2','POLYGON((10 0, 20 0, 20 20, 10 20, 10 0))'::Geometry),
        (3,'D3','POLYGON((0 10, 10 10, 10 20, 0 20, 0 10))'::Geometry)
    ) D(gid,cell,geom)
)

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