Suite

Sélection de POI autour de bâtiments spécifiques à l'aide de PostGIS


Le problème : je dois sélectionner, pour chaque immeuble résidentiel de mon tableau qui compte au moins 2 pharmacies et 2 centres éducatifs dans un rayon de 1km, tous les POI (pharmacies, centres commerciaux, centres médicaux, centres éducatifs, postes de police, pompiers, gares) qui se trouvent à moins de 1 km du bâtiment respectif. structure du tableau->

imeuble (identifiant en série, Nom varchar)

catégorie_poi(identifiant en série, cnom varchar) --cname étant le nom de la catégorie bien sûr

poi(identifiant en série, Nom varchar, c_id entier)-- c_id est le FK référençant poi_category(identifiant)

toutes les colonnes de coordonnées sont de type géométrie et non géographie (appelons-les géom)

voici la façon dont je pensais que cela devrait être fait mais je ne suis pas sûr que ce soit même correct et encore moins la solution optimale à ce problème

SELECTIONNER 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 bâtiment 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. center' )>1

Est-ce la voie à suivre pour ce dont j'ai besoin ? Quelle solution serait meilleure d'un point de vue performance ? Et la solution la plus élégante ?


Sur la base du deuxième exemple donné sur cette page, j'essayerais quelque chose comme :

SELECT b.gid, b.name, [+ any fields] -- vous récupérez ici les données de POI 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) -- éd. center -- LEFT JOIN POI AND POI_CATEGORY tables + conditions de jointure WHERE f.id_pc='pharmacy' AND ec.id_pc='ed. centre' ET COMPTE(f.gid) >1 ET COMPTE(ec.gid)>1 ;

Bien sûr, il n'est pas testé et la requête n'est pas complète mais la logique serait de joindre des tables sur des critères géométriques. Si cela fonctionne, ajoutez des instructions pour récupérer vos données de POI.


Je les fais généralement dans plpgsql car je trouve cela beaucoup plus facile à lire et les résultats sont généralement plus efficaces car vous pouvez contrôler le flux (sortir plus tôt, etc.):

CRÉER OU REMPLACER LA FONCTION getpois() RETOURNE le texte en tant que $$ DECLARE br record ; phcount entier ; edcount entier ; FOR br IN SELECT id, name, geom FROM building LOOP SELECT count(id) from poi où ST_DWITHIN(br.geom, geom, 1000) et c_id = pharmaciecateg dans phcount; SI phcount < 2 ALORS SORTIE ; --je pense que c'est l'équivalent de continuer, c'est-à-dire passer au prochain bâtiment ENDIF; SELECT count(id) de poi où ST_DWITHIN(br.geom, geom, 1000) et c_id = pharmaciecateg dans edcount ; SI edcount < 2 ALORS SORTIE; FIN SI; -- maintenant sélectionnez tous les POIS dans un rayon de 1 km et renvoyez-les peut-être sous forme de tableau, etc. END LOOP ; END $$ LANGUE 'plpgsql' strict;