해결된 질문
작성
·
364
1
qgis에서 차량의 주행데이터(point)와 표준노드링크의 링크(line)의 필드 속성을 결합시키고자 합니다.
그런데 차량데이터의 heading 값과 링크의 heading값을 오차 범위 내에서 고려하여,
차량데이터 필드에 오차 범위 내의 가장 가까운 링크 아이디를 넣는 것이 목표입니다.
그래서 heading값의 오차범위가 조건이 되어서 속성을 결합하는 것이 필요할 것 같은데
혹시 방법을 아시나요...?
공간 처리 툴박스를 이용하고 싶은데 '최근접 거리를 이용하여 속성을 결합' 과 같이 위치적인 것만 고려하는 기능만 보여서요 ㅠㅠ
표현식이나 파이썬이나 플러그인이나 혹시 방법이 있을까요..?
답변 3
1
네 그럼 지난번 보내주신 자료를 바탕으로 한 코드를 작성하여 공유드립니다.
코드 실행에 앞서, 아래 코드 중 input_1, input_2 변수의 경로를 확인 후 아무것도 불러오지 않은 QGIS 창에서 실행을 부탁드립니다.
input_1은 제공해주신 point 자료의 경로가 되도록, input_2는 line 자료의 경로로 수정하시면 됩니다.
코드 작동에 대해 설명을 드리면,
우선 최근접 이웃 수가 2 (neighbors = 2)가 되도록 최근접 속성 결합을 시행합니다.
그렇게 하면, line id 1, 2에 대한 정보가 point에 결합되며 이 때 결과물의 피처 수는 40개 (원본 point 피처 수 * 2)가 됩니다.
그 이후, point 자료의 heading 필드와, 결합된 line 자료의 azimuth_ 필드의 차이의 절댓값을 계산합니다.
계산값이 50보다 클 경우 (오차 범위를 벗어났다고 간주되는 경우), 해당 피처를 삭제하고, 최종적으로 해당 수정이 적용된 레이어를 shp 파일로 저장합니다.
결과적으론 20개의 피처만 결과물로 저장이 되고, 속성을 확인해보시면 id_2 (line 자료에서 결합된 id 속성)가 모두 1로 정상 결합 되어 있는 것을 확인할 수 있습니다.
추가적인 질문이 있다면 답글 부탁드립니다!!
-UPWISE 답변-
import processing
import os
#processing.algorithmHelp('native:joinbynearest')
# 최근접 변수 설정
input_1 = 'C:/shp/point.shp'
input_2 = 'C:/shp/line.shp'
neighbors = 2
output_join = 'memory:output_joinbynearest'
# 최근접 파라미터
joinbynearestParams = {'INPUT' : input_1, 'INPUT_2' : input_2, 'NEIGHBORS' : neighbors, 'OUTPUT' : output_join}
# 최근접 실행
joinbynearest = processing.run('native:joinbynearest', joinbynearestParams)
# 최근접 결과 레이어 추가
QgsProject.instance().addMapLayer(joinbynearest['OUTPUT'])
# 추가된 레이어 변수로 불러오기 및 수정 활성화
layer = iface.activeLayer()
layer.startEditing()
# attribute 를 통해 heading 과 azimuth 차이 절댓값 계산 및 오차 범위 외 필드 제거 (절댓값 50 이상)
for f in layer.getFeatures():
diff_abs = abs(f['heading'] - f['azimuth_'])
if diff_abs > 50:
layer.deleteFeature(f.id())
# 레이어 수정 적용 및 파일 저장
layer.commitChanges()
QgsVectorFileWriter.writeAsVectorFormat(layer,'C:/shp/output_joinbynearest.shp','utf-8',driverName='ESRI Shapefile')
1
안녕하세요. UPWISE 입니다.
지난번 자료를 공유해 주신 이후, 자료를 살펴보았습니다.
제공 주신 자료를 토대로 현재 가장 간단하게 해당 분석을 수행할 수 있는 방법은 아래와 같습니다.
1. "최근접 거리를 이용하여 속성을 결합" 기능 사용 시 "최대 최근접 이웃 수"를 2 이상으로 하여 인근의 다수의 line 정보를 결합 (이 경우, 결과물의 피처 수는 [point 피처 수 * "최대 최근접 이웃 수" 설정 값] 만큼 도출됨)
2. 결과물의 속성 테이블에서 point의 "heading" 필드와 결합된 line의 "azimuth" 필드의 오차 범위를 비교하여 유효한 피처만 선택 (각도 오차 범위 ± 15도 등)
위 방법은 pyqgis 코드 작성을 통해 간단히 자동화가 가능합니다.
다만 제가 우려되는 점은 전체 원본 데이터가, 제공해주신 데이터 만큼 간단하게 구성되어 있는지 입니다.
아마 경로 line의 길이도 훨씬 길고 line 자체도 곡선형일 것으로 예상됩니다.
또한, point의 수와 line 으로 부터의 거리도 더 다양할 것 같은데, 이런 경우에는 line 개체를 개별 shp으로 쪼갠 뒤, 분석을 진행하는 등의 다른 방법을 모색해봐야 할 것 같습니다.
만약 현재 제공해주신 데이터를 바탕으로 한 분석 코드 제공을 원하신다면, 작성 후 공유 드려보도록 하겠습니다.
감사합니다.
-UPWISE 답변-
1
안녕하세요. UPWISE 입니다.
우선 제 강의를 수강해주셔서 감사합니다.
그리고 양해의 말씀을 먼저 드리면, 제가 다음주까지 처리해야하는 일들이 몰려있어서 질문주신 사항을 빠르게 확인하기가 어려울 것 같습니다. 물론 중간에 시간이 있다면 바로 답변 드릴 수 있겠지만, 늦어질 가능성이 있어서 말씀을 드립니다.
질문해주신 내용에선 "오차 범위 내에서 고려" 라고 말씀해주셨는데, 오차 범위가 무엇을 뜻하는 것인가요?
저는 차량 주행데이터 포인트와 주변의 여러 링크 라인 중, 가장 가까운 라인의 속성을 포인트에 결합해야 하는 것으로 이해하였는데, 혹시나 다른 방법으로 분석이 되어야 하는 것이라면 말씀 부탁드립니다.
그리고 가능하시다면, 사용하시는 데이터 (혹은 일부 샘플)를 카카오톡 오픈채팅으로 공유해주시면 훨씬 쉽게 답변을 드릴 수 있을 것 같습니다. 데이터 공유가 어려우시다면, 시각적인 정보를 확인할 수 있도록 GIS 화면을 캡처해주셔도 좋을 것 같습니다.
다시 한 번 답변이 늦어질 수 있음에 대한 양해의 말씀을 드리며, 저도 최대한 빠르게 답변 드릴 수 있도록 하겠습니다.
감사합니다.
-UPWISE 답변-
답변 주셔서 감사합니다. 전체 데이터는 곡선이고 긴 것이 맞습니다. 우선은 선생님께서 알려주시는 코드를 기반으로 제가 한번 진행해보고 싶습니다. 이후에 어려운 것이 생기면 한번 더 질문을 드려도 될까요?