0

我在 Django 中有一个位置感知服务器,它应该只在用户位于数据库条目的给定半径内时返回数据。我在 python 中找到了一个代码片段,它可以在线执行此操作(在这里或其他地方,我真的不能请记住),当我针对 0,0 的坐标进行测试时它似乎有效,而不是当我设置两个不同的坐标时。我现在有一个数据库条目,位于我当前位置 300 米范围内,半径设置为 10 公里,但由于某种原因,服务器没有将结果返回给我。这段代码我哪里出了问题,因为我完全不知道如何修复它,python 的新手,并且在我的项目到期前 5 天无助地迷失了我的元素并使用了 haversine。这是我的基于 hasrsine 的查询的代码:

class StoreList(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                  IsOwnerOrReadOnly,)
serializer_class = StoreSerializer

def get_queryset(self):
    lat = self.request.query_params.get('lat', None)
    lon = self.request.query_params.get('lng', None)

    if lat and lon:
        lat = float(lat)
        lon = float(lon)

        # Haversine formula = https://en.wikipedia.org/wiki/Haversine_formula


        lat1 = math.radians(lat)  # lat in radians
        lng1 = math.radians(lon)  # lng in radians

        lat2 = math.asin(math.sin(lat1)*math.cos(distance/R) +
            math.cos(lat1)*math.sin(distance/R)*math.cos(bearing))

        lng2 = lng1 + math.atan2(math.sin(bearing)*math.sin(distance/R)*math.cos(lat1),
            math.cos(distance/R)-math.sin(lat1)*math.sin(lat2))

        lat2 = math.degrees(lat2)
        lng2 = math.degrees(lng2)

        return Store.objects.filter(latitude__gte=lat1, latitude__lte=lat2)\
            .filter(longitude__gte=lng1, longitude__lte=lng2)

此图像显示已收到请求且坐标正确,但结果集仍为空:(

服务器输出

4

3 回答 3

1

看起来您正在通过弧度,但lat1以度为单位。(您将和转换为弧度,但从未将它们改回度数。)lng1lat2lng2lat1lng1

于 2016-05-11T20:17:27.633 回答
1

切换到像 postgresql(带有 postgis 扩展)或 mysql 5.7 这样的位置感知数据库会容易得多。如果您查看距某个点具有给定距离的对象,那么对于此类数据库来说是一个简单的查询,并且django 完全支持

Dwithin 返回从查找几何到几何字段的距离在彼此之间给定距离内的模型。请注意,如果目标几何体位于投影系统中,您只能提供距离对象。对于地理几何,您应该使用几何字段的单位(例如 WGS84 的度数)。

例子:

Zipcode.objects.filter(poly__dwithin=(geom, D(m=5)))

因此,您的复杂代码变成了单行。您会发现地理空间数据库中有很多非常有用的功能。

于 2016-05-11T23:09:24.313 回答
0

所以..我发现了算法出错的地方..感谢@ncole458的帖子答案源

这是功能齐全的服务器代码:

class StoreList(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                  IsOwnerOrReadOnly,)
serializer_class = StoreSerializer

def get_queryset(self):
    lat = self.request.query_params.get('lat', None)
    lon = self.request.query_params.get('lng', None)

    if lat and lon:
        lat = float(lat)
        lon = float(lon)

        # Haversine formula = https://en.wikipedia.org/wiki/Haversine_formula


        """
        lat1 = math.radians(lat)  # lat in radians
        lng1 = math.radians(lon)  # lng in radians

        lat2 = math.asin(math.sin(lat1)*math.cos(distance/R) +
            math.cos(lat1)*math.sin(distance/R)*math.cos(bearing))

        lng2 = lng1 + math.atan2(math.sin(bearing)*math.sin(distance/R)*math.cos(lat1),
            math.cos(distance/R)-math.sin(lat1)*math.sin(lat2))

        lat1 = math.degrees(lat1)
        lat2 = math.degrees(lat2)

        lat2 = math.degrees(lat2)
        lng2 = math.degrees(lng2)
        """
        lat1 = lat - math.degrees(distance / R)
        lat2 = lat + math.degrees(distance / R)
        lng1 = lon - math.degrees(distance / R / math.cos(math.degrees(lat)))
        lng2 = lon + math.degrees(distance / R / math.cos(math.degrees(lat)))

        return Store.objects.filter(latitude__gte=lat1, latitude__lte=lat2)\
            .filter(longitude__gte=lng1, longitude__lte=lng2)
于 2016-05-12T17:45:58.970 回答