QGIS'de çokgen maskesi kullanarak belirli bir katmanı şekillendirmek mi?


10

QGIS bir çizgi katmanı ve bir çokgen katmanı var:

Maske öncesi

Çok katlı dışında çizgi katmanının bir stilini bir stil kullanarak ve içindeki bölümü farklı bir stil kullanarak şekillendirmek istiyorum:

Maske Sonrası

Bir türev veri kümesi oluşturmak istemiyorum, ör. çizgi katmanını kırpın ve iki parçayı şekillendirin.

Bu basit bir durum ama QGIS projemde +30 katman var, bu yüzden herhangi bir katman harmanlamasının alttaki katmanları rahatsız edeceğini düşünüyorum.

Böyle bir şey yapmak mümkün mü?

Çokgen katmanını göstermek istemiyorum, sadece ne yapmak istediğimi görselleştirmek için burada.


1
Güzel yöntem! Ben bu soruya bir düzenleme yerine bir cevap olarak gönderilmesi gerektiğini düşünüyorum :)
Joseph

@Joseph, bitti!
Chau

Yanıtlar:


11

Mükemmel bir çözüm değil, ancak kavşağı temsil etmek için görselleştirilmiş bir çizgi ekleyen Geometri Jeneratörünü kullanabilirsiniz . Daha sonra bunu orijinal çizgi özelliğinin üzerine gelecek şekilde ayarlayabilirsiniz.

Artı işaretine tıklayarak yeni bir sembol katmanı ekleyin ve Geometry generatorsembol katmanı türünü seçin. Geoemtry türünü LineString / MultiLineStringşu ifadeye ayarlayın ve aşağıdaki ifadeyi kullanın:

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

Belirli çokgeniniz hakkında ayrıntılar eklemeniz gerekir:

  • polygonLayer çokgen katmanınızın adıdır
  • fieldName alanın adı
  • value çokgeninizin özellik değeridir

Stil özellikleri

Görsel çizgiyi renklendirmek için, Çizim efektleri özelliğinden yapmanız gerekebilir :

Çizim efektleri özellikleri

Sonuç (görsel çizginin orijinal çizgiyle tamamen örtüşmediğine dikkat edin, bu yüzden ofseti biraz değiştirdim):

Sonuç

Ve çokgen olmadan:

Çokgensiz sonuç



Düzenle:

Bunun çokgen özelliğiyle kesişen her çizgi özelliğine uygulanmasını istiyorsanız, İşlev Düzenleyiciye gidin ve aşağıdaki işlevi kullanın ( polygon example_2adını çokgen katmanınızın adıyla eşleşecek şekilde değiştirin ):

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

İşlev düzenleyici

Click yükleyin sonra gidip İfade sekmesi ve yazın func(). Umarım sonuç aşağıdaki gibi görünmelidir (yukarıda belirtilen aynı stil özelliklerini kullanarak):

Son sonuç


Aslında buna baktım ama keşfettiğimde get_featurealan adı ve değeri gerektiren durdum . Sadece bir çokgen katmanım var ve bu katmandaki tüm özellikleri maskelemek için kullanmak istiyorum. Mümkün mü?
Chau

@Chau - Olası bir yöntemi içerecek şekilde yayın düzenlendi :)
Joseph

1
Başka bir seçenek çokgen tabakasını eritmek olacaktır.
csk

1
@Joseph - a kullanırken Geometry Generator, funcstil için kullanılan katmandaki her özellik için çağrılan yöntem nedir? Yani benim çizgi katmanı 3 özelliği varsa, o zaman func3 kez denir ve aynı sonucu 3 kez çizmek?
Chau

1
@Chau - Haklı olduğunu düşünüyorum, kod her özellik boyunca birden çok kez yinelenen. Gönderiyi funcşimdi her satır özelliği başına yalnızca çağrılacak şekilde düzenleyecek ve sonucu yalnızca bir kez çizecek (bu, çokgenlerin altında gizlenmeden önce, çokgenler içindeki tepe işaretçileri tarafından gösterildiği gibi görünüyor). Bunu işaret
Joseph

3

Üzerinde genişletme Joseph bireyin cevabı bu işlevi ile geldi. Farklı koordinat sistemlerini açıklar ve iki maskeleme katmanına bakmam gerekiyordu, bu yüzden bunu da ele alıyor. Dahası ya çokgenlerin içindeki çizgileri ya da çokgenlerin dışındaki çizgileri maskelemek istedim.

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

Bu alıştırma, QGIS'in büyük veri kümeleriyle çalışmaya çok düşkün olmadığını ve QGIS'in bu yolda sık sık çöktüğü algoritmayı gösterdi. QGIS oluşturucusunun zaman alan Geometri Üreteçlerini işlemekten hoşlanmadığından şüpheleniyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.