简体   繁体   English

GeoDjango查询:包含在多边形中的所有点

[英]GeoDjango query: all point that are contained into a multi polygon

I have two models: 我有两个型号:

Model_A that contains a GeoDjango Point;

Model_B that contains a GeoDjnago MultiPololygon;

For every element in Model_A I have to check if the point is contained into some m_polygon of Model_B element; 对于Model_A中的每个元素,我必须检查该点是否包含在Model_B元素的某个m_polygon中;

I'm able to make this simple query. 我能够做出这个简单的查询。

But I also thought: I have a lot of elements in Model_A and few elements in Model_B. 但我也想过:我在Model_A中有很多元素,在Model_B中有很少的元素。 So, probably is more efficient to iterate all elements in Model_B and check if exist some element in Model_A that it is contained into the current Model_B element . 因此,迭代Model_B中的所有元素并检查Model_A中是否存在包含在当前Model_B元素中的某个元素可能更有效

So, is there any way to make this GeoDjango query? 那么,有没有办法制作这个GeoDjango查询?

Something like this: 像这样的东西:

Model_A.objects.filter(*point_is_contained_into*=a_model_b_mpolygon);

------------------ EDIT ----------------- ------------------编辑-----------------

I tried to use this: 我试着用这个:

result = Model_A.objects.filter(position__intersects=a_model_b_mpolygon)

And this works for me. 这对我有用。 Are there contraindications to use this type of query in my case? 在我的案例中是否有使用此类查询的禁忌症?

From Django version 1.11 you have an optimized option to solve this query. 从Django 1.11版开始,您有一个优化的选项来解决此查询。

Assumptions: 假设:

  1. Model_A has a geometry field called: model_a_point . Model_A有一个名为: model_a_point的几何字段。
  2. Model_B has a geometry field called: model_b_poly . Model_B有一个名为: model_b_poly的几何字段。

Methods used: 使用的方法:

  1. Subquery() , new method in Django 1.11 which allows the definition of queries with a subquery part. Subquery() ,Django 1.11中的新方法,允许使用子查询部分定义查询。

  2. OuterRef() , new method in Django 1.11 which is used: OuterRef() ,Django 1.11中使用的新方法:

    when a queryset in a Subquery needs to refer to a field from the outer query. 当子查询中的查询集需要引用外部查询中的字段时。

  3. within() , which: within() ,其中:

    Tests if the geometry field is spatially within the lookup geometry. 测试几何字段是否在查找几何体中空间上。

  4. annotate() , which will generate for each item in a queryset, a new field (in our case it will contain the points contained by a polygon.) annotate() ,它将为查询集中的每个项生成一个新字段(在我们的例子中,它将包含多边形包含的点。)

Query: 查询:

Model_B.objects.annotate(
    contained_points=Subquery(
        Model_A.objects.filter(
            model_a_point__within=OuterRef('model_b_poly')
        )  # Ref: 1, referenced below, keep reading
    )
)

Result and something more: 结果等等:

The query above will have a field contained_points for every polygon in Model_B which contains every point from Model_A contained by this polygon. 上面的查询将有一个场contained_points在每个多边形Model_B其中包含每一点Model_A这个多边形遏制。

If you only want to keep geometry field of those points ( lon, lan ), at the end of the Subquery call (Ref: 1), use the values() method. 如果您只想在Subquery调用(Ref:1)的末尾保留这些点( lon, lan )的几何字段,请使用values()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM