J'essaie de faire correspondre de petits segments avec un segment plus grand auquel ils sont le plus probablement liés: relèvement relativement proche et similaire, et face à face.
Voici un exemple typique des données dont je dispose:
Ici, je devrais faire correspondre le segment 652 à 198969, tout en ayant 711 et 707 ne correspondant à rien.
J'ai cherché différentes méthodes, en particulier la distance de Hausdorff (basée sur les réponses ici ). Je l'ai calculé à l'aide de PostGIS mais j'obtiens des résultats étranges: la distance la plus courte que j'obtiens se situe entre 707 et 198985, et 652 a une distance plus grande avec 198969 qu'avec 198985 par exemple (je peux ajouter la requête et les résultats si nécessaire).
Hausdorff est-il réellement la bonne méthode pour résoudre ce problème? Existe-t-il d'autres approches? J'ai pensé à simplement créer un ensemble de contrôles sur les paramètres que j'ai mentionnés (distance, relèvement, etc.) mais j'ai peur d'avoir à ajouter tout un tas de conditions pour gérer les cas de bord ou des choses comme le seuil sur combien ils sont l'un face à l'autre.
Mise à jour: j'ai trouvé une méthode qui semble être un compromis acceptable:
- Je trouve d'abord les 10 segments noirs les plus proches du bleu que j'essaie de faire correspondre (en utilisant l'
<->
opérateur PostGIS ) qui sont à moins de 10 mètres. - Je crée ensuite un nouveau segment en trouvant les points les plus proches des extrémités du segment bleu sur chacun des noirs (en utilisant
ST_ClosestPoint
) et filtre les résultats dont la longueur est inférieure à 90% du bleu (ce qui signifie que les segments ne sont pas face ou que la différence d'appui est supérieure à ~ 20 °) - Ensuite, j'obtiens le premier résultat trié par distance et par distance de Hausdorff, le cas échéant.
Il pourrait y avoir un réglage fin à faire, mais il semble faire un travail acceptable pour l'instant. Toujours à la recherche d'autres méthodes ou de vérifications supplémentaires à exécuter si j'ai raté des cas marginaux.
la source
Réponses:
Voici quelques fonctions que j'ai écrites qui devraient vous permettre de faire ce que vous devez faire. Vérifiez et voyez si la ligne est polyligne ou segment si la polyligne explose la ligne, puis comparez l'azimut et l'inverse du premier point et du dernier point sur les lignes, définissez-vous des critères acceptables pour que le code prenne une décision pour vous. Ce sont des méthodes arcpy mais pourraient être modifiées.
retour azimut du segment de ligne ESRI @shape
retour inverse des points ESRI
exploser la polyligne en segment de ligne
courir à travers votre table comme ça
ces propriétés devraient être disponibles dans postgis - firstpoint, lastpoint, pointarray Je suppose que les propriétés esri ci-dessus parce que c'est ce que je connais le mieux, mais ce qui précède peut facilement être modifié pour fonctionner avec postgis.
la source