I would like to have a slope signature (in German "Böschungsschraffen") like this :
-
https://bauforum.wirklichewelt.de/index.php?id=9672 (German)
-
https://www.akgsoftware.de/docs/de/infravision/b56/akgcad/webhelp/topics/boeschung_c_grundlagen.html (German)
There are long and short lines going from a upper level to a lower level representing the slope.
I just want to draw the signature outgoing from an upper-level line to the lower-level line. I tried it with simple Marker-Line-Symbology but this is not working on edges as marked with red arrows. Maybe the Geometry Generator could do the job, but it seems very advanced.
This is a gravel pit where I tried "Böschungsschraffen" but the red arrows shows the problems I got:
Best Answer
Automatic solution
I created a model that automatically creates the lines as you want as a layer style. Run the model, make the inputs and you get the style you want. Details about how I did it: see below.
When running the model, you need to define 5 inputs: an inner (1) and an outer (2) vector layer (polygons or lines), the interval between the lines you want to create (3) and the files used for styling the output inner layer (4: these are the lines you want) and outer (5, no style at all) layers. The two style files (4 and 5) are included in the zip file together with the model itself, you can download everything here: https://drive.switch.ch/index.php/s/i6AkSCXxLFSNXxX
You can avoid having to define the two style files if you define them in the model: hardcode the path to the two style files. For this, change the two
Set layer style
entries and instead ofModel input
change toValue
and enter your path/filename. Then delete theinner style
andouter style
inputs.Solution: the prinicple
To get correct lines at corners you must combine two styles: one for "outward/convex" corners, one for "inward/concave" corners. Create points at regular intervals on inner and outer polygon boundary, then first create the line from each point of the inner layer to the closest point of the outer layer. Second, identify those points of the outer layer that have not yet been connected and create additional lines from these points to the closest point of the inner layer.
Solution, connecting red (inner) and blue (outer) points - combination of two symbol layer of type Geometry generator:
Step by step
Use QGIS expressions with geometry generator.
Create points at regular intervals along the boundary of the inner and outer polygons, thus creating two point layers
inner
andouter
. Use e.g. Points along geometry tool or this expression with Geometry by expression (and run Multipart to single parts), where2
is the interval (change this to fit your needs):Result: points layers![enter image description here](https://i.stack.imgur.com/sicdm.png)
inner
(red) andouter
(blue):Create slope lines from each point of the inner layer to the closest point of the outer layer with this expression (e.g. with Geometry Generator) and change
outer
to the layer name you use:If you want the half lines to start from the outer layer, change the second last line to:
line_substring (@line, length(@line)*($id%2+0)/2, length(@line))
Result: lines from all red points to the closest blue point:
After the first part, you now need to create lines from the points on the outer layer that have not been used yet. Add another symbol layer of type Geometry generator with this expression (again replacing
outer
with the layer name you use) - see below for explanation:Result: lines in red (color for visualization only to see the difference from lines created before): they connect blue points not yet connected in step 2 above with the closest red point:
Variant:
To change the half-size lines of step 3 to be outgoing from the outer line (not the inner), change the
line_substring()
part of the above expression (9th last to 5th last line) like this:Explanation of step 3 from above
case ... when
condition (line 1) with$id= minimum ($id)
- so just for the first feature you have.outer
layer usingaggregate ('outer', 'array_agg', $id)
(line 9)array_agg (overlay_nearest ('outer',$id)[0])
(line 12)array_contains()
(line 11) witharray_foreach()
(line 8) to check for each point from step 1 if it is contained in the points from step 2geometry()
andget_feature_by_id()
(lines 21-22) to convert the id to the features's point geometry.make_line ()
(line 28)line_substring()
function (line 38) similar to the one above to create alternating full and half lines. Add anotherarray_foreach ()
(line 36) to create alternating values of 1 and 0.5 (end of line 40)