Comment ajouter la direction et la distance à la table attributaire?

18

toute personne qui peut aider. je veux juste ajouter la direction (relèvement: ie N 25 35 E) et la distance (longueur: 125 mètres) comme mon nouveau champ dans les données de polyligne / ligne. existe-t-il un plug-in pour générer ces champs? J'ai essayé d'utiliser "exporter / ajouter des colonnes de géométrie" dans mes données de ligne, mais seule la valeur "Longueur" a été ajoutée.

arzandia
la source
Jusqu'à présent, je peux utiliser le plugin mmqgis pour me donner de la distance. J'explore le problème de la direction.
Willy
1
À quoi ressemblent vos données de polyligne? La distance est relativement facile à calculer - cependant, le «relèvement» peut changer sur la longueur d'une polyligne. Vous cherchez roulement du point de départ au point final ?
Simbamangu
Oui, je cherche un relèvement du point de départ au point d'arrivée ... merci
arzandia
1
Voulez-vous une distance en ligne droite du point de départ au point final, ou une longueur de ligne suivant le chemin de la ligne? Celles-ci pourraient varier considérablement si le segment de ligne a des courbes intermédiaires ou d'autres changements de direction.
RyanKDalton-OffTheGridMaps

Réponses:

42

Vous pouvez calculer le relèvement dans le calculateur de champ dans QGIS. Cela fonctionne en coordonnées UTM (métriques) sur de petites distances (centaines de km), mais quelque chose de plus sophistiqué serait nécessaire pour les grandes distances ou pour les degrés décimaux.

Ouvrez la table attributaire de votre calque de ligne, basculez l'édition et cliquez sur le bouton Calculatrice de champ pour ouvrir la boîte de dialogue:

entrez la description de l'image ici

Créez un nouveau champ décimal avec une précision de 1 ou 2.

Collez ce code dans la case "Expression" et cliquez sur "OK": (atan((xat(-1)-xat(0))/(yat(-1)-yat(0)))) * 180/3.14159 + (180 *(((yat(-1)-yat(0)) < 0) + (((xat(-1)-xat(0)) < 0 AND (yat(-1) - yat(0)) >0)*2)))

La première partie calcule la tangente inverse des différences x et y et la convertit en degrés (180 / pi). La deuxième partie ajoute 180 ou 360 à la figure résultante pour donner un relèvement de 0 à 360 °.

Simbamangu
la source
2
Une solution très élégante, merci. Je mentionnerais que si vous avez besoin de déterminer le relèvement pour chaque segment d'une polyligne, vous pouvez le faire en divisant le fichier de formes de ligne avec le plug-in 'Split Feature'. Chargez ensuite le nouveau fichier de formes (fractionné) et suivez la procédure ci-dessus.
nhopton
1
@arzandia - notez que vous DEVEZ utiliser QGIS 1.9 (voir la page d'accueil pour les téléchargements bêta) car les fonctions xat () et yat () ne fonctionnent pas en 1.7, que vous utilisez!
Simbamangu
j'ai déjà utilisé le plug-in que vous avez mentionné. comme vous pouvez le voir sur l'image, le nom du calque est "split" ...
arzandia
1
Pour répondre à ma propre question, «Oui, vous pouvez insérer des valeurs de champ pour yat (0) / yat (-1) et xat (0) / xat (-1)».
cbunn
1
Pour moi, j'ai dû apporter quelques modifications au script pour le faire fonctionner: (atan ((xat (0) -xat (1)) / (yat (0) -yat (1)))) * 180 / 3.14159 + (180 * (((yat (0) -yat (1)) <0) + (((xat (0) -xat (1)) <0 ET (yat (0) - yat (1))> 0) * 2)))
oskarlin
21

Vous n'avez pas besoin d'un plugin. Tout est dans la classe QgsPoint de PyQGIS

Si vous examinez le contenu d'une classe de points QGIS avec la fonction intégrée Python dir () dans la console Python.

dir(point])
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__'
, '__getitem__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'azimuth', 
'multiply', 'set', 'setX', 'setY', 'sqrDist', 'sqrDistToSegment', 'toDegreesMinutesSeconds', 'toString', 'wellKnownText', 'x', 'y']

Vous pouvez voir qu'il existe des fonctions azimut et sqrDist et après quelques essais:

- xy[0].azimuth(xy[1]) or xy[1].azimuth(xy[0]) gives the azimuth direction between two points(in degrees, +/- 180°)
- xy[0].sqrDist(xy[1]) give the square distance between two points (in the unit of the project)

Le problème entrez la description de l'image ici

Donc, dans la console Python

def select_all(layer):
     layer.select([])
     layer.setSelectedFeatures([obj.id() for obj in layer])

myline = qgis.utils.iface.activeLayer()
select_all(myline)
for elem in myline.selectedFeatures():
      xy = elem.geometry().asPolyline()

maintenant xy contient tous les nœuds (points) de la ligne

# first point
print "x=%2d y=%2d" % (xy[0].x(),xy[0].y())
x=112935 y=117784
# and others...

En utilisant tous les points nodaux de la ligne:

1) point d'azimut i au point i + 1 (+/- 180 °) (nœuds d'une ligne)

for i in range(len(xy)-1):
     print "x=%2d y=%2d azim=%6.1f azim2=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].azimuth(xy[i+1]), xy[i+1].azimuth(xy[i]))

x=112935 y=117784 azim= 168.4 azim2= -11.6
x=113032 y=117312 azim=-167.5 azim2=  12.5
x=112926 y=116835 azim= 177.3 azim2=  -2.7
x=112943 y=116472 azim= 145.1 azim2= -34.9
[...]

2) Distance euclidienne entre le point i et le point i + 1

for i in range(len(xy)-1):
     print "x=%2d y=%2d dist=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].sqrDist(xy[i+1]))

x=112935 y=117784 dist=232533.9
x=113032 y=117311 dist=238243.6
x=112926 y=116835 dist=131839.8
x=112943 y=116472 dist=209268.1
[...]

Après, il n'est pas très difficile d'ajouter ces valeurs à la table attributaire.

J'utilise cette technique pour analyser les linéaments (géologie) avec matplotlib et le plugin Script Runner

entrez la description de l'image ici

gène
la source
5
+1 - Bonne solution! Doit ... apprendre ... Python ...
Simbamangu
Ceci est une excellente solution et super utile pour les géologues .. mais aussi tellement compliqué
Shawn
10

La solution fournie par @Simbamangu est assez efficace mais ne couvre pas tous les cas. Par exemple, l'application de la formule avec un déplacement horizontal NULL le résultat, vous devez donc utiliser cette formule dans Field Calculator of QGIS

case
when yat(-1)-yat(0) < 0 or yat(-1)-yat(0) > 0 then 
(atan((xat(-1)-xat(0))/(yat(-1)-yat(0)))) * 180/3.14159 + 
(180 *
(((yat(-1)-yat(0)) < 0) + 
(((xat(-1)-xat(0)) < 0 AND (yat(-1) - yat(0)) >0)*2)
))
when ((yat(-1)-yat(0)) = 0 and (xat(-1) - xat(0)) >0) then 90
when ((yat(-1)-yat(0)) = 0 and (xat(-1) - xat(0)) <0) then 270
end
Sergio
la source