속성 테이블에 방향 및 거리를 추가하는 방법은 무엇입니까?


18

도울 수있는 사람. 폴리 라인 / 라인 데이터의 새 필드로 방향 (베어링 : 즉 N 25 35 E)과 거리 (길이 : 125 미터)를 추가하고 싶습니다. 이러한 필드를 생성하는 플러그인이 있습니까? 라인 데이터에 "내보내기 / 추가 형상 열"을 사용하려고했지만 "길이"값만 추가되었습니다.


지금까지 mmqgis 플러그인을 사용하여 거리를 좁힐 수 있습니다. 방향 문제를 탐색 중입니다.
Willy

1
폴리 라인 데이터는 어떤 모양입니까? 거리는 상대적으로 계산하기 쉽지만 '베어링'은 폴리 라인 길이에 따라 변경 될 수 있습니다. 시작점 에서 끝점 까지 베어링을 찾고 있습니까?
Simbamangu

예, 시작점에서 끝점까지 베어링을 찾고 있습니다 ... 감사합니다
arzandia

1
시작점에서 끝점까지 직선 거리 또는 선 경로를 따르는 선 길이를 원하십니까? 선분에 중간 곡선 또는 다른 방향 변경이있는 경우에는 크게 달라질 수 있습니다.
RyanKDalton-OffTheGridMaps

답변:


42

QGIS의 필드 계산기에서 베어링을 계산할 수 있습니다. 이것은 작은 거리 (수백 km)에 걸쳐 UTM (미터법) 좌표에서 작동하지만 먼 거리 나 10 진수 각도에는 더 정교한 것이 필요합니다.

선 레이어의 속성 테이블을 열고 편집을 토글 한 다음 필드 계산기 버튼을 클릭하여 대화 상자를 엽니 다.

여기에 이미지 설명을 입력하십시오

1 또는 2 정밀도로 10 진수로 새 필드를 만듭니다.

이 코드를 "표현식"상자에 붙여넣고 "확인"을 클릭하십시오. (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)로 변환합니다. 두 번째 부분은 결과 그림에 180 또는 360을 더하여 0-360 °의 베어링을 제공합니다.


2
가장 우아한 솔루션입니다. 감사합니다. 폴리 라인의 각 세그먼트에 대한 베어링을 결정해야하는 경우 선 모양 파일을 '분할 피쳐'플러그인으로 분할하여이 작업을 수행 할 수 있습니다. 그런 다음 새 (분할) 셰이프 파일을로드하고 위 절차를 따릅니다.
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)))
oskarlin

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)

문제 여기에 이미지 설명을 입력하십시오

파이썬 콘솔에서

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-좋은 해결책! 필수 ... 배우기 ... 파이썬 ...
Simbamangu

이것은 지질 학자들에게는 훌륭한 해결책이자 매우 가치있는 일입니다 .. 또한 복잡한 sooo
Shawn

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.