Thursday, 10 May 2018

vector - Styling specific layer by using polygon mask in QGIS?


I have a line layer and a polygon layer in QGIS:



Before mask


I would like to style the part of the line layer outside the polygon using one style and the part inside using a different style:


After mask


I don't want to create a derivative data set, ex. clip the line layer and style the two parts.


This is a simple case but in my QGIS project I have +30 layers so I think any layer blending would disturb the underlying layers.


Is it possible to do something like this?


I don't want to show the polygon layer, it is just here to visualise what I would like to do.



Answer



Not a perfect solution but you could make use of the Geometry Generator which adds a visualised line to represent the intersection. You could then set this to overlap the original line feature.


Add a new symbol layer by clicking the plus sign and select the Geometry generator as symbol layer type. Set the geoemtry type to LineString / MultiLineString and use the following expression:



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

You would need to add details about your specific polygon where:



  • polygonLayer is the name of your polygon layer

  • fieldName is the name of the field

  • value is the feature value of your specific polygon


Style properties


Note that to colour the visual line, you may need to do it from the Draw effects property:



Draw effects properties


This was the result (note that the visual line did not overlap the original line completely so I modified the offset slightly):


Result


And without the polygon:


Result without polygon






Edit:


If you want this to be applied for each line feature intersecting a polygon feature, go to the Function Editor and use the following function (change the name of polygon example_2 to match the name of your polygon layer):


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


Click Load then go to the Expression tab and type in func(). Hopefully the result should look like the following (using the same style properties mentioned above):


Final result


No comments:

Post a Comment