Tạo kiểu lớp cụ thể bằng cách sử dụng mặt nạ đa giác trong QGIS?


10

Tôi có một lớp dòng và một lớp đa giác trong QGIS:

Trước khi đắp mặt nạ

Tôi muốn tạo kiểu cho một phần của lớp đường bên ngoài đa giác bằng một kiểu và phần bên trong sử dụng một kiểu khác:

Sau khi đắp mặt nạ

Tôi không muốn tạo một tập dữ liệu phái sinh, ví dụ. clip lớp đường và phong cách hai phần.

Đây là một trường hợp đơn giản nhưng trong dự án QGIS của tôi, tôi có +30 lớp nên tôi nghĩ rằng bất kỳ lớp trộn nào cũng sẽ làm xáo trộn các lớp bên dưới.

Có thể làm một cái gì đó như thế này?

Tôi không muốn hiển thị lớp đa giác, nó chỉ ở đây để hình dung những gì tôi muốn làm.


1
Phương pháp tốt đẹp! Tôi nghĩ rằng nên được đăng dưới dạng câu trả lời thay vì chỉnh sửa câu hỏi :)
Joseph

@Joseph, xong rồi!
Châu

Câu trả lời:


11

Không phải là một giải pháp hoàn hảo nhưng bạn có thể sử dụng Trình tạo hình học để thêm một đường trực quan để thể hiện giao lộ. Sau đó, bạn có thể đặt điều này để chồng lấp tính năng dòng gốc.

Thêm một lớp biểu tượng mới bằng cách nhấp vào dấu cộng và chọn Geometry generatorloại lớp biểu tượng. Đặt loại Geoemtry thành LineString / MultiLineStringvà sử dụng biểu thức sau:

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

Bạn sẽ cần thêm chi tiết về đa giác cụ thể của mình trong đó:

  • polygonLayer là tên của lớp đa giác của bạn
  • fieldName là tên của lĩnh vực
  • value là giá trị tính năng của đa giác cụ thể của bạn

Thuộc tính phong cách

Lưu ý rằng để tô màu đường trực quan, bạn có thể cần phải làm điều đó từ thuộc tính Draw effect :

Vẽ các thuộc tính hiệu ứng

Đây là kết quả (lưu ý rằng dòng trực quan không hoàn toàn trùng với dòng ban đầu nên tôi đã sửa đổi phần bù một chút):

Kết quả

Và không có đa giác:

Kết quả không có đa giác



Biên tập:

Nếu bạn muốn áp dụng điều này cho từng tính năng đường giao nhau với tính năng đa giác, hãy chuyển đến Trình chỉnh sửa chức năng và sử dụng chức năng sau (thay đổi tên của polygon example_2để khớp với tên của lớp đa giác của bạn):

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

Chức năng chỉnh sửa

Nhấp vào Tải, sau đó chuyển đến tab Biểu thức và nhập func(). Hy vọng rằng kết quả sẽ giống như sau (sử dụng các thuộc tính kiểu tương tự được đề cập ở trên):

Kết quả cuối cùng


Tôi thực sự đã xem xét nhưng dừng lại khi tôi phát hiện ra, điều đó get_featuređòi hỏi tên và giá trị của trường. Tôi chỉ có một lớp đa giác và muốn sử dụng tất cả các tính năng trên lớp đó để che giấu. Điều đó có thể không?
Châu

@Chau - Đã chỉnh sửa bài đăng để bao gồm một phương pháp có thể :)
Joseph

1
Một lựa chọn khác là hòa tan lớp đa giác.
csk

1
@Joseph - Khi sử dụng a Geometry Generatorlà phương thức funcđược gọi cho mọi tính năng trên lớp nơi nó được sử dụng để tạo kiểu? Vậy nếu lớp dòng của tôi có 3 tính năng, thì funcđược gọi là 3 lần và vẽ cùng một kết quả 3 lần?
Châu

1
@Chau - Tôi nghĩ bạn đã đúng, mã được lặp qua từng tính năng nhiều lần. Đã chỉnh sửa bài đăng để funcbây giờ chỉ được gọi cho mỗi tính năng dòng và sẽ chỉ rút ra kết quả một lần (dường như là trường hợp được hiển thị bởi các điểm đánh dấu đỉnh trong đa giác, trước khi điều này bị ẩn bên dưới mà tôi đã bỏ lỡ). Cảm ơn bạn đã chỉ ra điều này :)
Joseph

3

Mở rộng câu trả lời của Joseph , tôi đã đưa ra chức năng này. Nó chiếm các hệ tọa độ khác nhau và tôi cần phải tra cứu thành hai lớp mặt nạ, do đó nó cũng xử lý nó. Hơn nữa tôi muốn có thể che dấu các đường bên trong đa giác hoặc các đường bên ngoài đa giác.

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

Bài tập này đã cho tôi thấy rằng QGIS không quá thích làm việc với các tập dữ liệu lớn và thuật toán này với QGIS bị sập trên đường của tôi quá thường xuyên. Tôi nghi ngờ rằng trình kết xuất QGIS không muốn kết xuất Trình tạo hình học gây tốn thời gian.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.