Указание больших полигонов в Django GEOS
Я получаю непонятные результаты при создании или объединении полигонов для покрытия большей части земного шара.
Если я использую один многоугольник, GEOS предполагает кратчайшую границу между координатами. Таким образом, ниже указана фигура шириной 0,2°, а не 359,8°:
from django.contrib.gis.geos import MultiPolygon, Polygon
Polygon([(-179.99, -85), (-179.99, 85), (179.99, 85), (179.99, -85), (-179.99, -85)], srid=4326)
Поэтому я создаю два полигона так, чтобы каждая граница была меньше 180°, и объединяю их в мультиполигон:
west = Polygon(((0, 85), (-179, 85), (-179, -85), (0, -85), (0, 85)), srid=4326)
east = Polygon(((0, 85), (179, 85), (179, -85), (0, -85), (0, 85)), srid=4326)
big = MultiPolygon(east, west)
feature.geography = big
feature.save()
Но я не получаю ни одного матча на востоке:
from django.contrib.gis.geos import Point
queryset.filter(feature__geography__intersects=Point(-2.5, 2.5, srid=4326)) # match
queryset.filter(feature__geography__intersects=Point(-2.5, -2.5, srid=4326)) # match
queryset.filter(feature__geography__intersects=Point(2.5, -2.5, srid=4326)) # no match
queryset.filter(feature__geography__intersects=Point(2.5, 2.5, srid=4326)) # no match
Если я просто ищу по east
, то есть feature.geography = east
, все четыре вышеуказанных запроса совпадают.
Если я разделю земной шар на четыре зоны вдоль экватора так:
northwest = Polygon(((0, 0), (0, 85), (-179, 85), (-179, 0), (0, 0)), srid=4326)
northeast = Polygon(((0, 0), (0, 85), (179, 85), (179, 0), (0, 0)), srid=4326)
southwest = Polygon(((0, 0), (0, -85), (-179, -85), (-179, 0), (0, 0)), srid=4326)
southeast = Polygon(((0, 0), (0, -85), (179, -85), (179, 0), (0, 0)), srid=4326)
big = MultiPolygon(northwest, northeast, southwest, southeast)
Все четыре запроса совпадают.
Я в полном недоумении.
Должно быть, некоторые из моих результатов выше были ошибочными.
Но GEOS не всегда выбирает кратчайший путь между координатами, как это предлагается здесь. Кажется, что он предпочитает идти на запад, а не на восток от нулевой широты. Например:
Polygon(((160, -85), (0, -85), (0, 85), (160, 85), (160, -85)), srid=4326)
заворачивает на запад от 0° через 180° (вокруг задней стороны глобуса) к 160°, хотя более короткий путь лежит на восток.
Похоже:
Polygon(((0, 85), (-179, 85), (-179, -85), (0, -85), (0, 85)), srid=4326)
охватывает большую часть запада, как и следовало ожидать. Но начните с широты 1:
Polygon(((1, 85), (-179, 85), (-179, -85), (1, -85), (1, 85)), srid=4326)
охватывает запад, но также заворачивает за Северный полюс. (Начиная с широты 0,1 - нет, я не тестировал между 0,1 и 1.)
Чтобы обойти это, объедините два полигона и соедините их в точке 1, или четыре полигона NW, NE, SW, SE.
Кроме того, убедитесь, что вы визуализируете все фигуры, чтобы уловить любые неинтуитивные формы.
Я был бы очень признателен за правильный набор правил, так как этот явно неполный, поэтому не отмечаю его как ответ.