1

I have a Lakes layers which has a transparent fill, and a Rivers layer which (for the sake of its geometric network) flows "through" the Lakes layer. Like so:

enter image description here

I would like to use the Lakes as a symbology mask to mask out the Rivers so it looks like this:

enter image description here

I know for point layers you can set the symbology to mask use use that to mask out other layers, but is there a way to do that with polygon symbology? Ideally I could add another symbology layer to the Lakes layers and use that to mask out the Rivers.

I know I could do this by using a Difference function but I want to learn how to use polygons as masks because I could use that a lot elsewhere also.

I also tried using a virtual layer with an st_difference function but my knowledge of PostGIS is terrible so I didn't get far.

I also tried using a point pattern fill with large points set to mask but when I tried to use it as a mask in the Rivers layer it didn't work.

EDIT: Expanding on @Babel's idea, I could also set the River symbology to geometry generator using this expression: difference($geometry, aggregate('Lakes', 'collect', $geometry)) However I would really like to know specifically if there's a way of using polygons as masks.

1 Answer 1

1

Add an additional symbol layer, set it to Geometry generator, get the intersection of lake with river and style this intersection in the same color as the lake, but with no transparency. This works if you have no additional background layers, otherwise see below. Use this expression in Geometry generator:

intersection( 
    $geometry, 
    geometry (
        get_feature_by_id (
            'river',
            1
        )
    )
)

enter image description here

Other possibility: use the same idea to hide the part of the river that "flows through" the lake. This works better if you have additional background layers. In the case above, adding a background, the river inside the lake will become visible again (since part of the lake is transparent, the lake-section covering the river is not).

You can avoid this if we hide the section of the river inside the lake:

On the river layer, create two symbol layers with Geometry generator: once for the intersection of river and lake, once the difference of the whole river to this intersection of river and lake. Style this last symbol layer with complete transparency.

The expression to use for the difference (river outside the lake, styled as blue line) looks like this; the other symbol layer for the river inside the lake (the one to be styled completely transparent) takes only the intersection() part of the expression (see red box in the following screenshot):

difference( 
   $geometry,
   buffer (
        intersection( 
            $geometry, 
            geometry (
                get_feature_by_id (
                    'lake',
                    1
                )
            )
        ),
        0.1
    )
)

Screenshot: expression for the symbol-layer rendering the visible part of the river, outside the lake. I had a add a small buffer to get red of all parts of the river inside the lake. The other symbol layer is set to complete transparency and uses the part of the expression highlighted with the red box: enter image description here

2
  • Thanks Babel. That's not a bad idea. I actually expanded on that and I can set the River symbology geometry generator to difference($geometry, aggregate('Lakes', 'collect', $geometry)) and it works but I'd love to know specifically if there's a way of using polygons as a mask. Definitely +1 for the idea though so thank you. Commented May 14, 2021 at 9:43
  • 1
    OK, you're right. I still added another (similar) idea that works also if additional background layers (as a basemap) are present, even if the question remains how you can use a polygon as a mask.
    – Babel
    Commented May 14, 2021 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.