user9315259
user9315259

Reputation:

Compare Lat/Lon and Display Closest to Farthest in Python

I have a program that compares a user input of Lat/Lon against a set of Lat/Lon and displays the closest.The code is below and works fine:

#prints out the closest lat and lon
from math import cos, asin, sqrt

#Haversine formula
def distance(lat1, lon1, lat2, lon2):
    p = 0.017453292519943295#degree to radian
    a = 0.5 - cos((lat2-lat1)*p)/2 + cos(lat1*p)*cos(lat2*p) * (1-cos((lon2-lon1)*p)) / 2
    return 12742 * asin(sqrt(a))#print in km


def closest(data, v):
    return min(data, key=lambda p:   distance(v['lat'],v['lon'],p['lat'],p['lon']))

sdata = [{'lat': 37.82, 'lon': 86.142}, 
        {'lat': 38.88,  'lon': 87.251 }, 
        {'lat': 39.78, 'lon': 89.336},
        {'lat': 40.42, 'lon': 86.123}, 
        {'lat': 41.35,  'lon': 90.21 }, 
        {'lat': 39.66, 'lon': 87.11}]

lat = input("Latitude:")
lon = input("Longitude:")

cust = {'lat': lat, 'lon':lon}

print(closest(sdata,cust))

However I want to display the result in a range i.e Lat/lon from closest to farthest from the list instead of a single Lat/lon output.
Input :lat:40 lon:80
Output :{'lat': 40.42, 'lon': 86.123}
Expected Output: {'lat': 40.42, 'lon': 86.123}, {'lat': 39.78, 'lon': 89.336}, {'lat': 39.66, 'lon': 87.11},{'lat': 41.35, 'lon': 90.21 },{'lat': 38.88, 'lon': 87.251 },{'lat': 37.82, 'lon': 86.142}

Upvotes: 1

Views: 239

Answers (2)

pe-perry
pe-perry

Reputation: 2621

You can also do it in one line.

cust = {'lat': 40, 'lon': 80}
out = sorted(sdata, key=lambda data: distance(data['lat'], data['lon'], cust['lat'], cust['lon']))
print(out)

Output:

[{'lat': 40.42, 'lon': 86.123}, {'lat': 37.82, 'lon': 86.142}, {'lat': 39.66, 'lon': 87.11}, {'lat': 38.88, 'lon': 87.251}, {'lat': 39.78, 'lon': 89.336}, {'lat': 41.35, 'lon': 90.21}]

Upvotes: 0

OneCricketeer
OneCricketeer

Reputation: 191884

Get the list of all distance from the input, then sort it

Tested in Python3

from operator import itemgetter 

# Use raw_input() with Python 2
lat = float(input("Latitude:"))
lon = float(input("Longitude:"))

distances = (distance(v['lat'],v['lon'],lat,lon) for v in sdata)
for lat_lng, d in sorted(zip(sdata, distances), key=itemgetter(1)):
  print(lat_lng['lat'], lat_lng['lon'], d)

Output

Latitude: 0.0
Longitude: 0.0

37.82 86.142 9668.762962674926
40.42 86.123 9679.445101487952
39.66 87.11 9760.193791714297
38.88 87.251 9769.623036766754
39.78 89.336 9950.802415333788
41.35 90.21 10025.072644640604

Upvotes: 1

Related Questions