QGIS에서 여러 점을 선에 맞추시겠습니까?


11

선 객체 주위에 지정된 공차 또는 버퍼를 사용하여 여러 점을 선 또는 레이어 내의 선에 정렬하고 싶습니다. 첨부 된 샘플 스케치를 참조하십시오.

이 예제를 위해 BEFORE 그림에서 선에 가장 가까운 점은 선의 5 개 맵 단위 내에 있고 가장 바깥 쪽 점은 10 개가 넘는 맵 단위입니다. AFTER 사진의 결과를 얻기 위해 5 개의지도 단위의 공차를 사용하여 가장 가까운 선에 가장 가까운 점을 스냅하고 싶습니다.

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


따라서 점은 선의 측면으로 0 개의지도 단위 여야하지만 점의 원래 위치와 관련하여 점이 선의 세로 방향으로 끝나는 위치에 신경을 씁니까?
Joe

이상적인 시나리오는 선에 수직 경로를 사용하여 점을 이동하는 것입니다. 그러나 의도는 상당히 작은 공차를 사용하는 것입니다. 점들이 종 방향 또는 위도 방향으로 선을 향하여 이동되면, 바람직한 수직 위치로부터 점들을 크게 상쇄하지 않을 것이다.
Ed Camden

이것이 최선의 방법인지 확실하지 않지만 내가 생각할 수있는 한 가지 방법은 파이썬 코드를 작성하여 두 데이터 세트를 분석하고 점 좌표를 생성하는 것입니다. 이것이 당신이 원하는 것이라고 생각한다면, 저에게 알려주십시오. 나는 당신에게 답을 줄 수 있습니다. 예를 들어 lat의 절대 값이 라인 <= 5 단위에서 먼 거리 = 0 인 경우 모든 포인트에 대해 x, y 값을 좌표로 변환하려면 gdal 라이브러리를 가져와야합니다. gis.stackexchange.com/questions/185445/…
Joe

PyQGIS를 사용하면 이전에 고려한 5 맵 단위의 공차와 선과의 수직 경로에 따라 점이 스냅되는 메모리 레이어를 생성 할 수 있습니다. 내 대답을 참조하십시오.
xunilk

답변:


15

(출시되지 않은) QGIS 3.0 버전에는이를위한 도구가 내장되어 있습니다. QGIS 웹 사이트에서 야간 스냅 샷을 가져와 미리 테스트 할 수 있습니다.

이것을하기 위해:

  1. "Snap geometry to layer"프로세싱 알고리즘 실행
  2. 포인트 레이어를 "입력 레이어"로 선택하십시오
  3. 선 레이어를 "참조 레이어"로 선택
  4. 적절한 공차를 입력합니다 (스냅하는 동안 포인트를 이동할 최대 거리)
  5. 동작을 "가장 가까운 지점 선호"로 변경

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

다음은 원래 점을 "x"로, 스냅 된 점을 녹색 점으로 표시하는 결과입니다. 여기에서는 일부 입력 포인트 만 스냅되도록 공차를 사용했습니다.

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


이것이 바로 내가 필요한 것입니다. 불행히도 고용주는 LTR 버전의 QGIS 만 설치하며 테스트 버전 다운로드 및 설치가 제한됩니다. (한숨) 기다릴 문제라고 생각합니다. 이것이 표준 / 내장 기능입니까 아니면 플러그인입니까?
Ed Camden

c ++ 클래스의 변경 사항에 의존하는 표준 기능-수동으로이를 이전 버전으로 복사 할 수있는 방법이 없습니다. 다른 시스템에서 OSGEO4W를 사용하여 설치 한 다음 osgeo4w 폴더를 USB 스틱에 복사하여 워크 스테이션에서 실행할 수 있습니다. 나는 과거에 그 접근 방식으로 운이 좋았습니다.
ndawson

1
이전 버전의 경우이 플러그인을 살펴보십시오. docs.qgis.org/2.14/en/docs/user_manual/plugins/…
iRfAn

플러그인이 포인트의 레이어를 지원하지 않는 것 같습니다.
Mykola Kozyr

7

이것은 PyQGIS 와 함께 제공 될 수 있습니다 . 다음 상황의 경우 :

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

QGIS의 Python 콘솔에서 5 개의지도 단위 허용 오차를 고려한 다음 코드가 실행되었습니다.

from math import sqrt

registry = QgsMapLayerRegistry.instance()

points = registry.mapLayersByName('points')
line = registry.mapLayersByName('line')

feat_points = [ feat for feat in points[0].getFeatures() ]
feat_line = line[0].getFeatures().next()

new_points = []

for feat in feat_points:
    pt = feat.geometry().asPoint()
    sqrdist, point, vertex = feat_line.geometry().closestSegmentWithContext(pt)
    if sqrt(sqrdist) <= 5:
        new_points.append(point)
    else:
        new_points.append(pt)

epsg = points[0].crs().postgisSrid()

uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'new_points',
                           'memory')

prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(len(new_points)) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromPoint(new_points[i]))

prov.addFeatures(feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

이전에 고려 된 5 개의지도 단위의 공차와 선에 대한 수직 경로에 따라 점이 스냅되는 메모리 레이어가 생성되었습니다.

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


2

refFunctions 플러그인을 사용하여 필드 계산기에서이를 수행 할 수도 있습니다. 필드 계산기를 사용하여 레이어 지오메트리 및 필드를 업데이트 할 수 있습니다. refFunctions는 주어진 거리 내에서 가장 가까운 선 (또는 임계 값을 원하지 않는 경우 "geomnearest")을 찾을 수있는 "geomdistance"함수를 제공하고 속성 또는 지오메트리를 반환하며 "closest_point"함수는 가장 가까운 것을 찾습니다 주어진 지오메트리를 가리 킵니다. 포인트 레이어의 새 형상을 계산하려면 다음과 같이 함께 묶으십시오.

closest_point(geom_from_wkt(geomdistance('snap_lines','$geometry',10)) , $geometry)

지오메트리를 직접 업데이트하는 대신 스냅 된 지오메트리로 필드를 계산할 수 있습니다. 암거 지점을 다른 스트림 레이어에 스냅하기위한 여러 형상을 저장하고 사용해야하는 스트림 라인에 따라 필드 계산기에서 포인트 형상을 쉽게 업데이트 할 수 있습니다.

여기에는 몇 가지 제한 사항이 있습니다. 두 레이어 모두 동일한 CRS 여야하며 geomdistance 함수는 포인트가 10 만개 이상인 경우 오류를 표시하지만 refFunctions 플러그인 파일을 편집하면이 제한을 변경할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.