地理数据跨越antimeridian的数据库和API的最佳做法


24

当这些地理特征(线,面和它们的多部分等价物)跨越时线(经度±180°)并且需要作为GeoJSON发送到客户端Web应用程序并从客户端Web应用程序接收时,最佳做法是什么?


我将开始在服务器端Web API上进行工作,并获得Postgres / PostGIS数据库的支持,以处理历史和预报的热带气旋轨道和风半径。不幸的是,太平洋上的许多气旋都有越过沙漏的趋势,有时在生命周期内多次发生:

在此处输入图片说明

作为居住在后脚区附近的新西兰人,我经常在区域数据中经常遇到此问题,以制定一些应对策略,但是我想实际找出什么是最佳实践。不幸的是,目前没有标记为问题,因此很难搜索相关问题。我所看到的那些困扰该问题的问题似乎都在寻求针对特定应用的建议。这个问题简要讨论了跨越地球的GeoJSON多边形无边界情况下的反子午线。这个问题很接近我的要求。

我需要将历史和预报的气旋存储在空间数据库中,但我希望反高度子集会出现问题。例如,一条线从纬度/经度开始,在其方向(0,179)结束时(0,-179)是不明确的:无论是经过小子午线的短路径,还是“包裹”整个星球。这样的路径应如何存储在空间数据库中(特别是我正在使用PostGIS,但我希望解决方案足够通用)?我有一些想法:

  1. 无需更改要素几何并将模糊性转移到客户端应用程序。
  2. 将跨越子午线的任何特征分割多部分几何,并在子午线处断开。(GeoJSON规范支持命名的CRS。)
  3. 使用不具有这种不连续性的不同旋风盆地或海洋区域的非全局投影
  4. 利用从未观察到旋风绕着整个行星传播这一事实,存储旋风的坐标,该旋风的坐标从纬度范围开始(90,-90) 偏移了360°相位(保持其他-180-180°)
  5. 利用一个事实,即在非洲南端以南极不可能发生气旋,请使用经度30°中断(如上图所示)。
  6. 允许坐标超出EPSG 4326的有效范围,例如,对于任何通过后向子午线的要素,> 180°且<-180°。
  7. Delta编码,例如在TopoJSON中(例如,始于,(0,-179)然后下一个坐标为-3西纬)。我不知道在PostGIS中存储数据时是否或如何实现此功能,但这是将数据发送到客户端应用程序的绝佳解决方案。
  8. 矢量符号或极坐标的某种形式。(似乎相当困难和不寻常。)

其中,我不喜欢想法2–5,因为它们不是通用的,但是我喜欢它们,因为它们对我的特定应用程序有意义。对于仅在太平洋中处理数据的应用程序,它们可能很有意义,因此我不希望完全打折。

想法6和7是从汤姆·麦克赖特(Tom MacWright)的博客中提出的,该博客值得一读,但对于antimeridian而言并不确定。

Idea 4由GeographicaGS'使用GeodesicLinesToGISPython,而后者又使用fiona.transform.transform_geom了360°的时间偏移。反过来,Fiona正在使用OGR的-wrapdateline。我认为这是一个非常坚实的先例,实际上是相当普遍的。

结合存储问题,我需要考虑应如何将此类功能发送到客户端应用程序,以及我的应用程序应如何考虑回传到该应用程序的数据(例如,人类预报员更改了太平洋气旋的预报轨迹)。交换格式可能是GeoJSON,但不是必须的。

不幸的是,GeoJSON规范并未明确涉及时间轴问题。来自维基百科

许多地理软件库或数据格式将世界投影到一个矩形。通常,此矩形正好在第180个子午线上精确地分割。这通常使得不可能在第180个子午线上执行简单的任务(例如表示一个区域或一条线)。一些例子:

  • GeoJSON规范在其规范中并未提及对第180条子午线的处理,因此,跨越第180条子午线的线的表示也可以解释为遍历世界。

  • 在OpenStreetMap中,区域(例如俄罗斯边界)在第180个子午线上被分割。

我的理解是,GeoJSON没有特定的跨时间跨度特征的标准表示形式,并且故意将其含糊不清(多部分几何形状可能会解决此问题)。类似地,在OpenStreetMap中,后子午线处有几何划分,尽管我不知道这样的拆分要素是多部分的还是实际上是离散的记录。

这带来了相当大的问题,尤其是从提出跨越此线的边界框或其他空间请求的角度而言,而且在解析和清理输入以及对要素几何的任何更新方面也是如此。这就是为什么我试图确定我可以寻求遵循的最佳实践的原因。


1
这是一个非常好的问题,以前我使用的是从90度开始的手工坐标系,但我只关心一个很小的区域。确实没有任何东西可以适当地“环绕”;我猜这是因为没有(重要的)跨度超过180,而且很少有人需要绘制整个图,整个问题很少受到关注。
Michael Stimson

好问题。我认为您对第4点很感兴趣,尽管实际上没有理由使用mod来恢复坐标不能超出360。Delta听起来像是最可扩展的解决方案,甚至可以在数据压缩方面带来一些好处,但是正如您所说的,将责任转移给了客户。
约翰·鲍威尔

自1.0 RC起,有关GeoJSON的一些注释已过时。一个示例是,不推荐使用GeoJSON中的CRS定义(sgillies.net//2014/08/06/pruning-crs-from-geojson.html)。我最终将对此进行编辑。
alphabetasoup

Answers:


7

纯粹从数据存储和分析的角度来讲,geographyPostGIS类型在设计时就考虑到了后院(在多个设计目标中)。有几种专门针对该geography类型设计的功能

例如,考虑跨越斐济塔韦乌尼岛(用Great Circle Mapper映射)的LineString ,它跨越了antimeridian:

SELECT ST_Length('LINESTRING(179.9 -17, -179.8 -16.7)'::geography);

测地线的长度约为46公里。同样,即使经度坐标在+179和-179之间跳跃,ST_Area也可以在岛的Polygon上正常工作。

将EPSG:4326 geometry转换为geography类型也会对​​坐标进行规范化,例如最后一个坐标的经度> 180:

SELECT ST_AsGeoJSON('LINESTRING (179.9 -17, 180.2 -16.7)'::geography);

NOTICE:  Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY
                           st_asgeojson
------------------------------------------------------------------
 {"type":"LineString","coordinates":[[179.9,-17],[-179.8,-16.7]]}

geography在第一个示例中被转换回完全相同的类型,但现在具有GeoJSON输出。您可以选择忽略NOTICE(或例如SET client_min_messages TO WARNING;),并将各种有趣的几何形状转换为geography类型。


geography在PostGIS外部的地图上显示类型是另一回事,希望在这方面有更好的答案。


2
一个局限性是,地理区域的长度不应超过/大于180º(请参阅高级FAQ)。但是,您可以只对顶点使用此规则,然后做一些愚蠢的事情,例如LINESTRING(179.9 -17, 60 -16.9, -60 -16.8, -179.8 -16.7),将其环绕。
Mike T

0

当然,首选答案是(1),即让客户做“正确的事情”。要考虑的一个好例子是此kml文件近似的代表南极洲的多边形

<kml> <Folder> <name>Antarctica</name> <Placemark> <name>Antarctica</name> <Polygon> <tessellate>1</tessellate> <outerBoundaryIs> <LinearRing> <coordinates> -58,-63.1,0 -74,-72.9,0 -102,-71.9,0 -102,-74.9,0 -131,-74.3,0 -163,-77.5,0 163,-77.4,0 172,-71.7,0 140,-65.9,0 113,-65.7,0 88,-66.6,0 59,-66.9,0 25,-69.8,0 -4,-70,0 -14,-71,0 -33,-77.3,0 -46,-77.9,0 -61,-74.7,0 -58,-63.1,0 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> </Folder> </kml>

经度中断发生处的Delta编码或移位对此类数据无济于事。将其工作到特定于南极洲的投影将起作用,但这并不是一个通用的解决方案。

令人惊讶的是,Google Earth Pro无法正确显示此多边形(除非您使用“轮廓”模式)。看这里 Google Earth Pro的屏幕截图


我对Google Earth不太了解,所以我不知道如何启用轮廓模式。但是这里您有一个有效的多边形,该多边形跨越了子午线,并且在您的图像中我们看到Google Earth无法正确渲染它:因此,如果Google Earth无法应对,那么如何证明将歧义传递给客户端应用程序是最佳实践呢?它?顺便说一句,QGIS给我提供了SRID 4326中此多边形的渲染问题,但是如果我在反子午线处引入了一条线(除非...好了,这条线),我就没有渲染问题。如果使用南极立体投影,则原始效果会很好。
alphabetasoup

很公平。但是,由于kml坐标仅限于纬度和经度,因此在此特定示例中,用户(用户)无法采取任何措施来帮助Google Earth。Google Earth维护人员有责任在客户端解决此问题。(不幸的是,他们这样做的意愿很小!)
cffk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.