Geospatial Functions

I just took the Geospatial course by @Paul. I really enjoyed it, he has a wonderful delivery and explained things well.

I tried my hand at writing two M functions based on the course (Haversine get distance and a function to get bearing).

Sharing in case it helps anyone:

// fnGetHaversine

// Source: https://www.geeksforgeeks.org/haversine-formula-to-find-distance-between-two-points-on-a-sphere/

(lat1 as number, lon1 as number, lat2 as number, lon2 as number, optional measure as number)=>

let
// distance between lats and longs
dLat = (lat2-lat1) * Number.PI / 180.0,
dLon = (lon2-lon1) * Number.PI / 180.0,

// convert to radians
latitude1 = lat1 * Number.PI / 180.0,
latitude2 = lat2 * Number.PI / 180.0,

// apply formulae
a = (Number.Power(Number.Sin(dLat/2),2) + 
        Number.Power(Number.Sin(dLon/2),2) * 
        Number.Cos(latitude1) * Number.Cos(latitude2)),

// default is kilometers but if 1 then miles
r = if measure ?? 0 = 0 then 6371 else 3961,
c = 2 * Number.Asin(Number.Sqrt(a)),
result = Number.Round(r * c,4)

in
result


// fnGetBearing
// Source: Paul Lucassen, I wrote this function based on his Enterprise DNA course

(lat1_rad as number, lat2_rad as number, lon1_rad as number, lon2_rad as number)=>

let
Source = Number.Atan2(Number.Sin(lon2_rad-lon1_rad) * Number.Cos(lat2_rad),
Number.Cos(lat1_rad) * Number.Sin(lat2_rad)-Number.Sin(lat1_rad) * Number.Cos(lat2_rad) * Number.Cos((lon2_rad-lon1_rad))),
FromRadians = Source * (180/Number.PI),
CorrectNegative = Number.Mod(FromRadians+360,360),
Round = Number.RoundUp(CorrectNegative),
DirectionResult =
if Round <= 11 or Round >= 349 then [Direction = “N”, Sort=1]
else if Round <= 33 then [Direction = “NNE”, Sort=2]
else if Round <= 55 then [Direction = “NE”, Sort=3]
else if Round <= 77 then [Direction = “ENE”, Sort=4]
else if Round <= 99 then [Direction = “E”, Sort=5]
else if Round <= 121 then [Direction = “ESE”, Sort=6]
else if Round <= 143 then [Direction = “SE”, Sort=7]
else if Round <= 166 then [Direction = “SSE”, Sort=8]
else if Round <= 189 then [Direction = “S”, Sort=9]
else if Round <= 212 then [Direction = “SSW”, Sort=10]
else if Round <= 234 then [Direction = “SW”, Sort=11]
else if Round <= 256 then [Direction = “WSW”, Sort=12]
else if Round <= 279 then [Direction = “W”, Sort=13]
else if Round <= 302 then [Direction = “WNW”, Sort=14]
else if Round <= 325 then [Direction = “NW”, Sort=15]
else if Round >= 348 then [Direction = “NNW”, Sort=16]
else [Direction=“UNK”, Sort=-1]
in
DirectionResult

3 Likes

Hi Krystel,
Thank you, good to learn you enjoyed it.
That function is a nice addition.
Paul

1 Like