4

Is there a simple way / ready-to-go function to calculate the azimuth of 2D polygons in a GeoPandas DataFrame? My goal is to eventually compute azimuth angles of building footprints.

Most of the functions I have found explicitly calculate the azimuth for a line, which is not what I am looking for. I have been thinking along the following lines to calculate the azimuth of a polygon using its normal vector (2 dimensions). Is my approach going in the right direction?

I am a bit unsure how to adjust for the quadrants, also my results seem a bit odd.

azimuth = 90 - math.degrees(math.atan2(normal[1], normal[0]))
if azimuth >= 360.0:
    azimuth -= 360.0
elif azimuth < 0.0:
    azimuth += 360.0
3
  • How is the normal defined for the polygon? Depending on that algorithm, (first three points?) using the 2 component defining the normal could give you arbitrary azimuths?
    – Dave X
    Commented Nov 29, 2020 at 14:15
  • 1
    You don't provide the inputs or outputs, or what you expected, but bearing calculations don't work on angular units (geographic coordinate system). Instead you need a function which solves the second (aka Inverse, aka Reverse) Problem of Geodesy
    – Vince
    Commented Nov 29, 2020 at 14:17
  • 1
    What have you tried so far using geopandas? Could you add your code attempts? How do you use a footprint in the script? You can calculate four different azimuths for a footprint which has four edges Commented Nov 29, 2020 at 14:27

1 Answer 1

11

Calculate the minimum rotated rectangle, find its longest side, calculate the angle of the side line:

import geopandas as gpd
import shapely
import math

df = gpd.read_file('/home/bera/GIS/Data/testdata/ak_riks.shp')

g = df.iloc[2].geometry #Select one polygon
a = g.minimum_rotated_rectangle #Calculate its minimum rotated rectangle
l = a.boundary #Extract the rectangle boundary as a line
coords = [c for c in l.coords] #List the line coordinates
segments = [shapely.geometry.LineString([a, b]) for a, b in zip(coords,coords[1:])] #Create the four side lines.
longest_segment = max(segments, key=lambda x: x.length) #Find the longest line (one of the long sides of the rotated rectangle)
    
p1, p2 = [c for c in longest_segment.coords] #List the start and end coordinates of it
angle = math.degrees(math.atan2(p2[1]-p1[1], p2[0]-p1[0])) #https://stackoverflow.com/questions/42258637/how-to-know-the-angle-between-two-points

enter image description here

2
  • Which IDE is that ?
    – Taras
    Commented Aug 9 at 18:21
  • 1
    Spyder, very easy to work in and fast
    – Bera
    Commented Aug 10 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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