Как сделать пространственный поиск "содержащимся" на MultiPolygon или нескольких полигонах?
У меня есть карта с множеством маркеров. И у меня есть два непересекающихся полигона (Box). Я хочу получить все маркеры, которые покрыты этими полигонами.
qb_1 = Polygon.from_bbox((-35.19153, -5.84512, -35.24054, -5.78552))
qb_2 = Polygon.from_bbox((64.16016, 50.26125, 61.80359, 52.04911))
q_box = MultiPolygon(qb_1, qb_2)
test1 = Marker.objects.filter(point__contained=qb_1)
test2 = Marker.objects.filter(point__contained=qb_2)
test = Marker.objects.filter(point__contained=q_box)
print "Count of Polygon 1 = %s" % test1.count()
print "Count of Polygon 2 = %s" % test2.count()
print "Count of MultiPolygon = %s" % test.count()
Но результаты таковы:
Count of Polygon 1 = 4
Count of Polygon 2 = 12
Count of MultiPolygon = 237
Почему Polygon 1 + Polygon 2 не равен MultiPolygon?
1 ответ
Секрет кроется в словах, которые я выделил (из документации по geoqueryset)
содержащиеся
Доступность: PostGIS, MySQL, SpatiaLite
Проверяет, полностью ли содержит ограничивающий прямоугольник геометрического поля ограничивающий прямоугольник поисковой геометрии
Два созданных вами полигона имеют небольшие области, а созданный вами мультиполигон также имеет небольшую область, но этого нельзя сказать о его ограничительной рамке.
qb_1.envelope.area # 0.0029209960000001417
qb_2.envelope.area # 4.213217240200014
qbox.envelope.area # 5754.726987961
как вы увидите, последний из них огромен по сравнению с ним, и он охватывает гораздо больше точек, чем два полигона, взятых самостоятельно. Таким образом, целое больше, чем сумма его частей.
Вы должны быть в состоянии получить действительные точки, покрытые двумя полигонами, следующим образом:
из django.db.models import Q Marker.objects.filter(Q(point__contained=qb_1) | Q(point__contained=qb_1))
Но, возможно, вы действительно ищете, если вы действительно ищете Но это доступно только в postgresql, так что содержит хорошую замену.
содержит
Доступность: PostGIS, Oracle, MySQL, SpatiaLite
Проверяет, содержит ли поле геометрии пространственную геометрию поиска.
Тогда ваш запрос становится
Marker.objects.filter(Q(point__contains=qb_1) | Q(point__contains=qb_1))