# Rotate a polygon bounding box

I would like to rotate a bounding box given a particular angle.

Here is what i get :

In this example the rotated bounding box does not contain the AOI blue polygon which is an issue for me. The green bounding box is oriented south-north and I can get the angle with which I want to rotate it.

The AOI coordinates are in (lat, lon) degrees but I would like to put a margin in meters on the 4 sides of my rotated bounding box. I guess the best way is to reproject in 3857?

The AOI could be a polygon situated everywhere on the globe.

I first thought to buffer little by little the orange bounding box until the AOI would be contained inside but getting the correct margin would be difficult using this method.

The example :

``````import shapely

a = [0, 0]
b = [1, 1]
c = [3, 1.5]
d = [1, 2]
e = [0, 1.5]
pol = shapely.geometry.Polygon([a, b, c, d, e])

bounds = shapely.geometry.box(*pol.bounds)
bounds_rotated = shapely.affinity.rotate(bounds, 30)
``````
• Have you tried buffering an oriented bounding box instead of a regular bounding box? Commented Jan 17 at 14:08
• Yes but the margin will not be the same on each side if i do this method. Commented Jan 17 at 14:10
• `pol.buffer(margin).minimum_rotated_rectangle`? Commented Jan 17 at 14:11
• No, do not use Web Mercator (EPSG:3857) for this. Web Mercator is useless for distance, because the poles are infinitely far from the Equator. You cannot rotate angular units as if they were Cartesian, because that does not work (as you have demonstrated). Even if you project decimal degrees into a locally appropriate projection, rotate there, and deproject, it's unlikely to "look" correct due to the oddities of Cartesian transformation of angular units. Commented Jan 17 at 14:58
• The crs problem can be solved using `.estimate_utm_crs`. Groupby some unique id and for each subframe returned - reproject to the estimated utm
– Bera
Commented Jan 17 at 18:27

For your exact example you can union the original polygon and the rotated, then `.minimum_rotated_rectangle` the union.

``````import shapely.affinity
import geopandas as gpd

a = [0, 0]
b = [1, 1]
c = [3, 1.5]
d = [1, 2]
e = [0, 1.5]
pol = shapely.geometry.Polygon([a, b, c, d, e])
bounds = shapely.geometry.box(*pol.bounds)
bounds_rotated = shapely.affinity.rotate(bounds, 30)
bounds_rotated_2 = pol.union(bounds_rotated).minimum_rotated_rectangle

df = gpd.GeoDataFrame(geometry=[pol, bounds, bounds_rotated, bounds_rotated_2])
df["color"] = ["blue", "green", "orange", "red"]
df.boundary.plot(color=df["color"])
``````

• Thanks, it's not exactly what i was looking for but it makes the job. Commented Jan 18 at 8:55

here a solution that can fit :

``````import shapely

a = [0, 0]
b = [1, 1]
c = [3, 1.5]
d = [1, 2]
e = [0, 1.5]
pol = shapely.geometry.Polygon([a, b, c, d, e])
circle = shapely.minimum_bounding_circle(pol)
bounds_circle = shapely.geometry.box(*circle.bounds)

plt.plot(*circle.exterior.coords.xy)
plt.plot(*bounds_circle.exterior.coords.xy)
plt.plot(*pol.exterior.coords.xy)
plt.show()
import numpy as np
for i in np.arange(0, 360):
a = shapely.affinity.rotate(bounds_circle, i)
print(a.contains(pol))
``````