J'essaie de trouver les points d'inflexion, c'est-à-dire les points où les courbes d'une ligne commencent et se terminent. Si vous regardez l'image, la ligne verte peut être une route ou un ruisseau et les points noirs sont les points de départ et de fin des courbes.
Quelles seraient les étapes de haut niveau pour automatiser la génération de ces points? J'ai un bureau ArcGIS et je suis assez maniable avec ArcObjects.
arcobjects
algorithm
Devdatta Tengshe
la source
la source
Réponses:
Lorsque la courbe est composée de segments de ligne, tous les points intérieurs de ces segments sont des points d'inflexion, ce qui n'est pas intéressant. Au lieu de cela, la courbe doit être considérée comme étant approximée par les sommets de ces segments. En splining une courbe deux fois différentiable par morceaux à travers ces segments, nous pouvons alors calculer la courbure. Un point d'inflexion proprement dit est alors un endroit où la courbure est nulle.
Dans l'exemple, il y a des étirements longs où la courbure est presque nulle. Cela suggère que les points indiqués devraient se rapprocher des extrémités de ces tronçons de régions à faible courbure.
Un algorithme efficace va donc spliner les sommets, calculer la courbure le long d'un ensemble dense de points intermédiaires, identifier les plages de courbure proche de zéro (en utilisant une estimation raisonnable de ce que signifie être "proche") et marquer les extrémités de ces plages .
Voici un
R
code de travail pour illustrer ces idées. Commençons par une chaîne de lignes exprimée comme une séquence de coordonnées:Spline les coordonnées x et y séparément pour obtenir un paramétrage de la courbe. (Le paramètre sera appelé
time
.)Interpoler les splines pour le traçage et le calcul:
Nous avons besoin d'une fonction pour calculer la courbure d'une courbe paramétrée. Il doit estimer les première et deuxième dérivées de la spline. Avec de nombreuses splines (telles que des splines cubiques), il s'agit d'un calcul algébrique facile.
R
fournit automatiquement les trois premiers dérivés. (Dans d'autres environnements, on peut vouloir calculer les dérivées numériquement.)Je propose d' estimer un seuil de courbure nulle en termes d'étendue de la courbe. C'est au moins un bon point de départ; il doit être ajusté en fonction de la tortuosité de la courbe (c'est-à-dire augmentée pour les courbes plus longues). Il sera ensuite utilisé pour colorer les parcelles en fonction de la courbure.
Maintenant que les sommets ont été cannelés et la courbure calculée, il ne reste plus qu'à trouver les points d'inflexion . Pour les montrer, nous pouvons tracer les sommets, tracer la spline et y marquer les points d'inflexion.
Les points ouverts sont les sommets d'origine
xy
et les points noirs sont les points d'inflexion identifiés automatiquement avec cet algorithme. Étant donné que la courbure ne peut pas être calculée de manière fiable aux extrémités de la courbe, ces points ne sont pas spécialement marqués.la source
Vous pouvez utiliser l' outil Densifier . Dans ce cas, vous choisissez de densifier par angle, Ensuite, choisissez l'angle maximum accepté en ligne droite. Appliquez ensuite la ligne de résultat à l'outil Scinder la ligne aux sommets . Enfin, supprimez les lignes dont la longueur de forme est inférieure à la longueur de route minimale.
Dans cette image, nous voyons trois étapes:
1- Densifiez la ligne en utilisant l'angle. J'ai utilisé 10 degrés comme paramètre, et nous avons utilisé splitline. Dans l'image, la ligne courbe est dans sa phase initiale.
2- Sélectionnez les segments où la forme_longueur n'est pas redondante. Comme nous le voyons dans le tableau, je n'ai pas sélectionné ces longueurs redondantes. Ensuite, je les sélectionne dans une nouvelle classe d'entités.
3- Nous avons extrait les sommets situés dans les bords des lignes, qui sont des points d'inflexion.
la source
Vous pouvez utiliser l' outil Généraliser qui a le décalage maximum par rapport à la ligne d'origine comme paramètre, afin que vous puissiez choisir le décalage qui correspond à votre cas.
Si nous nommons la ligne d'origine "line_cur" et la ligne généralisée "line_gen", nous pourrions couper "line_cur" par "line_gen". Le résultat sera le segment droit de "line_cur". Ensuite, nous pourrions nettoyer un segment très court en les supprimant avec une requête sql qui sélectionne la Shape_length supérieure à cette longueur de route minimale.
la source