简体   繁体   中英

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;

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. 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 .

So, is there any way to make this GeoDjango query?

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.

Assumptions:

  1. Model_A has a geometry field called: model_a_point .
  2. Model_B has a geometry field called: model_b_poly .

Methods used:

  1. Subquery() , new method in Django 1.11 which allows the definition of queries with a subquery part.

  2. OuterRef() , new method in Django 1.11 which is used:

    when a queryset in a Subquery needs to refer to a field from the outer query.

  3. within() , which:

    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.)

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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