10

I would like to symbolise a polygon without converting them into a line. I have a polygon feature (hatched and bounded by red line) which coincides on top and bottom of the coastline (blue line). I would like to symbolise the outline of a polygon only on two sides and want to drop out the red colour on top and bottom.

Image

I would like to see the end result like this.

Image

2
  • Could you provide some more information on your workflow? E.g., if this a one-time use-case, or will you have to display several polygons this way? If several polygons, are they oriented differently and have they different or similar proportions? Could manual digitising of the side lines be a suitable option?
    – Erik
    Commented Oct 8, 2019 at 14:12
  • 1
    This is not one-time use-case. I have several polygons and they would get updated so the shapes change very often. And I don't want to digitise they manually or covert the polygon into lines.
    – Raj
    Commented Oct 8, 2019 at 14:54

4 Answers 4

12

I struggled a bit with the Geometry generator as @GSienko. For intersection part you can also use built-in function aggregate. Also I used segment_to_lines function which convert polygons to lines.

difference(
    segments_to_lines($geometry),
    aggregate(
        layer:= 'line',
        aggregate:='collect',  
        expression:= $geometry,
        filter:=intersects($geometry, geometry(@parent))
    )
)

or

difference(
    segments_to_lines($geometry),
    aggregate('line','collect',$geometry,intersects($geometry, geometry(@parent)))
)

enter image description here

If you have some polygon "unrelated" to lines you can add if condition for intersection. If layers are in intersection, then difference is applied for symbology, otherwise whole geometry is applied.

if(
    intersects(
        segments_to_lines($geometry),
        aggregate('line','collect',$geometry,intersects($geometry, geometry(@parent)))
    ),
    difference(
        segments_to_lines($geometry),
        aggregate('line','collect',$geometry,intersects($geometry, geometry(@parent)))
    ),
    segments_to_lines($geometry)
)

enter image description here

edit: Using line generator this way has a weak point - you have to handle legend symbol, because it render line thru the polygon (not as a border). However you can still duplicate the layer, set simple fill and use it for legend.

enter image description here

4
  • 1
    More complex solution, and i learn a bit more again :)
    – GSienko
    Commented Oct 8, 2019 at 19:21
  • I also :). I didn't need to use Geometry generator before, but it was first thing I thought about after reading OP. Got stuck a little bit on this trying to combine intersections, and your answer also helped me, because I totally forgot about the Difference function :).
    – Oto Kaláb
    Commented Oct 9, 2019 at 8:11
  • Perfect solution for my case. I very much appreciate all your help :)
    – Raj
    Commented Oct 9, 2019 at 8:36
  • Only downside of using line generator is that you have to handle legend symbol, because it render line thru the polygon (not as a border). However you can still duplicate the layer, set simple fill and use it for legend.
    – Oto Kaláb
    Commented Oct 9, 2019 at 9:24
4

Try using refFunction plugin within geometry generator.

Assumption. 2 layers - one lines as line, and polygons as polygon.

Style polygon like that:enter image description here

difference(exterior_ring( $geometry ),geom_from_wkt(geomintersects('line','$geometry')))

geomintersect will make spatial query between polygon layer and line layer, and return geometry of intersection of two of them, in ours case, two border of polygons. Next step is to make difference with border of polygon. I don't know if you will have holes inside or not, then exterior_ring() will return only exterior border.

Final result: enter image description here

The limitation - geomintersect will check intersection only for one polygon. I manage that limitation by make polygons layer to one big multipolygon, for example by virtual layer for border styling.

3

How about adding a white line under the blue line in the other layer, that has the same width as the red line? If you place the blue line above the polygon layer the white line will obscure the red line.

This of course assumes that you have a white background like in your example, and that you are ok with some of the crosshashes also being obscured.

This is my quick test result:

Map image showing style

Settings for blue line:

Symbology

1
  • In my case, the line thickness and colours may vary . Also I have to use marker lines symbols to the polygons across the map where the thickness of the other feature and the thickness of the polygon won't be the same.
    – Raj
    Commented Oct 8, 2019 at 14:36
2

Disclaimer: This answer won't work if you have multiple polygons

What you could do is find out which nodes form the four corners of the polygon that you wish to draw lines between, and then use those in MAKE_LINE() functions to draw the lines:

To find which nodes you need:

  • First add a geometry generator symbology
  • Set the geometry type to Point/MultiPoint
  • Use the expression POINT_N($geometry, 1) to display the first node as a point
  • Keep changing the value until you know the number of each of the four corners of the polygon, make note of these as you will use pairs of these to draw the lines

To draw the lines:

  • Change the geometry type of the geometry generator to LineString/MultiLineString
  • Use the expression MAKE_LINE(POINT_N($geometry, *first point*), POINT_N($geometry, *second point*)
  • Duplicate this using the other point pair
  • This will draw the two boundary lines

Next you just add a normal line pattern fill symbology underneath those two geometry generators

1
  • Unfortunately, I have loads of polygons.
    – Raj
    Commented Oct 8, 2019 at 14:25

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