Power BI – Haversine formula not giving expected results

I hope someone can help, because despite extensive searching and trial and error I am getting nowhere…

My aim is to select a postcode area (eg. BS10, L20, LS9) and radius in miles, and the map visual will show all staff within that radius around the chosen postcode area. I cannot post any sample files because of data protection, so I’ll try to explain as best I can…

I have two tables of data –
rv_staff – this shows all staff members and their addresses, including postcodes (both full and partial) as well as the coordinates of said postcode
Area Selection – this is a list of all UK postcode ares (so first half only) and the corresponding coordinates, along with area (Leeds/Manchester/Bristol etc) and other details.

These tables have a many-to-one relationship from the staff table to the area selection table on the partial postcodes (as there are more than one postcode on the staff table, and only one on the area table).

I have a radius slider set up, and I want a slicer/drop-down list to be able to choose a partial postcode from the Area Selection table. This should then populate a table of all staff and the distance from the selected postcode to each staff member (within the specified radius as selected).

Here is where I struggle though. My distance haversine formula just does not work and I don’t know why, as I haven’t changed anything other than the lat/long references.

The initial code I tried as per several sites/people:

Distance = 

var Lat1 = MIN('Area Selection'[latitude])
var Lng1 = MIN('Area Selection'[longitude])

var Lat2 = MIN(rv_staff[Lat])
var Lng2 = MIN(rv_staff[Long])

var P = DIVIDE( PI(), 180)
var A = 0.5 - COS((Lat2-Lat1) * p)/2 + 
    cos(Lat1 * p) * COS(Lat2 * P) * (1-COS((Lng2 - Lng1) * p)) /2
var final = (3958 * ASIN((SQRT(A))))
return final

With this formula (radius set to 100) it shows that people who live in Cornwall/Devon are between 50-100 miles from anywhere, even Glasgow.

So I set up two measures to retrieve the lat and long from the selected postcode area for checking purposes:

Selected Postcode - Lat = LOOKUPVALUE('Area Selection'[latitude], 'Area Selection'[postcode], SELECTEDVALUE('Area Selection'[postcode]))
Selected Postcode - Long = LOOKUPVALUE('Area Selection'[longitude], 'Area Selection'[postcode], SELECTEDVALUE('Area Selection'[postcode]))

I have these in a table and every time I select a new postcode area, the coordinates change accordingly. Some spot checking on google maps shows the coordinates are correct for the location, so I know there’s no issues with the initial postcode selection.

So I tried adding these into the haversine formula to see if this would work (I don’t know why it needs to be a min() value if you’re using just one set of coordinates here – maybe someone can enlighten me):

Linguist Distance (Miles) = 

var Lat1 = [Selected Postcode - Lat]
var Lng1 = [Selected Postcode - Long]

var Lat2 = MIN(rv_staff[Lat])
var Lng2 = MIN(rv_staff[Long])

var P = DIVIDE( PI(), 180)
var A = 0.5 - COS((Lat2-Lat1) * p)/2 + 
    cos(Lat1 * p) * COS(Lat2 * P) * (1-COS((Lng2 - Lng1) * p)) /2
var final = (3958 * ASIN((SQRT(A))))
return final

This (probably expectedly) shows zero for everything.

I also tried a column approach as suggested here, but this just errors (An argument of function ‘ACOS’ has the wrong data type or the result is too large or too small).

Distance = 
acos(sin([Selected Postcode - Lat])*sin(rv_staff[Lat])+cos([Selected Postcode - Lat])*cos(rv_staff[Lat])*cos(rv_staff[Long]-[Selected Postcode - Long]))*3958

I just don’t know what else to try or why I’m not getting the correct results… Any help or suggestions would be most appreciated!

  • I appreciate you have confidential data that can’t be shared, however, you can create a dummy PBIX (a MVP) with fake data that illustrates your challenge. It will help us to help you.

    – 

  • it looks like an interesting challenge, as Sam says if you can share dummy PBIX it would be interesting. It might be the min statements causing the issues, check the values it is creating in case there is a problem with the data. I would also make sure your data category is correct and you are not summarizing the data

    – 

Leave a Comment