属性テーブルに方向と距離を追加する方法は?


18

助けることができる人。ポリライン/ラインデータの新しいフィールドとして、方向(方位:N 25 35 E)と距離(長さ:125メートル)を追加したいだけです。これらのフィールドを生成するプラグインはありますか?ラインデータで「ジオメトリ列のエクスポート/追加」を使用しようとしましたが、「長さ」値のみが追加されました。


これまでのところ、距離を与えるためにmmqgisプラグインを使用できます。方向の問題を調査しています。
ウィリー

1
ポリラインデータはどのように見えますか?距離の計算は比較的簡単ですが、「方位」はポリラインの長さにわたって変化する場合があります。始点から終点までの方位をお探しですか?
シンバマング

はい、開始点から終了点までのベアリングを探しています...ありがとう
アルザンディア

1
始点から終点までの直線距離、または線の経路に沿った線の長さを希望しますか?これらは、線分に中間曲線または他の方向の変化がある場合、大きく異なる可能性があります。
RyanKDalton-OffTheGridMaps

回答:


42

QGISのフィールド計算機で方位を計算できます。これは、短い距離(数百km)のUTM(メートル法)座標で機能しますが、長距離または小数度の場合は、より高度なものが必要になります。

ラインレイヤーの属性テーブルを開き、編集を切り替え、[フィールド計算機]ボタンをクリックしてダイアログを開きます。

ここに画像の説明を入力してください

1または2の精度を持つ10進数として新しいフィールドを作成します。

このコードを「式」ボックスに貼り付けて、「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)))

最初の部分は、xとyの差の逆正接を計算し、度(180 / pi)に変換します。2番目の部分は、結果の図に180または360を追加して、0〜360°の方位を与えます。


2
最もエレガントなソリューション、ありがとう。ポリラインの各セグメントの方位を決定する必要がある場合は、 'Split Feature'プラグインでラインシェープファイルを分割することでこれを行うことができます。次に、新しい(分割)シェープファイルをロードし、上記の手順に従います。
nhopton

1
@arzandia- xat()およびyat()関数は使用している1.7では機能しないため、QGIS 1.9(ベータ版ダウンロードのホームページを参照)を使用する必要があることに注意してください!
シンバマング

既に述べたプラグインを使用しました。あなたが画像を見ることができるように、層の名前は...「分割される」
arzandia

1
私自身の質問に答えるために、「はい、yat(0)/ yat(-1)およびxat(0)/ xat(-1)のフィールド値を挿入できます。」
cbunn

1
私にとっては、スクリプトを動作させるためにいくつかの変更を行う必要がありました:(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)))
オスカーリン

21

プラグインは必要ありません。すべてがPyQGISのクラスQgsPointにあります

PythonコンソールでPython組み込み関数dir()を使用してQGISポイントクラスの内容を調べる場合。

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

あなたはあります見ることができ、方位sqrDist機能は、いくつかの試行後:

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

問題 ここに画像の説明を入力してください

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

xyには、ラインのすべてのノード(ポイント)が含まれています

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

線のすべてのノードポイントを使用:

1)方位角ポイントiからポイントi + 1(+/- 180°)(ラインのノード)

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)点iと点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
[...]

その後、これらの値を属性テーブルに追加することはそれほど難しくありません。

この手法を使用して、matplotlibとScript Runnerプラグインでリニアメント(地質)を分析します

ここに画像の説明を入力してください


5
+1-素晴らしい解決策!する必要があります...学ぶ... Python
...-シンバマング

これは優れた解決策であり、地質学者にとっては非常に貴重なものですが、非常に複雑です
ショーン

10

@Simbamanguが提供するソリューションは非常に効果的ですが、すべてのケースをカバーしているわけではありません。たとえば、水平方向のずれのある数式を適用すると結果がNULLになるため、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.