在 Django GEOS 中指定大多边形

问题描述 投票:0回答:1

在创建或组合多边形以覆盖地球大部分地区时,我得到了我不明白的结果。

如果我使用一个多边形,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)

所有四个查询都匹配。

我完全困惑了。

django gis geodjango geos
1个回答
0
投票

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。

此外,确保您可视化任何形状以捕捉任何反直觉的形状。

我非常感谢一套适当的规则,因为这显然不完整,因此不将其标记为答案。

© www.soinside.com 2019 - 2024. All rights reserved.