Geographic Information Systems Asked by Théo Champion on March 29, 2021
I’m working in QGIS and I can’t seem to warp my head around this problem.
I have bounding box defined as 4 coordinates pair (A, B, C, D in the picture) and a center and I want to calculate a new bounding box (A’, B’, C’, D’ in the picture) defined as the original bounding box, plus a padding on all sides. The padding value is defined as a percentage of the longest side of the original bounding box P
.
What I’m trying to achieve is: given A, B, C, D, CENTER
and a percentage value P
, calculate A', B', C', D'
.
How can I achieve this using QGIS?
Here is a picture of this for reference:
You can achieve this with the following steps as a kind of algorithmic description (pseudo code) that you can implement whatever software you use. For an actual implementation, I will add a solution how to do it in QGIS using expressions. Also see the screenshot at the very bottom:
P
to get the padding distanceTo implement this in QGIS: Let's presume you have a polygon layer rectangle
and a point layer vert
for the vertices of the rectangle: A, B, C, D, whereas these four letters are stored in an attribute field name
. You can use QGIS expressions either for visualization purpose only as an additional symbol layer or create actual geometries using Menu Processing / Toolbox / Geometry by expression
. This is a step by step guide to show how the expression is built according to the steps above for better understanding. However, you can directly jump to 10 to use the expression there as it includes all the steps from 1 to 10.
distance (geometry (get_feature('vert','name','A')), geometry (get_feature('vert','name', 'B')))
distance (geometry (get_feature('vert','name','A')), geometry (get_feature('vert','name', 'D')))
max (a, b)
, whereas a is the value (or expression) from step 1, b the one from 2c*p
, whereas c
is the value or expression form 3, p
is the percentage for the padding; implementing the whole expression from 1 to 4 with percentage=20% would look like (change 0.2 accordingly for other values):max (
distance (geometry (get_feature('vert','name','A')), geometry (get_feature('vert','name', 'B'))),
distance (geometry (get_feature('vert','name','A')), geometry (get_feature('vert','name', 'D')))
) *0.2
make_line (geometry (get_feature('vert','name','A')),geometry (get_feature('vert','name','B')))
extend (geometry, d, e)
, whereas geometry
is the expression from 5 and d
as well as e
is the value or expression from 4 (screenshot: red line connecting points 1 and 2)start_point (geom)
and end_point(geom)
, whereas geom
is in both cases the line or expression from 6 (screenshot: points 1 and 2)x(point)
and y(point)
, whereas point is the point/expression from 7B
in step 5 with D
, everything else remains the same; to get all four points at once, you can create a multipoint using collect_geometries(1,2,3,4)
, whereas 1
,2
,3
and 4
are the start- and end-points (step 7/8) of the two lines (step 6/8)
All steps from 1 to 9 together looks like this. To keep it straightforward, here I would create a new layer for these four points (1,2,3 and 4 on screenshot), using Menu Processing / Toolbox / Geometry by expression
, than set the rectangle layer as input layer,
and point as output geometry type
and than paste the following expression (here I used with_variable()
to define once a variable padding
for the padding distance and insert it as @padding
afterwards to avoid repeating expressions). After that, use menu Vector / Geometry Tools / Multipart to singleparts
to get a separate feature for each point. In the Geometry by expression
dialog, use this expression:with_variable (
'padding',
max (
distance (
geometry (get_feature('vert','name','A')),
geometry (get_feature('vert','name', 'B'))),
distance (
geometry (get_feature('vert','name','A')),
geometry (get_feature('vert','name', 'D')))
) *0.2,
collect_geometries (
start_point(extend (
make_line (
geometry (get_feature('vert','name','A')),
geometry (get_feature('vert','name','B'))),
@padding,
@padding)
),
end_point(extend (
make_line (
geometry (get_feature('vert','name','A')),
geometry (get_feature('vert','name','B'))),
@padding,
@padding)
),
start_point(extend (
make_line (
geometry (get_feature('vert','name','A')),
geometry (get_feature('vert','name','D'))),
@padding,
@padding)
),
end_point(extend (
make_line (
geometry (get_feature('vert','name','A')),
geometry (get_feature('vert','name','D'))),
@padding,
@padding
)
)
)
)
Now you should have a layer with four points (red points 1,2,3, and 4 on the screenshot). Get the max and min coordinates for x and y using this expressions:
For x: maximum(x($geometry))
and minimum(x($geometry))
For y: maximum(y($geometry))
and minimum(y($geometry))
and 12. can be done in one step. Use this expression:
make_rectangle_3points (
make_point (minimum(x($geometry)), maximum(y($geometry))),
make_point (maximum(x($geometry)), maximum(y($geometry))),
make_point (maximum(x($geometry)), minimum(y($geometry)))
)
And here you are, you get the red rectangle:
Correct answer by Babel on March 29, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP