QGIS에서 폴리곤 마스크를 사용하여 특정 레이어 스타일링?


10

QGIS에 선 레이어와 다각형 레이어가 있습니다.

마스크 전

하나의 스타일을 사용하여 다각형 외부의 선 레이어 부분의 스타일을 지정하고 다른 스타일을 사용하여 내부의 부분 스타일을 지정하고 싶습니다.

마스크 후

파생 데이터 세트를 생성하고 싶지 않습니다 (예 : 선 레이어를 클립하고 두 부분의 스타일을 지정하십시오.

이것은 간단한 경우이지만 QGIS 프로젝트에는 +30 개의 레이어가 있으므로 레이어 블렌딩이 기본 레이어를 방해한다고 생각합니다.

이런 식으로 할 수 있습니까?

다각형 레이어를 표시하고 싶지 않습니다. 내가하고 싶은 것을 시각화하기 위해 여기 있습니다.


1
좋은 방법! 나는 그것이 질문에 대한 편집 대신 답변 으로 게시되어야한다고 생각합니다 :)
Joseph

@Joseph, 끝났어!
Chau

답변:


11

완벽한 솔루션은 아니지만 교차점을 나타내는 시각화 된 선을 추가하는 Geometry Generator 를 사용할 수 있습니다 . 그런 다음 이것을 원래 선 피처와 겹치도록 설정할 수 있습니다.

더하기 부호를 클릭하여 새 심볼 레이어를 추가하고 Geometry generator심볼 레이어 유형으로를 선택하십시오 . 지오메트리 유형을로 설정하고 LineString / MultiLineString다음 표현식을 사용하십시오.

intersection($geometry, geometry(get_feature( 'polygonLayer','fieldName','value'))) 

다음 위치에서 특정 다각형에 대한 세부 사항을 추가해야합니다.

  • polygonLayer 다각형 레이어의 이름입니다
  • fieldName 필드의 이름입니다
  • value 특정 다각형의 기능 값입니다

스타일 속성

시각적 선의 색상을 지정하려면 그리기 효과 속성 에서이를 수행해야 할 수 있습니다.

그리기 효과 속성

결과는 (비주얼 선이 원래 선과 완전히 겹치지 않았으므로 오프셋을 약간 수정 한 것입니다.)

결과

그리고 다각형없이 :

다각형이없는 결과



편집하다:

다각형 피처를 교차하는 각 선 피처에 이것을 적용하려면 함수 편집기 로 이동 하여 다음 함수를 사용 polygon example_2하십시오 (폴리곤 레이어의 이름과 일치하도록 이름 변경 ).

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def func(feature, parent):
    polygon_layer = QgsMapLayerRegistry.instance().mapLayersByName( "polygon example_2" )[0]
    feat_list = []
    geoms = QgsGeometry.fromWkt('GEOMETRYCOLLECTION()')
    for polygon_feat in polygon_layer.getFeatures():
        if feature.geometry().intersects(polygon_feat.geometry()):
            intersection = feature.geometry().intersection(polygon_feat.geometry())
            feat_list.append(intersection)
    for x in feat_list:
        geoms = geoms.combine(x)
    return geoms

기능 편집기

로드 를 클릭 한 다음 표현식 탭으로 이동 하여을 입력하십시오 func(). 결과는 다음과 같아야합니다 (위에서 언급 한 것과 동일한 스타일 속성 사용).

최종 결과


나는 실제로 그것을 보았지만 발견했을 때 멈추었습니다 get_feature. 필드 이름과 값 이 필요합니다. 방금 다각형 레이어가 있고 해당 레이어의 모든 기능을 사용하여 마스크 처리하고 싶습니다. 가능합니까?
Chau

@Chau-가능한 방법을 포함하도록 게시물 수정 :)
Joseph

1
다른 옵션은 다각형 레이어를 녹이는 것입니다.
csk

1
@Joseph-a를 사용할 때 스타일 지정에 사용되는 레이어의 모든 기능에 대해 Geometry Generator메소드가 func호출됩니까? 내 선 레이어에 3 개의 피처가있는 경우 func3 번이라고하고 같은 결과를 3 번 ​​그리는가?
Chau

1
@Chau-당신이 옳았다 고 생각합니다. 코드는 각 기능을 여러 번 반복했습니다. 게시물을 편집하여 func각 라인 기능마다 호출해야하며 결과는 한 번만 그려집니다 (이것은 내가 놓친 아래에 숨겨지기 전에 다각형 내부의 정점 마커로 표시되는 것처럼 보입니다). 이것을 지적 해 주셔서 감사합니다 :)
Joseph Joseph

3

Joseph 의 대답을 확장 하면서이 기능을 생각해 냈습니다. 다른 좌표계를 설명하기 때문에 두 개의 마스킹 레이어를 찾아야하므로 처리합니다. 또한 다각형 내부의 선이나 다각형 외부의 선을 마스크 할 수 있기를 원했습니다.

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

@qgsfunction(args='auto', group='Custom')
def mask_line_with_polygon(mask_type, line_layer_name, polygon_layer_name_1, polygon_layer_name_2, feature, parent):
    line_layer = QgsMapLayerRegistry.instance().mapLayersByName( line_layer_name )[0]

    # This is the geometry outside the polygon mask.
    outside = QgsGeometry(feature.geometry())

    polygon_layer_names = [polygon_layer_name_1, polygon_layer_name_2]
    line_feature_extent = outside.boundingBox()

    geoms = QgsGeometry.fromWkt('MultiLineString()')

    for polygon_layer_name in polygon_layer_names:
        if polygon_layer_name is None or len(polygon_layer_name) == 0:
            continue

        # If the line and the polygon layers have different projections, handle them here.
        polygon_layer = QgsMapLayerRegistry.instance().mapLayersByName(polygon_layer_name)[0]
        trs = QgsCoordinateTransform(line_layer.crs(), polygon_layer.crs())
        polygon_extent = trs.transform(line_feature_extent)
        trs = QgsCoordinateTransform(polygon_layer.crs(), line_layer.crs())

        # Go through the features in the polygon layer, but only those within the line feature bounding box.
        for feature in polygon_layer.getFeatures(QgsFeatureRequest().setFilterRect(polygon_extent)):
            polygon_geometry = QgsGeometry(feature.geometry())

            # Transform the polygon to line space.
            polygon_geometry.transform(trs)

            if outside.intersects(polygon_geometry):
                if mask_type.lower() == 'outside':
                    inside = outside.intersection(polygon_geometry)

                    if inside.isMultipart():
                        for x in inside.asMultiPolyline():
                            geoms.addPart(x)
                    else:
                        geoms.addPart(inside.asPolyline())

                outside = outside.difference(polygon_geometry)

    if mask_type.lower() == 'inside':
        if outside.isMultipart():
            for x in outside.asMultiPolyline():
                geoms.addPart(x)
        else:
            geoms.addPart(outside.asPolyline())

    return geoms

이 연습에서는 QGIS가 대용량 데이터 세트를 사용하는 것을 좋아하지 않으며 QGIS를 사용하는 알고리즘이 너무 자주 충돌하는 것으로 나타났습니다. QGIS 렌더러가 시간이 많이 걸리는 Geometry Generator를 렌더링하는 것을 좋아하지 않는 것 같습니다.

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