取出指定坐标点指定距离内所有坐标的优化方法

标题写的不是特别清楚,举个例子解释一下,现在有两个表:①北京市所有的小区(大约1.2万数据,包含百度地图坐标信息),②北京市所有的餐饮商家(大约12万数据,包含百度地图坐标信息),现在要匹配小区周边实际距离在一千米内所有的商家。如果遍历每个小区,然后在小区里遍历每个商家,得到距离,然后得出结果,但是显而易见,这样的话数量非常可观,1.2万 * 12万的数据实在是太大了,如果每个都请求地图接口,非常耗时,而且接口配额基本上无法满足。那么只能从算法上优化: 思路是这样: ①首先以小区的坐标为中心,划出一个边长为2km的正方形,可以得到一个经纬度的左边范围,那么在数据库查询的时候就可以根据lng、lat最大值最小值查询出一个很小的范围,一下子就排除了很大一部分数据
,Python代码如下:

# 根据一个坐标点和距离限制,返回其范围坐标的最大最小值
def get_range_by_point(point, distance):
    lat_distance = float(distance * 360) / float(40000000)
    lng_distance = float(distance * 360) / float(40000 * 1000 * math.cos(float(point['lat']) * math.pi / 180))
    return {'max_lng': point['lng'] + lng_distance,
            'max_lat': point['lat'] + lat_distance,
            'min_lng': point['lng'] - lng_distance,
            'min_lat': point['lat'] - lat_distance}
②从第一部得到数据之后,正方形内可能还有一部分直线距离在1km之外的,所以可以根据两点之间直线距离再次排除一部分,Python代码如下:
class Point:
    pass


def max(a,b):
    if a>b:
        return a
    return b


def min(a,c):
    if a>c:
        return c
    return a


def lw(a, b, c):
    a = max(a,b)
    a = min(a,c)
    return a


def ew(a, b, c):
    while a > c:
        a -= c - b
    while a < b:
        a += c - b
    return a


def oi(a):
    return math.pi * a / 180


def Td(a, b, c, d):
    return 6370996.81 * math.acos(math.sin(c) * math.sin(d) + math.cos(c) * math.cos(d) * math.cos(b - a))


def Wv(a, b):
    if not a or not b:
        return 0;
    a.lng = ew(a.lng, -180, 180)
    a.lat = lw(a.lat, -74, 74)
    b.lng = ew(b.lng, -180, 180)
    b.lat = lw(b.lat, -74, 74)
    return Td(oi(a.lng), oi(b.lng), oi(a.lat), oi(b.lat))


def getDistance(a, b):
    c = Wv(a, b)
    return c


def distance(p1, p2):
    t1 = Point()
    t1.lat = float(p1['lat'])
    t1.lng = float(p1['lng'])
    t2 = Point()
    t2.lat = float(p2['lat'])
    t2.lng = float(p2['lng'])
    return getDistance(t1, t2)
③第三步就是根据上述步骤筛选下来的数据进行百度地图接口查询了,但是这个量就很少了,速度当然也快得多。