问题
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?
回答1:
From Django version 1.11 you have an optimized option to solve this query.
Assumptions:
Model_A
has a geometry field called:model_a_point
.Model_B
has a geometry field called:model_b_poly
.
Methods used:
Subquery(), new method in Django 1.11 which allows the definition of queries with a subquery part.
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.
within(), which:
Tests if the geometry field is spatially within the lookup geometry.
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.
来源:https://stackoverflow.com/questions/37166891/geodjango-query-all-point-that-are-contained-into-a-multi-polygon