/ Разработчикам / Исправление границ

Исправление границ

Границы полей редко поступают в идеальном виде. Launch Pad пропускает каждую границу через автоматический конвейер коррекции геометрии, который обнаруживает некорректные фигуры и исправляет их до начала планирования, поэтому планы проходов всегда строятся на чистой, корректной геометрии.

Большинство проблем с границами незаметны

Некорректная геометрия на удивление часто встречается в реальных данных о границах, и в большинстве случаев её не видно на карте: самопересечение может скрываться в одной-единственной вершине. Большинство клиентов даже не догадываются о таких проблемах в своих границах, потому что Launch Pad исправляет их автоматически. Если вы интегрируетесь с API и не понимаете, почему полученная обратно граница немного отличается от отправленной, эта страница объясняет, что произошло и почему.

Откуда берётся некорректная геометрия

Ручное редактирование

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

Сторонние сервисы

Границы, изменённые подключёнными платформами (например, John Deere Operations Center), могут возвращаться топологически некорректными.

Файлы со смешанным содержимым

Загруженные файлы иногда содержат лишние точки, линии или коллекции геометрий вместо чистых полигонов.

Больше, чем простое "make valid"

Большинство ГИС-платформ исправляют повреждённую геометрию одной операцией "make valid" (автоматическим приведением геометрии к корректному виду). Она устраняет топологическую ошибку, но действует грубо и никак не учитывает, насколько пригодной окажется граница поля после исправления. Launch Pad вместо этого применяет последовательность целевых исправлений, а общее исправление "make valid" оставляет как запасной вариант для случаев, с которыми целевые методы не справляются.

Фильтрация

Точки, линии и другая неплощадная геометрия удаляются, чтобы дальше проходили только полигоны.

Разделение

Самопересекающиеся внешние границы разделяются на отдельные корректные полигоны вместо отбрасывания части поля.

Объединение

Перекрывающиеся или пересекающиеся отверстия объединяются в одно отверстие, как того требует спецификация.

Буферизация

Кольца буферизуются с небольшим допуском, чтобы отверстия никогда не имели общих рёбер с внешней границей.

Реконструкция

Отверстия вычитаются из внешних границ для пересборки чистого MultiPolygon, при этом любое отверстие, выходящее за пределы своей оболочки, обрезается.

Удаление мелких фрагментов

Мелкие фрагменты площадью меньше минимальной отбрасываются, если только они не являются единственной частью поля.

Нормализация

Порядок обхода колец соответствует правилу правой руки GeoJSON, координаты приводятся к 2D, а любые значения высоты удаляются.

Резервное исправление

Универсальное исправление "make valid" обрабатывает самопересечения и другие ошибки, которые остаются после целевых шагов.

Что означает "валидный"

Результатом работы конвейера всегда является валидный MultiPolygon, соответствующий правилам валидности полигонов и MultiPolygon согласно OGC Simple Features Specification:

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

Внешнее кольцо (оболочка)

Внешняя граница полигона. У каждого полигона она ровно одна.

Внутреннее кольцо (отверстие)

Внутренняя граница, вырезанная из полигона, например заболоченный участок или груда камней. У полигона может быть много отверстий.

MultiPolygon

Набор полигонов. Поле из двух отдельных участков представляет собой один MultiPolygon с двумя полигонами.

Объединение

Операция объединения геометрий: слияние перекрывающихся фигур в одну.

Как работает конвейер

  1. 1
    Нормализация входных данных. Сохраняется только полигональная геометрия. Точки, линии и другие неплощадные элементы коллекций геометрий отбрасываются, а внешние кольца извлекаются.
  2. 2
    Проверка каждого кольца. По очереди проверяется каждый внешний полигон, затем каждое внутреннее кольцо.
  3. 3
    Исправление самопересечений. Самопересекающиеся внешние кольца разделяются на отдельные полигоны. Пересекающиеся внутренние кольца объединяются. Если объединение не устраняет пересечение внутри основной оболочки, полигон обрабатывается общим исправлением "make valid".
  4. 4
    Буферизация колец. Каждое кольцо буферизуется с небольшим допуском, чтобы внутренние кольца никогда не имели общих рёбер с внешним кольцом.
  5. 5
    Пересборка результата. Внутренние кольца вычитаются из внешних, формируя итоговый валидный MultiPolygon. Отверстия, выходящие за пределы оболочки, обрезаются по содержащей их оболочке, а отверстие, целиком лежащее вне всех оболочек, сохраняется как отдельный полигон, а не отбрасывается.

Если входные данные невозможно спасти, например когда после удаления некорректных частей ничего не остаётся, Launch Pad сообщает об ошибке, а не придумывает фигуру, и каждый шаг коррекции записывается в журнал, чтобы результат можно было проверить.

Примечание: Обработка выполняется в проекционной системе координат, где расстояния измеряются в метрах, а результат преобразуется обратно в WGS84. Именно поэтому допуски буферизации задаются в метрах, а не в градусах.

Примеры до и после

Пять характерных случаев некорректной входной геометрии (синим) и исправленного результата (жёлтым). Разверните WKT, чтобы увидеть точные координаты.

Случай 1: Смешанные типы геометрии

На входе вместо MultiPolygon поступает GeometryCollection, и наряду с самим полигоном она содержит LineString и Point. Линия и точка удаляются, а из полигона извлекается внешнее кольцо.

Исходная геометрия
Исходная геометрия, содержащая полигон, а также лишнюю линию и точку
Исходный WKT
GEOMETRYCOLLECTION (LINESTRING (131 125, 305 326),
  POINT (260 130),
  POLYGON ((130 330, 223 330, 223 245, 130 245, 130 330)))
Результат
Результат: один чистый полигон, линия и точка удалены
WKT результата
MULTIPOLYGON (((130 330, 223 330, 223 245, 130 245, 130 330)))

Случай 2: Самопересекающаяся граница

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

Исходная геометрия
Исходный полигон, контур которого пересекает сам себя, образуя фигуру в виде бабочки с выделенной точкой пересечения
Исходный WKT
POLYGON ((120 110, 120 360, 340 130, 310 360, 120 110))
Результат
Результат: бабочка разделена на два корректных полигона, соприкасающихся в одной точке
WKT результата
MULTIPOLYGON (((120 110, 120 360, 225.87639311043566 249.3110435663627, 120 110)),
  ((225.87639311043566 249.3110435663627, 310 360, 340 130, 225.87639311043566 249.3110435663627)))

Случай 3: Перекрывающиеся отверстия

Два внутренних кольца пересекаются друг с другом, что запрещено спецификацией. Отверстия объединяются в одно, и полигон пересоздаётся с единственным объединённым отверстием.

Исходная геометрия
Исходная геометрия с двумя перекрывающимися отверстиями внутри границы поля
Исходный WKT
-- outer boundary
POLYGON ((130 460, 550 460, 550 30, 130 30, 130 460))
-- inner boundary
MULTIPOLYGON (((230 110, 410 290, 470 100, 230 110)),
  ((370 380, 400 140, 200 200, 370 380)))
Результат
Результат: перекрывающиеся отверстия объединены в одно отверстие внутри границы
WKT результата
MULTIPOLYGON (((130 460, 550 460, 550 30, 130 30, 130 460),
  (292.3076923076923 172.30769230769232, 200 200, 370 380, 384.44444444444446 264.44444444444446, 410 290, 470 100, 230 110, 292.3076923076923 172.30769230769232)))

Случай 4: Перекрывающиеся внешние кольца

Несколько внешних колец перекрываются и самопересекаются, замыкая при этом пустую область. Кольца буферизуются и объединяются в единый контур, а замкнутая область сохраняется как полноценное отверстие.

Исходная геометрия
Исходная геометрия из нескольких перекрывающихся прямоугольников, образующих замкнутую петлю
Исходный WKT
MULTIPOLYGON (((107 153, 134.3 153, 134.3 121.6, 107 121.6, 107 153),
  (120 147, 120 176.2, 130.5 176.2, 130.5 147, 120 147)),
  ((125 174, 163 174, 163 168, 125 168, 125 174)),
  ((157.5 178.6, 191 178.6, 191 156, 157.5 156, 157.5 178.6),
    (170 166, 185 166, 185 135, 170 135, 170 166)),
  ((180 140, 180 136, 120 136, 120 140, 180 140)))
Результат
Результат: прямоугольники объединены в единый контур, охватывающий одно отверстие
WKT результата
MULTIPOLYGON (((170 136, 134.3 136, 134.3 121.6, 107 121.6, 107 153, 120 153, 120 176.2, 130.5 176.2, 130.5 174, 157.5 174, 157.5 178.6, 191 178.6, 191 156, 185 156, 185 135, 170 135, 170 136),
  (130.5 168, 130.5 153, 134.3 153, 134.3 140, 170 140, 170 156, 157.5 156, 157.5 168, 130.5 168)))

Случай 5: Отверстия вне оболочки

У поля два отдельных внешних кольца, и отверстия их не учитывают: одно отверстие перекрывает промежуток между двумя оболочками, а другие выступают за края. Каждая оболочка пересобирается отдельно, и каждое отверстие обрезается по содержащей его оболочке, с небольшим буфером, чтобы ни одно отверстие не имело общего ребра со своей оболочкой.

Исходная геометрия
Исходная геометрия с двумя отдельными контурами и отверстиями, которые пересекают их или лежат за их пределами
Исходный WKT
-- outer boundary
MULTIPOLYGON (((104 199, 165 199, 165 125, 104 125, 104 199)),
  ((170 150, 195 150, 195 132, 170 132, 170 150)))
-- inner boundary
MULTIPOLYGON (((158.44444444444446 144.33333333333334, 174 144.33333333333334, 174 139, 158.44444444444446 139, 158.44444444444446 144.33333333333334)),
  ((101 169, 159 169, 159 165, 101 165, 101 169)),
  ((136 122, 109.44444444444444 122, 109.44444444444444 151.55555555555554, 136 151.55555555555554, 136 122)))
Результат
Результат: два чистых полигона, каждое отверстие обрезано так, чтобы целиком помещаться внутри своего контура
WKT результата
MULTIPOLYGON (((170 150, 195 150, 195 132, 170 132, 170 150),
  (170.0010000000475 144.33333333333334, 174 144.33333333333334, 174 139, 170.0010000000475 139, 170.0010000000475 144.33333333333334)),
  ((104 199, 165 199, 165 125, 104 125, 104 199),
    (109.44444444444444 125.0010000000475, 109.44444444444444 151.55555555555554, 136 151.55555555555554, 136 125.0010000000475, 109.44444444444444 125.0010000000475),
    (164.9989999999525 139, 158.44444444444446 139, 158.44444444444446 144.33333333333334, 164.9989999999525 144.33333333333334, 164.9989999999525 139),
    (104.0010000000475 169, 159 169, 159 165, 104.0010000000475 165, 104.0010000000475 169)))

Связанные страницы