1

问题:我需要为我表中的每座建筑物选择在 1 公里半径内至少有 2 个药店和 2 个教育中心的所有 POI(药房、商业中心、医疗中心、教育中心、警察局、消防局) 距离相关建筑物 1 公里以内。表结构->

建筑物(id 序列号,名称 varchar )

poi_category(id serial, cname varchar) --cname 当然是类别名称

poi(id serial, name varchar, c_id integer)-- c_id 是引用 poi_category(id) 的 FK

所有坐标列都是几何类型而不是地理类型(我们称它们为 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

4

1 回答 1

3

这是我阐述的解决方案。这是我能找到的最快的,但它仍然很慢。鉴于任务的性质,我怀疑它可以做得更快......

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))

你的。S。

于 2012-08-15T23:18:01.873 回答