Django - how can I find the distance between two points?

I have some users registered in my Django application and I just want to calculate the distance, geographically, between two users based on their zip code, and then sort the list based on this. I would suggest that this functionality is not built into Django. I looked at some options and came across geodjango, which seems like it might be redundant for my needs.

+8
python django google-maps geodjango
source share
4 answers

Following tcarobruce's suggestion, here is my comment above:

The zip code database project has a latitude and longitude database of US zip codes, either as SQL or CSV. They also provide the following code for calculating distance (edited by me slighlty):

from math import sin, cos, radians, degrees, acos def calc_dist(lat_a, long_a, lat_b, long_b): lat_a = radians(lat_a) lat_b = radians(lat_b) long_diff = radians(long_a - long_b) distance = (sin(lat_a) * sin(lat_b) + cos(lat_a) * cos(lat_b) * cos(long_diff)) return degrees(acos(distance)) * 69.09 

Please note that the result is indicated in miles charter.

Edit: Corrections due to John Machin.

+6
source share

This is a big fat commentary on the code posted in @Sven Marnach's (currently accepted) answer.

Original code from the zip project site, indented by me:

 from math import * def calcDist(lat_A, long_A, lat_B, long_B): distance = (sin(radians(lat_A)) * sin(radians(lat_B)) + cos(radians(lat_A)) * cos(radians(lat_B)) * cos(radians(long_A - long_B))) distance = (degrees(acos(distance))) * 69.09 return distance 

Code sent by Sven:

 from math import sin, cos, radians, degrees def calc_dist(lat_a, long_a, lat_b, long_b): lat_a = radians(lat_a) lat_b = radians(lat_b) distance = (sin(lat_a) * sin(lat_b) + cos(lat_a) * cos(lat_b) * cos(long_a - long_b)) return degrees(acos(distance)) * 69.09 

Problem 1: DO NOT START : acos needs to be imported

Problem 2: INCORRECT ANSWERS : it is necessary to convert the difference of longitude to radians in the second last line

Task 3: The variable name "distance" is an extreme misnomer. This value is actually equal to the cos of the angle between the two lines from the center of the earth to the input points. Go to "cos_x"

Problem 4: There is no need to convert the angle x to degrees. Just multiply x by the radius of the earth in the selected units (km, nm or "charter miles")

After fixing all this, we get:

 from math import sin, cos, radians, acos # http://en.wikipedia.org/wiki/Earth_radius # """For Earth, the mean radius is 6,371.009 km (˜3,958.761 mi; ˜3,440.069 nmi)""" EARTH_RADIUS_IN_MILES = 3958.761 def calc_dist_fixed(lat_a, long_a, lat_b, long_b): """all angles in degrees, result in miles""" lat_a = radians(lat_a) lat_b = radians(lat_b) delta_long = radians(long_a - long_b) cos_x = ( sin(lat_a) * sin(lat_b) + cos(lat_a) * cos(lat_b) * cos(delta_long) ) return acos(cos_x) * EARTH_RADIUS_IN_MILES 

Note. After eliminating problems 1 and 2, this is the "spherical law of cosines", as is usually implemented. This is normal for applications such as the "distance between two US zip codes."

Caution 1: it is not accurate for small distances, for example, from your front door to the street, so much that it can give a non-zero distance or cause an exception (cos_x> 1.0) if the two points are identical; this situation can be specially dressed.

Caution 2: If two points are antipodes (a direct path passes through the center of the earth), it can throw an exception (cos_x <-1.0). Anyone who is worried about this can check cos_x before executing acos (cos_x).

Example:

SFO (37.676, -122.433) to NYC (40.733, -73.917)

calcDist β†’ 2570.7758043869976
calc_dist β†’ 5038.599866130089
calc_dist_fixed β†’ 2570.9028268899356

US Government Website (http://www.nhc.noaa.gov/gccalc.shtml) β†’ 2569

This site (http://www.timeanddate.com/worldclock/distanceresult.html?p1=179&p2=224), from which I got the coordinates of SFO and NYC, β†’ 2577

+18
source share

http://code.google.com/apis/maps/documentation/directions/

You can make directions for each location. Given the full distance. The API seems to output JSON; You can either analyze the response on the server side, or calculate the distance using JavaScript.

0
source share

Another easy way:

Below the function returns the distance between two locations after calculating latitudes and longitudes from zipcode.

lat1 , long1 - latitude and longitude of the first location.

lat2 , long2 - latitude and longitude of the second location.

 from decimal import Decimal from math import sin, cos, sqrt, atan2, radians def distance(lat1, lat2, long1, long2): r = 6373.0 lat1 = radians(lat1) lat2 = radians(lat2) long1 = radians(long1) long2 = radians(long2) d_lat = lat2 - lat1 d_long = long2 - long1 a = (sin(d_lat/2))**2 + cos(lat1) * cos(lat2) * (sin(d_long/2))**2 c = 2 * atan2(sqrt(a), sqrt(1-a)) # distance in miles dis = r * c # distance in KM dis /= 1.609344 return dis 
0
source share

Source: https://habr.com/ru/post/651174/


All Articles