Python Geocode按距离过滤

发布于 2021-01-29 16:16:30

我需要过滤地理位置代码以了解与某个位置的距离。例如,我要过滤一个餐厅地理编码列表,以标识距离我当前位置10英里内的那些餐厅。

有人可以指出我要将距离转换为纬度和经度增量的函数吗?例如:

class GeoCode(object):
   """Simple class to store geocode as lat, lng attributes."""
   def __init__(self, lat=0, lng=0, tag=None):
      self.lat = lat
      self.lng = lng
      self.tag = None

def distance_to_deltas(geocode, max_distance):
   """Given a geocode and a distance, provides dlat, dlng
      such that

         |geocode.lat - dlat| <= max_distance
         |geocode.lng - dlng| <= max_distance
   """
   # implementation
   # uses inverse Haversine, or other function?
   return dlat, dlng

注意:我使用距离的最高准则。

关注者
0
被浏览
51
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    似乎还没有一个好的Python实现。幸运的是,SO“相关文章”侧边栏是我们的朋友。这篇SO文章指向了一篇出色的文章,提供了数学和Java实现。您所需的实际功能相当简短,并嵌入下面的Python代码中。测试到显示的程度。阅读评论中的警告。

    from math import sin, cos, asin, sqrt, degrees, radians
    
    Earth_radius_km = 6371.0
    RADIUS = Earth_radius_km
    
    def haversine(angle_radians):
        return sin(angle_radians / 2.0) ** 2
    
    def inverse_haversine(h):
        return 2 * asin(sqrt(h)) # radians
    
    def distance_between_points(lat1, lon1, lat2, lon2):
        # all args are in degrees
        # WARNING: loss of absolute precision when points are near-antipodal
        lat1 = radians(lat1)
        lat2 = radians(lat2)
        dlat = lat2 - lat1
        dlon = radians(lon2 - lon1)
        h = haversine(dlat) + cos(lat1) * cos(lat2) * haversine(dlon)
        return RADIUS * inverse_haversine(h)
    
    def bounding_box(lat, lon, distance):
        # Input and output lats/longs are in degrees.
        # Distance arg must be in same units as RADIUS.
        # Returns (dlat, dlon) such that
        # no points outside lat +/- dlat or outside lon +/- dlon
        # are <= "distance" from the (lat, lon) point.
        # Derived from: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
        # WARNING: problems if North/South Pole is in circle of interest
        # WARNING: problems if longitude meridian +/-180 degrees intersects circle of interest
        # See quoted article for how to detect and overcome the above problems.
        # Note: the result is independent of the longitude of the central point, so the
        # "lon" arg is not used.
        dlat = distance / RADIUS
        dlon = asin(sin(dlat) / cos(radians(lat)))
        return degrees(dlat), degrees(dlon)
    
    if __name__ == "__main__":
    
        # Examples from Jan Matuschek's article
    
        def test(lat, lon, dist):
            print "test bounding box", lat, lon, dist
            dlat, dlon = bounding_box(lat, lon, dist)
            print "dlat, dlon degrees", dlat, dlon
            print "lat min/max rads", map(radians, (lat - dlat, lat + dlat))
            print "lon min/max rads", map(radians, (lon - dlon, lon + dlon))
    
        print "liberty to eiffel"
        print distance_between_points(40.6892, -74.0444, 48.8583, 2.2945) # about 5837 km
        print
        print "calc min/max lat/lon"
        degs = map(degrees, (1.3963, -0.6981))
        test(*degs, dist=1000)
        print
        degs = map(degrees, (1.3963, -0.6981, 1.4618, -1.6021))
        print degs, "distance", distance_between_points(*degs) # 872 km
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看