Calcul de la longueur d'un polygone le long d'une ligne?

8

J'ai besoin de calculer la longueur des polygones le long / projetés sur une ligne. Une image pour montrer l'idée:

entrez la description de l'image ici

J'ai des milliers de polygones à "projeter" sur les lignes pour vérifier à combien de mètres de la ligne ils appartiennent. Les polygones sont irréguliers, avec une orientation différente, une partie d'entre eux coupent la ligne, une partie pas.

J'ai essayé:

  1. Outil de localisation d' entités le long de la ligne dans ArcGIS Pro, mais il ne donne que la longueur de ligne pour la partie chevauchante d'un polygone (description de l'outil ici, aide ESRI )

  2. Géométrie de délimitation minimale avec l'option `` coque convexe '', mais elle ne donne que la distance entre les points antipodaux d'un polygone, qui n'est pas parallèle à ma ligne (description de l'outil ici Aide ESRI

Suis-je absent d'un outil pour cela dans ArcGIS ou QGIS? Auriez-vous une solution pour cela?

Konrad Gje
la source
Votre ligne est-elle une ligne droite?
JiyuuSensei
Puisque vous avez une exigence unique, il ne semble pas déraisonnable qu'un tel outil n'existe pas. Vous pouvez certainement coder un tel outil en utilisant des fonctions trigonométriques et diverses fonctions d'aide à la géométrie, mais vous devez d'abord choisir une plate-forme logicielle.
Vince
@JiyuuSensei non, en fait c'est un réseau polyligne - comme un réseau routier ou un réseau de pipelines. Cela devrait donc fonctionner comme le calcul de cette «longueur de polygone» pour le segment de ligne le plus proche du réseau. C'est donc essentiellement l'idée du fonctionnement de l'outil Localiser les fonctionnalités le long de la ligne .
Konrad Gje

Réponses:

7

Utilisation de QGIS:

(1) Créez une couche de points des sommets du polygone à l'aide de l' outil Extraire les sommets (dans la boîte à outils de traitement QGIS> Géométrie vectorielle).

entrez la description de l'image ici

(2) Ouvrez la table attributaire du calque Vertices nouvellement créé .

(3) Démarrez le calculateur de champ et;

(3A) Créez un nouveau champ, appelons-le min_poly pour stocker la distance minimale et donner une expression:

minimum(
 line_locate_point(
  geometry:=geometry(get_feature_by_id('Lines', '1')), point:=$geometry), 
 group_by:="fid")

NB: vous devrez changer 'Lines'votre nom de ligne réel et '1'l'identifiant de ligne que vous avez dans votre table d'attributs.

(3B) Créez un autre nouveau champ, appelons-le max_poly pour stocker la distance maximale et donner une expression:

maximum(
 line_locate_point(
  geometry:=geometry(get_feature_by_id('Lines', '1')), point:=$geometry), 
 group_by:="fid")

entrez la description de l'image ici

Étant donné que la couche Vertices conserve le champ fid des identifiants de polygone d'origine, vous trouverez que min_poly et max_poly est la distance minimale / maximale le long de la ligne pour chaque polygone.

(L'exemple ci-dessus montre que le premier polygone fid = 1 s'étend de 8,688 à 24,45, tandis que le deuxième polygone fid = 2 est de 35,062 à 42,496).

Kazuhito
la source
5

Je ne sais pas comment le faire avec QGIS ou ArcGIS mais ce que vous voulez ressemble à une largeur d'un cadre de délimitation orienté. Comme preuve de concept, j'ai fait pivoter votre échantillon d'image de sorte que la ligne de projection soit horizontale.

entrez la description de l'image ici

Ensuite, j'ai numérisé les polygones de l'image et généré des enveloppes pour eux. La largeur de l'enveloppe répond à votre question.

entrez la description de l'image ici

Ce qui manque, c'est un outil qui crée une boîte englobante à un angle donné. QGIS a un outil de boîte de délimitation minimale orientée mais l'utilisateur ne peut pas donner un angle fixe pour cela. Vous pourriez probablement adopter la solution PostGIS à partir de la réponse acceptée à cette question Créer un "cadre de délimitation oblique" avec un rapport largeur / hauteur maximum? .

user30184
la source
Cette réponse serait la meilleure approche car il est très facile d'obtenir un cadre de délimitation orienté dans QGIS (avec la largeur et la hauteur de l'enveloppe) mais les deux côtés de ce cadre de délimitation orienté doivent nécessairement être parallèles à la ligne de référence et cette condition n'est pas garantie . C'est le problème du polygone irrégulier.
xunilk
2

Sur la base de la réponse de @ kazuhito, j'ai rassemblé une seule expression hacky dans la calculatrice de champ QGIS qui devrait faire la même chose en une seule étape.

Cependant, je peux imaginer que cela nécessitera beaucoup de ressources sur de plus grands ensembles de données. Je pense que le problème est mieux adapté à une implémentation Python, qui gère évidemment le référencement et l'itération bien mieux que le Field Calculator.

array_last(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1)) 
- array_first(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1))

Cela crée d'abord un «tableau» de numéros de nœuds en utilisant generate_series(), en spécifiant le maximum comme le nombre de nœuds dans chaque polygone - c'est-à- num_points($geometry)dire moins 1 pour ignorer le premier / dernier nœud répété.

Vous pouvez ensuite passer les valeurs de ce tableau via une fonction pour générer un autre tableau à l'aide array_foreach(). Ici, nous transmettons le numéro de nœud du polygone (représenté par @element) à point_n(), qui renvoie la géométrie réelle de ce nœud, puis nous l'introduisons dans line_locate_point()pour déterminer sa longueur le long de la ligne spécifiée (voir la remarque importante ci-dessous).

Le tableau résultant est ensuite trié par ordre croissant en utilisant array_sort()ce qui nous permet ensuite d'obtenir les distances "les plus à gauche" et "les plus à droite" le long de la ligne en utilisant array_last()et array_first(). Soustrayez les deux et le résultat est la "longueur" du polygone le long de la ligne.

Voir ci-dessous pour un exemple de l'expression ci-dessus montrée comme une étiquette dans les polygones (plus les distances de ligne "les plus à gauche" et "les plus à droite" séparées de l'expression ci-dessus). Pour comparaison, j'ai également inclus des sommets extraits et des valeurs de distance de ligne pertinentes. Les sommets verts sont les sommets "les plus à gauche" et "les plus à droite" le long de la ligne. Notez le polygone en haut à gauche où le point vert est en fait plus loin le long de la ligne que le point à droite en dessous, en raison de l'angle de la ligne ...

Remarque importante :

La géométrie de la couche linéaire est référencée ici à l'aide de aggregate(). Vous aurez besoin de changer le nom de la couche ( 'lines') au besoin, et si vous avez plusieurs lignes, vous devez ajouter un filtre pour spécifier la ligne que vous voulez comparer avec, par exemple: aggregate('lines','collect',$geometry,"name"='TrainLine1'). Pour que cela fonctionne automatiquement sur la ligne la plus proche, je recommande vraiment SQL ou Python sur Field Calc.

En outre, cela calcule la "longueur" du polygone LE LONG de la ligne, y compris si la ligne est pliée selon mon exemple. Si vous voulez la distance en ligne droite ... peut-être calculer le distance()entre les nœuds pertinents?

entrez la description de l'image ici

she_weeds
la source
1

La meilleure approche dans QGIS pour ce faire (en considérant des milliers de polygones à "projeter" sur une ligne de référence) est de déterminer le cadre de délimitation tourné par l'angle entre la ligne de référence et l'axe X. Cet angle est facilement déterminé en utilisant l'outil Extraire les sommets (dans la boîte à outils de traitement QGIS -> Géométrie vectorielle) pour la ligne de référence. À partir de l'exemple de l'image suivante, l'angle requis est déterminé avec la valeur dans la table d' attributs de la couche Vertices en utilisant cette formule:

90 - 63,91873763467915 = 26,081262365320853 degrés.

entrez la description de l'image ici

Présentation de l'angle ci-dessus dans l'outil Rotation de la boîte à outils de traitement et exécution:

entrez la description de l'image ici

est produite une couche tournée dont le cadre de délimitation a dans son tableau d'attributs la longueur du polygone projeté sur la ligne de référence. On peut enfin l'observer en exécutant cet outil de Processing Toolbox:

entrez la description de l'image ici

Sur l'image suivante, la longueur du polygone projeté sur une ligne est la valeur trouvée dans la largeur du champ .

entrez la description de l'image ici

On peut observer à l'image suivante que la longueur projetée du polygone considéré, ce serait comme prévu car la ligne de référence tournée de 26,081262365320853 degrés (obtenue avec l'outil Rotation de Processing Toolbox) est parallèle à l'axe X.

entrez la description de l'image ici

xunilk
la source