Как я могу сделать обтекание полилинии по всему миру?


14

Я использую карты листовок, чтобы создать представление о кругосветном вызове. Я хотел бы добавить полилинию, которая направляется на восток от Токио, а затем появляется на карте к западу от Южной Америки, но вместо этого я получаю линию, которая пересекает карту в противоположном направлении (см. Желтую линию).

введите описание изображения здесь

Я думаю, что это, вероятно, связано с датами и / или системами координат, но я немного схематичен в деталях. Может ли кто-нибудь объяснить теорию, стоящую за тем, что мне нужно сделать, чтобы заставить это работать? Я использую прогноз bluemarble от Nasa:

var bluemarble = new L.TileLayer.WMS("http://demo.opengeo.org/geoserver/wms", {
layers: 'bluemarble',
attribution: "Data © NASA Blue Marble, image service by OpenGeo",
minZoom: 2,
maxZoom: 5
});

2
Вам нужно разбить ломаную линию на меридиане + -180 градусов. Это требует нахождения широты, на которой ломаная пересекает этот меридиан. Ваша ГИС, вероятно, имеет методы для взлома. Если нет, простое решение может быть получено из кода, показанного в связанном потоке . Можете ли вы выполнить подобный код на своей платформе?
whuber

Я согласен с Whuber. Мне пришлось выполнить аналогичную задачу с пересечением полигонов + - 180. Вы должны разбиваться на несколько полилиний / полигонов каждый раз, когда вы пересекаете + -180.
Стив

Ответы:


13

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

  • Полилиния представлена ​​в виде последовательности вершин , каждая из которых представлена ​​в форме (широта, долгота) с -180 <= lon <= 180. Вам необходимо проверить каждую последующую пару, чтобы увидеть, пересекает ли она меридиан + -180. Существует быстрый тест: если абсолютное значение разности долгот составляет 180 или больше, происходит пересечение.

  • Внутри каждого сегмента (lat0, lon0) -> (lat1, lon1), который пересекает меридиан + -180, необходимо разбить ломаную на две части, где она пересекается.

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

Пусть рассматриваемый отрезок проходит из точки 0 в точке (lat0, lon0) в точку 1 в точке (lat1, lon1). Точку разрыва можно найти, запустив отрезок прямой линии в 3D между двумя точками, представленными в декартовых координатах, и найдя, где координата y равна нулю. В декартовы координаты являются

(x0, y0, z0) = (cos(lon0)*sin(lat0), sin(lon0)*sin(lat0), cos(lat0))

и аналогичное выражение, дающее (x1, y1, z1) для точки 1. Решите уравнение

t * y0 + (1-t) * y1 = 0

для т; то есть,

t = y1 / (y1 - y0).

Поэтому координаты пересечения

(x, y, z) = (t * x0 + (1-t) * x1, 0, t * z0 + (1-t) * z1)

Эта точка (которая лежит под поверхностью земли где-то под меридианом + -180) имеет широту, равную

lat2 = ATan(z/x).

Точка останова должна быть представлена ​​двумя способами. Прикрепляя его после (lat0, lon0) для завершения первой части ломаной ломаной линии, используйте (lat2, -180), если lon0 отрицательно, и используйте в противном случае (lat2, 180). Прикрепляя его перед (lat1, lon1), чтобы начать вторую часть ломаной ломаной линии, следуйте аналогичному правилу.

В исключительных случаях одна или обе точки 0 и 1 могут находиться на меридиане + -180. Следуя этой процедуре, вы поместите сегмент нулевой длины на одну из созданных вами полилиний. Если это может вызвать проблемы с ГИС, проверьте это условие.

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


1
То, что сказал whuber, в порядке, но я думаю, что в следующем предложении есть опечатка:> При присоединении его после (lat0, lon0), чтобы завершить первую часть ломаной> ломаной, используйте (lat2, -180), если lat0 отрицателен, и в противном случае используйте (lat2, 180). Я думаю, что это должно быть:> использовать (lat2, -180), если lon0 отрицателен, а в противном случае использовать (lat2, 180)
Georgi

@ Георгий Спасибо, что поймали это; Я думаю, что вы правы, и я внесу изменения.
whuber

Я должен был реализовать это в Leaflet.js, вот мой код: gist.github.com/mikeatlas/0b69b354a8d713989147
Майк Атлас,

Спасибо, Майк. Мне нравится зигзагообразная иллюстрация: это именно то обстоятельство, которое я представлял, когда писал этот ответ. Если вы хотите действительно серьезный тест, посмотрите, что происходит с ломаной, которая проходит вдоль самого меридиана + -180 градусов (и пересекает оба полюса)!
whuber

@whuber Мне, возможно, просто нужно попробовать это: / Опубликовать результаты
Майк Атлас

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.