【问题标题】:GeoDjango: Finding objects in radiusGeoDjango:在半径中查找对象
【发布时间】:2019-11-29 21:42:10
【问题描述】:

我目前正在尝试获取半径内包含的点列表,但无法正常工作。到目前为止,这是我的观点的代码:

from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance

class AreaInfoViewSet(viewsets.ViewSet):
    queryset = models.AreaInfoRequest.objects.all()
    serializer_class = serializers.AreaInfoRequestRequestSerializer

    def list(self, request):
        center_point = 'POINT(48.80033 2.49175)'
        radius = "50.0"

        data = {"center_point": center_point, "radius": radius, "source_ip": utils.get_client_ip(request)}
        serializer = serializers.AreaInfoRequestRequestSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        # Contains an object with field "from_location"="SRID=4326;POINT (48.80029 2.49157)"
        objs = models.PointsResult.objects.all()

        float_radius = serializer.data["radius"]
        center_point = serializer.data["center_point"] # Point object

        res = models.PointsResult.objects.filter(from_location__distance_lte=(
            center_point, Distance({"meter": float_radius})))
        # Here the res doesn't contain the unique object in the db even if it's within the radius

        return Response(res)

知道为什么它不起作用吗?谢谢

【问题讨论】:

    标签: python django django-rest-framework gis geodjango


    【解决方案1】:

    我相信您遇到了与此处描述的问题类似的问题:GeoDjango & SpatiaLite - filtering nearby objects

    首先,我建议使用dwithin 而不是distance_lte 进行过滤,因为它已针对该用途进行了优化(非常分类的解释here
    来自我们阅读的dwithin 文档:

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

    因此,您必须将查询更改为以下内容:

    meters_to_degrees = CONVERT YOUR METERS TO DEGREES
    res = models.PointsResult.objects.filter(
        from_location__dwithin=(center_point, meters_to_degrees)
    )
    

    米(特别是公里)到度的计算可以在这里找到:How do I convert kilometres to degrees in Geodjango/GEOS?

    最后一点,从 DRF 的角度来看,您正在 ViewSetlist 方法内创建模型实例。 这是绝对错误的,应该避免。如果你想干扰对象创建过程,你应该重写create方法。

    【讨论】:

    • 非常感谢您的回复!我想这就是我一直在寻找的东西,很快就会尝试。还要感谢 DRF 的建议,我会将此视图更改为 APIView 并改用 get
    • @E-Kami 乐于提供帮助 :)
    【解决方案2】:

    我可以在这里看到两个问题:

    1. 您没有在中心点指定 SRID,这意味着您正在比较两个不同的 SRID。你需要在center_point上设置SRID:

      center_point = 'SRID=4326;POINT(48.80033 2.49175)'
      
    2. 您的内联注释显示POINT (2.49157 48.80029),但您的代码使用POINT(48.80033 2.49175) - 请注意,纬度和经度已交换位置。我不知道您打算使用哪一个,但它们指的是完全不同的位置。

    【讨论】:

    • 对不起,我在实验后交换了两者。实际的实际上没有交换。我编辑了我的问题并解决了这个问题。
    • 即使使用center_point = 'SRID=4326;POINT(48.80033 2.49175)' 也不起作用,我相信默认情况下SRID=4326 用于我创建的所有Point 对象
    • 请提供您希望匹配的点的样本数据?
    • 应该找到注释中的那个:``` # 包含一个对象,字段为“from_location”="SRID=4326;POINT (48.80029 2.49157)" objs = models.PointsResult.objects.all () ```
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 2021-06-02
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多