Лучшие практики для баз данных и API с географическими данными, охватывающими антимеридиан

24

Какова наилучшая практика для хранения географических объектов (линий, многоугольников и их многочастных эквивалентов), когда эти объекты охватывают антимеридиан (долгота ± 180 °), и их необходимо отправлять и получать из клиентских веб-приложений как GeoJSON?


Я начинаю работу над веб-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. Дельта-кодирование , как в TopoJSON (например, начало (0,-179)и следующая координата - -3широта на запад). Я понятия не имею, следует ли это реализовать при хранении данных в PostGIS или нет, но это отличное решение для отправки данных в клиентские приложения.
  8. Некоторая форма векторных обозначений или полярных координат. (Кажется, довольно сложно и необычно.)

Из них мне не нравятся идеи 2–5, потому что они не являются общими, но они мне нравятся, потому что они имеют смысл для моего конкретного приложения. Для приложений, работающих только с данными в Тихом океане, они могут иметь большой смысл, поэтому я не хочу полностью сбрасывать их со счетов как варианты.

Идеи 6 и 7 были взяты из блога Тома МакВрайта , который стоит прочитать, но не является окончательным в отношении антимеридиана.

Идея 4 используется GeographicaGSGeodesicLinesToGISPython , которая, в свою очередь, использует fiona.transform.transform_geomантимеридианное смещение на 360 °. В свою очередь, Фиона использует OGR -wrapdateline. Я полагаю, это очень серьезный прецедент и на самом деле довольно общий.

В связи с проблемой хранения мне нужно рассмотреть, как такие функции следует отправлять в клиентские приложения, и как мое приложение должно учитывать данные, отправленные обратно в него (например, прогнозист-человек, изменяющий траекторию прогноза циклона в Тихом океане). Формат обмена, вероятно, будет GeoJSON, но не обязательно.

К сожалению, спецификация GeoJSON не является явной в вопросах антимеридиана. Это из Википедии :

Многие географические библиотеки программного обеспечения или форматы данных проецируют мир на прямоугольник; очень часто этот прямоугольник разбивается ровно на 180 меридиане. Это часто делает невозможным выполнение простых задач (например, представление области или линии) на 180-м меридиане. Некоторые примеры:

  • Спецификация GeoJSON не упоминает обработку 180-го меридиана в своей спецификации, поэтому представления линий, пересекающих 180-й меридиан, также можно интерпретировать как движение по миру.

  • В OpenStreetMap области (например, граница России) разделены на 180 меридиане.

Мое чтение состоит в том, что GeoJSON не имеет конкретного стандартного представления антимеридиановых функций, и он намеренно оставлен неоднозначным (геометрия из нескольких частей, возможно, решит проблему). Точно так же в OpenStreetMap на антимеридиане есть геометрические деления, хотя я не знаю, являются ли такие разделенные объекты множественными или фактически дискретными записями.

Это кажется довольно проблематичным, особенно с точки зрения создания ограничивающего прямоугольника или других пространственных запросов, которые охватывают эту линию, а также при разборе и очистке входных данных и любых обновлений геометрии элементов. Вот почему я пытаюсь определить наилучшую практику, которой я могу стремиться соответствовать.

alphabetasoup
источник
1
Это действительно хороший вопрос, ранее я использовал ручную систему координат, начинающуюся с 90 градусов, но меня интересовала только очень маленькая область. Там действительно нет ничего, чтобы "обернуть" должным образом; Я предполагаю, что это потому, что нет никакого сухопутного массива (важного), расположенного между 180, и очень немногие люди должны наносить на него карту, всей проблеме уделяется очень мало внимания.
Майкл Стимсон
Отличный вопрос Я думаю, что вы искушаете судьбу с помощью пункта 4, хотя на практике нет причин, по которым координаты не могут выходить за пределы 360, используя мод для их восстановления. Дельта звучит как наиболее расширяемое решение и может даже принести некоторую выгоду с точки зрения сжатия данных, но, как вы говорите, переносит ответственность на клиента.
Джон Пауэлл
Некоторые комментарии о GeoJSON теперь устарели с версии 1.0 RC. Одним из примеров является то, что определения CRS в GeoJSON устарели ( sgillies.net//2014/08/06/pruning-crs-from-geojson.html ). Я отредактирую это в конце концов.
alphabetasoup

Ответы:

7

Говоря исключительно с точки зрения хранения и анализа данных, geographyтип PostGIS был разработан с учетом антимеридиана (среди нескольких целей разработки). Есть несколько функций, специально разработанных для данного geographyтипа .

Например, рассмотрим LineString через Тавеуни, Фиджи ( сопоставленный с Great Circle Mapper ), который расположен между антимеридианом:

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

Длина этой геодезической составляет около 46 км. Точно так же ST_Area будет правильно работать на полигоне острова, даже если координаты долготы прыгают между +179 и -179.

Преобразование 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. Вы можете игнорировать УВЕДОМЛЕНИЕ (или, например, 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), которые бы-обертки вокруг.
Майк Т
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>

Дельта-кодирование или сдвиг, где происходит разрыв долготы, не поможет с такими данными. Работая с проекцией, специфичной для Антарктиды, сработает, но вряд ли это общее решение.

Удивительно, но Google Планета Земля Про не отображает этот многоугольник правильно (если вы не используете режим «контур»). Глянь сюда снимок экрана с Google Планета Земля Про

cffk
источник
Я не знаю много о Google Планета Земля, поэтому я не знаю, как включить режим контура. Но здесь у вас есть действительный многоугольник, который охватывает антимеридиан, и на вашем изображении мы видим, что Google Планета Земля не может правильно его отобразить: как же это доказательство того, что передача неоднозначности клиентскому приложению является наилучшей практикой, если Google Планета Земля не может справиться с этим? Это? Кстати, QGIS дает мне проблемы с рендерингом с этим многоугольником в SRID 4326, но не в том случае, если я введу линию на антимеридиане (кроме ... ну, конечно, линии). Оригинал очень блестящий, если я использую антарктическую стереографическую проекцию.
alphabetasoup
Справедливо. Однако, учитывая, что координаты kml ограничены широтой и долготой, вы, пользователь, ничего не можете сделать, чтобы помочь Google Планета Земля в этом конкретном примере. Ответственность за решение этой проблемы на стороне клиента лежит на сопровождающих Google Планета Земля. (К сожалению, они демонстрируют небольшую склонность к этому!)
cffk