Increase the BBOX size but keep the ratio (Lon/Lat)

Viewed 192

I have a Bbox that is defined by the following values:

xmin: 11.555333537980914 
ymin: 47.76067947037518 
xmax: 11.995692579075694 
ymax: 48.281587762758136

I would like to increase the size of this Bbox but keep the ratio. One approach I tried is to calculate the middle point of the Bbox and calculate a new Bbox with the value of radius increased by 50%. The problem: the ratio gets lost.

How could I increase the size of Bbox to 50% but keep the ratio.

3 Answers

Perhaps ST_Expand is what you're looking for. You could first calculate the area of the input bbox using ST_Area and then use the output as a unit to expand the bbox.

SELECT            -- here you can play with different sizes
  ST_Expand(geom, ST_Area(geom)/2) 
FROM yourtable;

Example:

WITH j (geom) AS (
  SELECT ST_MakeEnvelope(11.555333537980914,
                         47.76067947037518,
                         11.995692579075694,
                         48.281587762758136,4326)
)
SELECT 
  ST_Expand(geom,ST_Area(geom)/2) 
FROM j;

The image below represents the result set. The inner bbox is the one you provided and the outer one was created with ST_Expand.

enter image description here

Demo: db<>fiddle

The answer provided by @Jim Jones works perfectly. Is there something PostGIS can not do? :)

I did not wanted to be dependend on PostGIS

so I tried to solve the problem with R. My approach:

I prolong each diagonal of the bbox and calculate the bearing for that diagonal. Based on that data I calculate new edge points of the bbox. It kind of works but the left side of the bbox looks a bit small. I think there is a misstake somwhere but i dont know yet where.

xmin<- 11.555333537980914 
ymin<- 47.76067947037518 
xmax<- 11.995692579075694 
ymax<- 48.281587762758136 

###calculate bearing clockwise of diagonal for each corner of the BBOX
######## right bottom, left und top
######## left and bottom, right and top 
######## left and top and right and bottom 
######## right and top, left and bottom 
##bearing(p1, p2, a=6378137, f=1/298.257223563)
bearing1 <- geosphere::bearingRhumb(c(xmax,ymin),c(xmin,ymax))
bearing2 <- geosphere::bearingRhumb(c(xmin,ymin),c(xmax,ymax))
bearing3 <- geosphere::bearingRhumb(c(xmin,ymin),c(xmax,ymin))
bearing4 <- geosphere::bearingRhumb(c(xmax,ymax),c(xmin,ymin))
#new bbox points
########################## left und top
########################## right und top
########################## right und bottom
########################## left und bottom
p1<- geosphere::destPointRhumb(c(xmin,ymax), bearing1, 10000, r = 6378137)
p2<- geosphere::destPointRhumb(c(xmax,ymax), bearing2, 10000, r = 6378137)
p3<- geosphere::destPointRhumb(c(xmax,ymin), bearing3, 10000, r = 6378137)
p4<- geosphere::destPointRhumb(c(xmin,ymin), bearing4, 10000, r = 6378137)

data<-rbind.data.frame(p1,p2,p3,p4)

xmin<-min(data$lon)
ymin<-min(data$lat)
xmax<-max(data$lon)
ymax<-max(data$lat)
cat(xmin,",",ymin,",",xmax,",",ymax)

enter image description here

One solution would be to translate the box so that its center is at the origin, multiply everything with 1.5, and then translate back. This should be possible with a single ST_Affine(), but I'm too lazy to work out the details. :)

Related