postgis разширена (?) заявка за избор

Проблемът: Трябва да избера за всяка сграда в моята таблица, която има поне 2 аптеки и 2 образователни центъра в радиус от 1 км, всички POI (аптеки, търговски центрове, медицински центрове, образователни центрове, полицейски участъци, пожарни станции ), които са на 1 км от съответната сграда. структура на таблицата->

сграда (сериен идентификатор, име varchar)

poi_category(id serial, cname varchar) --cname е името на категорията, разбира се

poi(id serial, name varchar, c_id integer)-- c_id е FK, препращащ към poi_category(id)

всички координатни колони са от тип геометрия, а не география (нека ги наречем geom)

ето начина, по който мислех, че трябва да се направи, но не съм сигурен, че дори е правилен, да не говорим за оптималното решение на този проблем

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

Това ли е начинът да отида за това, от което се нуждая? Какво решение би било по-добро от гледна точка на ефективността? Какво ще кажете за най-елегантното решение? Също така публикувах тук: http://gis.stackexchange.com/questions/11445/postgis-advanced-selection-query


person Dackster.ox    schedule 24.06.2011    source източник


Отговори (1)


Това е решение, което разработих. Това е най-бързият, който успях да намеря, но все още е бавен. Предвид естеството на задачата се съмнявам, че може да се направи по-бързо...

WITH 
building AS (
  SELECT way, osm_id
  FROM osm_polygon
  WHERE tags @> hstore('building','yes')
  --ORDER BY 1 
  LIMIT 1000
),
pharmacy AS (
  SELECT way
  FROM osm_poi
  WHERE tags @> hstore('amenity','pharmacy') 
), 
school AS (
  SELECT way 
  FROM osm_poi
  WHERE tags @> hstore('amenity','school') 
)
SELECT ST_AsText(building.way) AS geom, building.osm_id AS label
FROM building
WHERE
  (SELECT count(*) > 1
   FROM pharmacy
   WHERE ST_DWithin(building.way,pharmacy.way,1000))
  AND
  (SELECT count(*) > 1
   FROM school
   WHERE ST_DWithin(building.way,school.way,1000))

твоя. С.

person Stefan    schedule 15.08.2012