Wie füge ich Richtung und Entfernung zur Attributtabelle hinzu?

18

Wer kann helfen. Ich möchte nur die Richtung (Peilung: N 25 35 E) und die Entfernung (Länge: 125 Meter) als mein neues Feld in den Polylinien- / Liniendaten hinzufügen. Gibt es ein Plug-In, um diese Felder zu generieren? Ich habe versucht, "Geometriespalten exportieren / hinzufügen" in meinen Liniendaten zu verwenden, aber es wurde nur der Wert "Länge" hinzugefügt.

arzandia
quelle
Bisher kann ich das mmqgis-Plugin verwenden, um mir Distanz zu geben. Erforsche das Richtungsproblem.
Willy
1
Wie sehen Ihre Polyliniendaten aus? Die Entfernung ist relativ einfach zu berechnen. Die Peilung kann sich jedoch über die Länge einer Polylinie ändern. Suchen Sie nach Peilung vom Startpunkt zum Endpunkt ?
Simbamangu
Ja,
ich bin auf der
1
Möchten Sie einen geradlinigen Abstand vom Startpunkt zum Endpunkt oder eine Länge der Linie, die dem Pfad der Linie folgt? Diese können stark variieren, wenn das Liniensegment Zwischenkurven oder andere Richtungsänderungen aufweist.
RyanDalton

Antworten:

42

Sie können die Peilung im Feldrechner in QGIS berechnen. Dies funktioniert in UTM-Koordinaten (metrisch) über kleine Entfernungen (Hunderte von Kilometern). Für große Entfernungen oder Dezimalgrade ist jedoch etwas Feineres erforderlich.

Öffnen Sie die Attributtabelle für Ihre Linienebene, schalten Sie die Bearbeitung ein und klicken Sie auf die Schaltfläche Feldrechner, um das Dialogfeld zu öffnen:

Bildbeschreibung hier eingeben

Erstellen Sie ein neues Feld als Dezimalzahl mit einer Genauigkeit von 1 oder 2.

Fügen Sie diesen Code in das Feld "Ausdruck" ein und klicken Sie auf "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)))

Der erste Teil berechnet den inversen Tangens der x- und y-Differenzen und rechnet ihn in Grad (180 / pi) um. Der zweite Teil addiert entweder 180 oder 360 zu der resultierenden Zahl, um eine Peilung von 0-360 ° zu erhalten.

Simbamangu
quelle
2
Eine sehr elegante Lösung, danke. Ich würde erwähnen, dass Sie, wenn Sie die Peilung für jedes Segment einer Polylinie bestimmen müssen, dies tun können, indem Sie das Linien-Shapefile mit dem Plug-In 'Split Feature' teilen. Laden Sie dann das neue (geteilte) Shapefile und folgen Sie der obigen Prozedur.
Nhopton
1
@arzandia - Beachten Sie, dass Sie QGIS 1.9 verwenden MÜSSEN (Beta-Downloads finden Sie auf der Homepage), da die Funktionen xat () und yat () in 1.7, das Sie verwenden, nicht funktionieren!
Simbamangu
Ich habe bereits das von Ihnen erwähnte Plug-In verwendet. Wie Sie das Bild sehen können, wird der Name der Ebene "aufgeteilt" ...
arzandia
1
Um meine eigene Frage zu beantworten: "Ja, Sie können Feldwerte für yat (0) / yat (-1) und xat (0) / xat (-1) einfügen."
Cbunn
1
Für mich musste ich einige Änderungen am Skript vornehmen, damit es funktioniert: (atan ((xat (0) -xat (1)) / (yat (0) -yat (1))) * 180 / 3.14159 + (180 * (((yat (0) - yat (1)) <0) + (((xat (0) - xat (1)) <0 AND (yat (0) - yat (1))> 0) * 2)))
oskarlin
21

Sie brauchen kein Plugin. Alles ist in der Klasse QgsPoint von PyQGIS

Wenn Sie den Inhalt einer QGIS-Punktklasse mit der in Python integrierten Funktion dir () in der Python-Konsole untersuchen.

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']

Sie können sehen, dass es Azimut- und sqrDist- Funktionen gibt. Nach einigen Versuchen:

- 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)

Das Problem Bildbeschreibung hier eingeben

Also in der Python-Konsole

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()

Jetzt enthält xy alle Knoten (Punkte) der Linie

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

Verwenden aller Knotenpunkte der Linie:

1) Azimutpunkt i bis Punkt i + 1 (+/- 180 °) (Knoten einer Linie)

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) euklidischer Abstand zwischen Punkt i und Punkt 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
[...]

Danach ist es nicht sehr schwierig, diese Werte zur Attributtabelle hinzuzufügen.

Ich verwende diese Technik, um die Linien (Geologie) mit matplotlib und dem Script Runner Plugin zu analysieren

Bildbeschreibung hier eingeben

Gen
quelle
5
+1 - Schöne Lösung! Muss ... lernen ... Python ...
Simbamangu
Dies ist eine großartige Lösung und super wertvoll für Geologen .. aber auch sooo kompliziert
Shawn
10

Die von @Simbamangu bereitgestellte Lösung ist ziemlich effektiv, deckt jedoch nicht alle Fälle ab. Wenn Sie beispielsweise die Formel mit einer horizontalen Verschiebung anwenden, wird das Ergebnis NULL. Sie müssen diese Formel daher im Feldrechner von QGIS verwenden

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
quelle