#1 Thu 30 April 2020 20:53
- preliator
- Participant assidu
- Date d'inscription: 17 Nov 2018
- Messages: 433
Selection de polygones par la forme
Bonjour à tous,
Je travaille actuellement sur une étude liée à la position des bâtiments dans un département. Pour avoir une base de données de bâtiments la plus complète possible, j'utilise deux couches de deux bdd différente : Les bâtiments d'OSM et de datagouv. Effectivement, certains bâtis d'OSM (environ 10%) ne sont pas présents dans les bâtis de Datagouv. Mais les 90% sont des doublons des bâtis de datagouv.
Je me retrouve dans une situation aussi jubilante qu'embêtante, car les bâtis sont scannés ... en décalé !
Voici un exemple : https://zupimages.net/viewer.php?id=20/18/71wt.png
En violet, nous avons les polygones de datagouv. En gris, ceux d'OSM.
Entre deux polygones qui représentent une même maison, la superficie varie entre 1 et 2 m² mais la forme est visiblement très homogène.
Je cherche donc à supprimer les bâtis d'OSM qui sont des doublons de ceux de datagouv. Mais comment reconnaître ces doublons ? Certains d'entre eux sont simplement superposés (donc un st_intersects suffira pour les selectionner et supprimer), mais dans cette exemple et dans d'autre, les bâtis sont très espacés (plusieurs dizaines de mètres).
Existe t-il d'autres manière de trouver ces doublons ? Je pensais à des formules qui se base sur la ressemblance de la forme de polygones.
Merci.
Hors ligne
#2 Thu 30 April 2020 21:23
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Selection de polygones par la forme
Bonsoir,
Je partirais sur une comparaison de surface, de distance de Hausdorff (https://postgis.net/docs/manual-2.5/ST_ … tance.html) et d'indice de compacité. (https://gis.stackexchange.com/questions … of-polygon)
Nicolas
En ligne
#3 Thu 30 April 2020 21:52
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Selection de polygones par la forme
Un mix des critères suivant les cas, mais pas forcément facile sans essais-erreur avant:
Code:
-- fonction utilitaire indice de compacité create function st_compactnessindex(geom geometry) returns double precision language sql as $$ select (4*pi()*st_area(geom))/(nullif(st_perimeter(geom), 0)^2) $$; -- cross join entre les deux tables pour afficher les infos complètes: (attention a ne faire que sur des toutes petites tables :) ) select b1.gid, b2.gid as gid2, st_area(b1.geom) as area1, st_area(b2.geom) as area2, st_hausdorffdistance(b1.geom, b2.geom) as hdist, st_compactnessindex(b1.geom) as cidx1, st_compactnessindex(b2.geom) as cidx2 from bat b1, bat2 b2 order by b1.gid, b2.gid; gid gid2 area1 area2 hdist cidx1 cidx2 1 1 30102.74632169168 10128.92332806234 440.72335319776073 0.7553205231982011 0.7690827522505548 1 2 30102.74632169168 15296.523827591263 526.4486281851497 0.7553205231982011 0.577661001599545 1 3 30102.74632169168 7604.686539527581 688.2669119454129 0.7553205231982011 0.7718128198540396 1 4 30102.74632169168 3565.029900548586 789.2677104729362 0.7553205231982011 0.6487170062843381 2 1 9982.209118296534 10128.92332806234 166.03757945814021 0.7520901102347395 0.7690827522505548 2 2 9982.209118296534 15296.523827591263 225.80428866661123 0.7520901102347395 0.577661001599545 2 3 9982.209118296534 7604.686539527581 307.9930222870181 0.7520901102347395 0.7718128198540396 2 4 9982.209118296534 3565.029900548586 383.91744716803595 0.7520901102347395 0.6487170062843381 3 1 15312.825406454136 10128.92332806234 306.8291476836387 0.5812664559062624 0.7690827522505548 3 2 15312.825406454136 15296.523827591263 167.9001063856627 0.5812664559062624 0.577661001599545 3 3 15312.825406454136 7604.686539527581 253.21470668281214 0.5812664559062624 0.7718128198540396 3 4 15312.825406454136 3565.029900548586 286.18462597116365 0.5812664559062624 0.6487170062843381 4 1 7842.313400643993 10128.92332806234 332.946308288149 0.7894012461036052 0.7690827522505548 4 2 7842.313400643993 15296.523827591263 212.14948803325382 0.7894012461036052 0.577661001599545 4 3 7842.313400643993 7604.686539527581 167.49632002821605 0.7894012461036052 0.7718128198540396 4 4 7842.313400643993 3565.029900548586 129.59800191041765 0.7894012461036052 0.6487170062843381 5 1 3626.474313185553 10128.92332806234 496.41182281643984 0.6267715798896841 0.7690827522505548 5 2 3626.474313185553 15296.523827591263 376.5383130683794 0.6267715798896841 0.577661001599545 5 3 3626.474313185553 7604.686539527581 320.1022569335611 0.6267715798896841 0.7718128198540396 5 4 3626.474313185553 3565.029900548586 166.65195621986115 0.6267715798896841 0.6487170062843381 -- filtre sur un des critères: par ex moins de 10% d'ecart de surface: with tmp as ( select b1.gid, b2.gid as gid2, st_area(b1.geom) as area1, st_area(b2.geom) as area2, st_hausdorffdistance(b1.geom, b2.geom) as hdist, st_compactnessindex(b1.geom) as cidx1, st_compactnessindex(b2.geom) as cidx2 from bat b1, bat2 b2 ) select * from tmp where abs(area1 - area2)/area1 < 0.1; gid gid2 area1 area2 hdist cidx1 cidx2 2 1 9982.209118296534 10128.92332806234 166.03757945814021 0.7520901102347395 0.7690827522505548 3 2 15312.825406454136 15296.523827591263 167.9001063856627 0.5812664559062624 0.577661001599545 4 3 7842.313400643993 7604.686539527581 167.49632002821605 0.7894012461036052 0.7718128198540396 5 4 3626.474313185553 3565.029900548586 166.65195621986115 0.6267715798896841 0.6487170062843381
Nico
En ligne
#4 Fri 01 May 2020 09:29
- preliator
- Participant assidu
- Date d'inscription: 17 Nov 2018
- Messages: 433
Re: Selection de polygones par la forme
Merci beaucoup pour ces informations et cet exemple détaillé. Je regarderai ça de plus près.
Peut t-on imaginer adapter cette requête pour des tables de ~200 000 entités en rajoutant un index spatial ?
Merci.
Hors ligne
#5 Fri 01 May 2020 10:04
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Selection de polygones par la forme
Bonjour,
Oui vous pouvez filtrer les batiments en ne prenant que les n plus proches voisins de chaque polygone ou ne prenant que les batiments a moins de x metres des polygones (st_dwithin)
Nicolas
En ligne