I have three pieces of data:
我有三个数据:
- user's current lat/lng
- company's current lat/lng
- bounding distance
I need to check if the user's lat/lng
is inside a circle created by the bounding distance
(example 100 metres), using the company's lat/lng
as the centre. I hope that makes sense ...
我需要检查用户的lat / lng是否在由边界距离(例如100米)创建的圆内,使用公司的lat / lng作为中心。我希望这是有道理的 ...
Using these three values, all I really need is a True/False.
Are they or are they not in this space.
使用这三个值,我真正需要的是一个真/假。是他们还是不在这个空间。
Without using any DB additives, ala geodjango would be great.
不使用任何DB添加剂,ala geodjango会很棒。
Any help is appreciated, Thanks
任何帮助表示赞赏,谢谢
1 个解决方案
#1
0
Edit
I removed a previous version, using radians, and integrated successive edits in the final format of the answer
我删除了以前的版本,使用弧度,并在答案的最终格式中集成了连续编辑
To use the following, user
is a position on Earth that must be represented by a tuple/list/ndarray of length 2, the first element being the latitude, in degrees, the second the longitude, in degrees as well... the position of company
must be represented in the same way, finally radius
must be specified in metres. (there is also a debug
optional variable, that enables printing a debugging help)
要使用以下内容,用户是地球上的一个位置,必须由长度为2的元组/列表/ ndarray表示,第一个元素是纬度,以度为单位,第二个元素是经度,以度为单位...公司必须以相同的方式表示,最后半径必须以米为单位。 (还有一个调试可选变量,可以打印调试帮助)
def is_close(user,company,radius, debug=0):
"user=(lat, lon) in degrees, company=(lat, lon), radius in m"
from math import cos, pi, sqrt
EarthRadius = 6.371E6 # metre, = 6371 km
deg2rad = pi/180.0
# localize the equirectangular projection to the latitude
# (the 1st coordinate) of the company
radius_x = EarthRadius*cos(company[0]*deg2rad)
radius_y = EarthRadius
dx, dy = ((user[1]-company[1])*deg2rad*radius_x,
(user[0]-company[0])*deg2rad*radius_y)
if debug:print dx, dy, sqrt(dx*dx+dy*dy)
return True if (dx*dx+dy*dy) <= (radius*radius) else False
and eventually a version that uses a list of users, to bypass the function call overheads
并最终使用一个用户列表的版本,以绕过函数调用开销
def are_close(users, company, delta):
from math import cos, pi
# uses angles in degrees, uses Equirectangular projection
rx = 6.371E6*pi/180.*cos(company[0]*pi/180)
ry = 6.371E6*pi/180.
close = []
for user in users:
dx = (user[1]-company[1])*rx
dy = (user[0]-company[0])*ry
close.append(True if dx*dx+dy*dy-r*r <= 0 else False)
return close
Addendum
An example of usage from the interactive prompt
交互式提示中的使用示例
>>> def is_close(user,company,radius, debug=0):
... from math import cos, pi, sqrt
... EarthRadius = 6.371E6 # metre, = 6371 km
... deg2rad = pi/180.0
... radius_x = EarthRadius*cos(company[0]*deg2rad)
... radius_y = EarthRadius
... dx, dy = ((user[1]-company[1])*deg2rad*radius_x,
... (user[0]-company[0])*deg2rad*radius_y)
... if debug:print dx, dy, sqrt(dx*dx+dy*dy)
... return True if (dx*dx+dy*dy) <= (radius*radius) else False
...
>>> user, company = (48.860384,2.338520), (48.859282,2.343369)
>>> is_close(user,company,500, 1)
-354.73500519 122.536809163 375.302802424
True
>>> is_close(user,company,500)
True
>>>
#1
0
Edit
I removed a previous version, using radians, and integrated successive edits in the final format of the answer
我删除了以前的版本,使用弧度,并在答案的最终格式中集成了连续编辑
To use the following, user
is a position on Earth that must be represented by a tuple/list/ndarray of length 2, the first element being the latitude, in degrees, the second the longitude, in degrees as well... the position of company
must be represented in the same way, finally radius
must be specified in metres. (there is also a debug
optional variable, that enables printing a debugging help)
要使用以下内容,用户是地球上的一个位置,必须由长度为2的元组/列表/ ndarray表示,第一个元素是纬度,以度为单位,第二个元素是经度,以度为单位...公司必须以相同的方式表示,最后半径必须以米为单位。 (还有一个调试可选变量,可以打印调试帮助)
def is_close(user,company,radius, debug=0):
"user=(lat, lon) in degrees, company=(lat, lon), radius in m"
from math import cos, pi, sqrt
EarthRadius = 6.371E6 # metre, = 6371 km
deg2rad = pi/180.0
# localize the equirectangular projection to the latitude
# (the 1st coordinate) of the company
radius_x = EarthRadius*cos(company[0]*deg2rad)
radius_y = EarthRadius
dx, dy = ((user[1]-company[1])*deg2rad*radius_x,
(user[0]-company[0])*deg2rad*radius_y)
if debug:print dx, dy, sqrt(dx*dx+dy*dy)
return True if (dx*dx+dy*dy) <= (radius*radius) else False
and eventually a version that uses a list of users, to bypass the function call overheads
并最终使用一个用户列表的版本,以绕过函数调用开销
def are_close(users, company, delta):
from math import cos, pi
# uses angles in degrees, uses Equirectangular projection
rx = 6.371E6*pi/180.*cos(company[0]*pi/180)
ry = 6.371E6*pi/180.
close = []
for user in users:
dx = (user[1]-company[1])*rx
dy = (user[0]-company[0])*ry
close.append(True if dx*dx+dy*dy-r*r <= 0 else False)
return close
Addendum
An example of usage from the interactive prompt
交互式提示中的使用示例
>>> def is_close(user,company,radius, debug=0):
... from math import cos, pi, sqrt
... EarthRadius = 6.371E6 # metre, = 6371 km
... deg2rad = pi/180.0
... radius_x = EarthRadius*cos(company[0]*deg2rad)
... radius_y = EarthRadius
... dx, dy = ((user[1]-company[1])*deg2rad*radius_x,
... (user[0]-company[0])*deg2rad*radius_y)
... if debug:print dx, dy, sqrt(dx*dx+dy*dy)
... return True if (dx*dx+dy*dy) <= (radius*radius) else False
...
>>> user, company = (48.860384,2.338520), (48.859282,2.343369)
>>> is_close(user,company,500, 1)
-354.73500519 122.536809163 375.302802424
True
>>> is_close(user,company,500)
True
>>>