I have a polygon (rectangle or very close it) in a geopandas dataframe that is at an angle relative the x-axis, i.e. it is neither horizontal not vertical. I have a function that splits polygons into smaller rectangles (isometric) but it only works (as desired) on polygon making an angle that is a multiple of pi/2 with the x-axis.

So, my idea has been to rotate any polygon that does not satisfy my requirements, split it and rotate it back to its original position.

For instance:

polygon = 

id geometry
85 POLYGON ((49.37794 51.395203, 49.37794 51.395203, 49.37794 51.395203, 49.37794 51.395203, 49.178337 50.363914, 49.178337 50.363914, 49.178337 50.363914, 49.178337 50.363914, 59.99021 48.733814, 59.99021 48.733814, 59.99021 48.733814, 59.99021 48.733814, 60.223083 49.698566, 60.223083 49.698566, 60.223083 49.698566, 60.223083 49.698566, 49.37794 51.395203))

which looks like this: enter image description here

Now, I determine its angle with the x-axis and rotate it:

polygon = pd.DataFrame(geostore_obstacles_geometry_polygon.loc[85:85,])
polygon['angle'] = polygon.apply(lambda row : polygon_angle(row['geometry']), axis = 1)
polygon = gpd.GeoDataFrame(polygon)
polygon = polygon.set_geometry('geometry')
polygon['rotated'] = polygon.apply(lambda row : shapely.affinity.rotate(row['geometry'], row['angle']), axis = 1)
polygon = polygon.set_geometry('rotated')

which gives: enter image description here

This step splits the polygon inte smaller pieces:

polygon['add'] = polygon.apply(lambda row : split_polygon_up(row['rotated'],side_length=side_length, shape="square", thresh=threshold), axis = 1)
polygon = polygon.explode('add')
polygon = polygon.set_geometry('add')

enter image description here

Before I finally rotate it back

polygon['rotated_add'] = polygon.apply(lambda row : shapely.rotate(row['add'], -row['angle']), axis = 1)
polygon = polygon.set_geometry('rotated_add')

enter image description here

But, as you can imagine, this is not what I expect to have (sorry for the very uggly image).

enter image description here

I understand WHY it does this but I cannot solve it. I have some ideas that the one possible solution would be to rotate all the smaller polygons together with the convex hull or envelope of their union, but I struggle using geopandas to do it.

I would be immensely grateful for any help on how to solve this issue. The dataframe obtained after all the transformations can be found here: https://drive.google.com/file/d/1wY7g3jsD7PNpaTkGBjbGvYArpRUr0UIk/view?usp=sharing

  • 5
    What happens if you wrap all the small polygons into one GeometryCollection and rotate that instead?
    – user30184
    Jun 16, 2021 at 14:28

1 Answer 1


Original problem

  • original geometry in red
  • splits the rotated polygon in blue

enter image description here

With your solution, you rotate every geometry of the blue GeoDataFrame by the angle

blueGeoDataFrame.geometry.rotate(-9) # angle = 9 in the csv file

enter image description here

To rotate the whole GeoDataFrame you need a solution to group all the geometries in one geometry that will be rotated (as suggested by user30184 in the comment)

from shapely.geometry import MultiPolygon
from shapely.affine import rotate
geom = MultiPolygon(blueGeoDataFrame.geometry.values)
res = rotate(geom, -9) # angle = 9 in the csv file

enter image description here

  • Great solution! Jun 17, 2021 at 13:50
  • Elegant solution. there's a typo in the import statement: "from shapely.affine import rotate" should be "from shapely.affinity import rotate" Aug 7, 2021 at 23:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.