11 votos

¿Estilo capa concreta utilizando máscara de polígono en QGIS?

Tengo una capa de línea y una capa de polígonos en QGIS:

Before mask

Me gustaría estilo de la parte de la capa de línea fuera del polígono utilizando un estilo y la parte interior con un estilo diferente:

After mask

No quiero crear un derivado del conjunto de datos, ex. clip de la capa de línea y el estilo de las dos partes.

Este es un caso sencillo, pero en mi proyecto de QGIS tengo +de 30 capas así que creo que cualquier capa de la mezcla sería molestar a las capas subyacentes.

Es posible hacer algo como esto?

No quiero mostrar la capa de polígonos, es sólo aquí para visualizar lo que me gustaría hacer.

11voto

Mue Puntos 2469

No hay una solución perfecta, pero se puede hacer uso de la Geometría Generador que añade un visualizadas línea para representar la intersección. Entonces, podría establecer esta a la superposición de la línea original de la característica.

Añadir un nuevo símbolo de la capa haciendo clic en el signo más y seleccione el Geometry generator como símbolo del tipo de capa. Establecer el geoemtry tipo a LineString / MultiLineString y el uso de la siguiente expresión:

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

Se necesitaría añadir detalles acerca de su polígono donde:

  • polygonLayer es el nombre de la capa de polígono
  • fieldName es el nombre del campo
  • value es la función de valor de su polígono

Style properties

Tenga en cuenta que para el color de la línea visual, usted puede necesitar para hacerlo desde el Sorteo de los efectos de la propiedad:

Draw effects properties

Este fue el resultado (tenga en cuenta que la línea visual no se superpone a la línea original completamente así que he modificado el desplazamiento un poco):

Result

Y sin el polígono:

Result without polygon



Editar:

Si usted desea que se aplique para cada entidad de línea de intersección de un polígono característica, vaya al Editor de la Función y el uso de la siguiente función (cambiar el nombre de polygon example_2 a coincidir con el nombre de su capa de polígonos):

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

Function editor

Haga clic en Cargar , a continuación, vaya a la Expresión tab y escriba en func(). Esperemos que el resultado debería parecerse a la siguiente (usando el mismo estilo de propiedades mencionadas anteriormente):

Final result

3voto

Mike Powell Puntos 2913

Se extiende sobre José's respuesta que se me ocurrió con esta función. Las cuentas para los diferentes sistemas de coordenadas y necesitaba de búsqueda en dos enmascaramiento de las capas, por lo tanto se maneja que demasiado. Es más, yo quería ser capaz de cualquier máscara de las líneas en el interior de los polígonos o líneas fuera de los polígonos.

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

Este ejercicio me ha demostrado que QGIS no es demasiado aficionado a la de trabajar con grandes conjuntos de datos y de este algoritmo con QGIS estrellarse en mi camino demasiado a menudo. Sospecho que el QGIS renderizador no le gusta para representar la Geometría de los Generadores que consumen mucho tiempo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X