5 votos

Selección de puntos de interés alrededor de edificios específicos utilizando PostGIS

El problema: tengo que seleccionar, para cada edificio residencial en mi mesa, que ha decir que al menos 2 de las farmacias y 2 centros de educación dentro de un radio de 1 km, todos los Poi (farmacias, centros comerciales, centros médicos, centros de enseñanza, estaciones de policía, estaciones de bomberos), que están a menos de 1 km de los edificios. estructura de la tabla->

edificio (id serial, nombre varchar )

poi_category(id serial, nombre varchar) --cname ser el nombre de la categoría de curso

pdi(id serial, nombre varchar, c_id entero)-- c_id es el FK referencia poi_category(id)

todas las coordenadas de las columnas son de tipo de geometría no geografía (vamos a llamarlos geom)

he aquí la manera en que yo pensaba que debería hacer, pero no estoy seguro de que es correcto aún no digamos la solución óptima para este problema

    SELECT r.id_b, r.id_p
    FROM (
         SELECT b.id AS id_b, p.id AS id_p, pc.id AS id_pc,pc.cname
         FROM building AS b, poi AS p, poi_category AS pc
         WHERE ST_DWithin(b.geom,p.geom, 1000) AND p.c_id=pc.id
         ) AS r,
         (
         SELECT * FROM r GROUP BY id_b
         ) AS r1

     HAVING  count (
                       SELECT *
                       FROM r, r1
                       WHERE r1.id_b=r.id_b AND r.id_pc='pharmacy'

                    )>1
                 AND
                 count (
                       SELECT *
                       FROM r, r1
                       WHERE r1.id_b=r.id_b AND r.id_pc='ed. centre'

                    )>1

Es este el camino a seguir para lo que yo necesito ? ¿Qué solución sería la mejor desde un punto de vista del rendimiento? ¿Qué acerca de la solución más elegante?

2voto

axk Puntos 2147

Generalmente éstos en plpgsql haré que me resulta mucho más fácil de leer y los resultados son generalmente más eficientes porque puede controlar el flujo (salida temprano, etcetera):

CREATE OR REPLACE FUNCTION getpois() RETURNS text as $$
DECLARE
br record;
phcount integer;
edcount integer;
FOR br IN SELECT id, name, geom FROM building LOOP
  SELECT count(id) from poi where ST_DWITHIN(br.geom, geom, 1000) and c_id = pharmacycateg into phcount;
  IF phcount < 2 THEN
     EXIT; --i think this is the equiv of continue, i.e. skip to next building
  ENDIF;
  SELECT count(id) from poi where ST_DWITHIN(br.geom, geom, 1000) and c_id = pharmacycateg into edcount;
  IF edcount < 2 THEN
     EXIT;
  ENDIF;
  -- now select all POIS within 1KM and maybe return them as array, etc
END LOOP;
END
$$ LANGUAGE 'plpgsql' strict;

2voto

eplawless Puntos 2076

Basado en el segundo ejemplo dado en esa página, me gustaría probar algo como:

SELECT b.gid, b.name, [+ any fields] -- here you retrieve POI data
    FROM building b
        LEFT JOIN building f ON ST_DWithin(b.the_geom, f.the_geom, 1000) -- farmacy
        LEFT JOIN building ec ON ST_DWithin(b.the_geom, ec.the_geom, 1000) -- ed. center
        -- LEFT JOIN POI AND POI_CATEGORY tables + join conditions
    WHERE f.id_pc='pharmacy' AND ec.id_pc='ed. centre'
    AND COUNT(f.gid) >1 AND COUNT(ec.gid)>1;

Por supuesto, no está probado y la consulta no está completa pero la lógica sería unir tablas con respecto a criterios geométricos. Si eso funciona, a continuación, agregue las instrucciones para recuperar sus datos POI.

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