QGIS Drawing – Drawing an Arc with Length Proportional to a Distance in QGIS

expressiongeometry-generatorpolyline-creationqgis

From two points layers:

'ORIGIN' → Origin point at coordinate 0,0

'CLUSTERS' → Points identified by cluster with field "CLUSTER_ID"

I am drawing a line from each point in the 'CLUSTERS' layer to the 'ORIGIN' layer and, at the same time, I am labeling the distance. I am using these two following expressions:

Geometry Generator for the line style:

make_line(make_point(0,0),$geometry)

Expression for Label:

distance(make_point(0.0,0.0),$geometry)

With the following result:

enter image description here

My goal is to change the style of the straight line that connects each point of the 'CLUSTERS' layer to the 'ORIGIN' layer, by an arc oriented to the point 0,0 for each point of the 'CLUSTERS' layer that crosses the center of each point and that has a length proportional to the distance.

I add a manual screenshot of the result I would like to obtain with a Geometry Generator expression:

enter image description here

Best Answer

Use the expression below.

The expression in action: enter image description here

Explanation how the expression works:

  1. The expression creates a wedge buffer using function wedge_buffer() with a buffer width (in degrees) that depends on the distance of the current point from the center.

  2. You must define a maximum distance (in my example: 2000 m), corresponding e.g. to the point furthest away from the center, as being 100%, than calculate the percentage of the distance the current point is away from the center (like e.g. 0.7 for 70% of the max. distance) and multiply this with 360.

  3. As this means that the point furthest away would result in a closed circle, but you want only a part of it (arcs), add a coefficient, (in my case 0.1) that you use to divide the angle of the resulting wedge buffer width. So in my case, I have (pseudocode): 360 degrees * [distance from center to current point] / (2000 * 0.1). Feel free to change this value as you like so that it outputs the result you expect.

  4. The wedge-buffer is a polygon, but you want a line (arcs). Create a circle from the center with the distance to each of the points, then get the circle's bondary (line). The intersection of this line with the wedge buffer is the result.

  5. The first six lines of the expression are used to create two variables that are used several times afterwards: 1) get the center from where the distance to each point is measured from the layer center (change layer name if necessary) and 2) the distance from this center point to the current point.

with_variable(
    'center',
    overlay_nearest('center',$geometry)[0], -- change layer name if necessary
with_variable(
    'distance',
    distance(overlay_nearest('center',$geometry)[0],$geometry),
intersection(
    boundary(
        make_circle(
            @center,
            @distance,
            100
        )
    ),
    wedge_buffer(
        @center,
        degrees (azimuth (@center,$geometry)),
        360*@distance/20000,  -- change the value to fit your needs
        @distance
    )
)))

Edit: there is a variant to to make the arc length inversely proportional to the distance (your comment). For this, in the expression above replace 360*@distance/20000 with 1/@distance^2*10000000, where, again, 10000000 is a coefficient that you should change to adapt your expression.

enter image description here