2011-06-24 71 views
1

问题:我需要为表中的每个建筑物选择至少2个药房和2个教育中心,方圆1公里内的所有POI(药房,商业中心,医疗中心,教育中心,警察局,消防局),距离各自建筑1公里。表结构 - >postgis高级(?)选择查询

建筑物(ID的序列,名称VARCHAR)

poi_category(ID的序列,CNAME VARCHAR)--cname是当然

POI(ID的序列,名称VARCHAR,C_ID的类别名称整数) - C_ID是FK引用poi_category(ID)

所有的坐标列的类型都是几何不是地理的(姑且称之为GEOM)

以下是我认为它应该做的方式,但我不确定它甚至是正确的让阿洛ne对此问题的最佳解决方案

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

回答

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.