Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Пользовательские Инструменты
                Введение в морскую навигацию

Введение в морскую навигацию

Опубликованно: 04.07.2017, 20:00
Последняя редакция, Andry: 04.03.2018 14:08

Следующий урок: Визуализация 3D-карт

В этой статье описывается инструмент проекция меркатора JME. Если вы не знаете, что это значит, мы предлагаем начать с чтения Американского практического навигатора или просмотра Википедии. Если вы знаете, что такое проекция Меркатора, то наше «Введение в морскую навигацию» может помочь вам освежить ваш знания.

Википедия является источником приведенных здесь формул. Прочтите. Изучите это. Для тех кто не знает английский можете почитать статьи здесь.

Термины, условное обозначения и определения карт определяются как «графические изображения зон Земли использующиеся в морской или воздушной навигации, для осуществления которой морские карты изображают особенности поверхности земли, представляющие особый интерес для мореплавателей [1].

Нулевой меридиан обозначается Гринвичским меридианом с 1884 года.

Расстояние обозначается в морских милях, где одна морская миля соответствует одной меридианной дуге (1852 метра) на экваторе.

Мореходство использует различным математическим методы определения курса, расстояния и положения. Скорость относится к скорости движения или расстоянию за единицу времени и измеряется в узлах (kn). Один узел равен одной морской миле в час.

Координаты координаты нужны что бы определять точное местоположение на земле. Для целей этого проекта важны только широта и долгота, хотя читатель должен знать, что существуют другие системы координат, такие как UMT (Universal Transverse Mercator) и UPS (Universal Polar Stereographic).

Широта — это угловое расстояние от экватора, измеряемое на север или на юг вдоль меридиана от 0° на экваторе до ±90° на полюсах [1]. В авиации и морском судоходстве широта обозначается как северная (N — по русски С) или южная (S — по русски Ю), чтобы указать направление измерения. В системе обозначений север (С) должен быть положительным, а юг (Ю) отрицательным. Например, 18° С становится 18, а 18° Ю становится -18. Долгота — это угловое расстояние между главным меридианом и меридианом точки на Земле, измеряемое на восток или на запад от основного меридиана на 180°. Она обозначается восточная (E — по русски В) или западная (W — по русски З), чтобы указать направление измерения [1], однако подобно угловому измерению экватора, может быть выражена через отрицательные (З) и положительные (В) значения. Например, 18° В становится 18, а 18° З становится -18. Стоит отметить, что градусы можно далее подразделить на минуты, при этом один градус равен 60 минутам. Минуты в свою очередь подразделяются на секунды, для которых одна минута равна 60 секундам. Поэтому координаты широты и долготы обычно определяются как градусы (°), минуты (′) и секунды (″).

Например: 1° 2′ 3″ З означает 1° градус, 2 минуты и 3 секунды на Запад. Это, в свою очередь, может быть переведено в десятичную систему исчисления, в которой градусы выражаются в виде десятичной дроби: поэтому 1° 2′ 3″ З станет -1.034167. В качестве альтернативы эти угловые измерения так же можно преобразовать в радианы (в этом случае они будут выражаться как дробь π со знаком ±).

Разница в широте между двумя разными местами — это угловая длина дуги любого меридиана(долготы) между их параллелями(широтами). То есть, это численное различие между широтами, если места находятся на одной стороне от экватора или сумма широт, если точки находятся на противоположных сторонах относительно экватора. [1]

Подобная разница и у долготы между двумя разными местами — короткая дуга из параллели(широты) или маленький угол на полюсе между меридианами(долгота) двух мест. Если оба места находятся на одной стороне (т.е. на востоке или западе) от Гринвича, то разница долготы — это численное различие между долготой двух мест; В противном случае разницей долготы является их числовая сумма (если, конечно, она не превышает 180°. В этом случае она равна 360° минус сумма).

globe_lat_long

Меридиональные части — Как описывал Боудич, меридиональные части это «единицы широты, которые были скорректированы для компенсации искажений, возникающих в результате проецирования трехмерного глобуса на двумерную карту Меркатора».

Пеленг(Bearing) — В морской навигации пеленг определяется как «направление одного объекта относительно другого объекта, как правило, направление объекта относительно вашего судна». Обратите внимание, что это не следует путать с эквивалентным термином в авиации, поскольку пеленг относится к «настоящему (скорректированному) направлению по компасу, курсу движения вперёд самолёта».

Направление и Курс(Heading and Course) — это направление, в которое судно направлено, выражается в градусах от 0° до 359°. Курс — это надземный путь, по которому движется судно. Из-за ветра, движения воды и ошибок рулевого управления, направление и курс не обязательно будут равны.

Проекция Меркатора — является стандартом в морских картах, представляющий собой линий румба (Также известная, как Локсодрома) как прямые сегменты. Проекция Меркатора имеет нелинейный масштаб, поскольку она учитывает искажение по широте, возникающее при отдалении от экватора к полюсам (при этом полюса определяются как бесконечность. Это понятие показано справа на рис. 1.2). Эти искажения возникают из-за того, что земля является сплюснутой сферой, то есть сферой с плоским верхом и низом (полюсами). Поэтому, когда человек отходит от экватора, морские метрики искажаются до такой степени, что длина одной градуса широты вдоль полюсов покрывает примерно на 1% процент больше расстояния, чем на экваторе.

Проектирование карт

Проекция Меркатора определяется её меридианами и параллелями, каждая из которых расширяются в равном соотношении с увеличением широты. Это расширение связано с искажением, которое возникает в результате проецирования сплющенного сфероида на двумерную поверхность (см. Вступительные примечания выше) и соответствует секущей широты в дополнение к поправке на это искажение. Заметим, что секущие на 90° бесконечны, и поэтому проекции Меркатора не могут включать полюса (таким образом, Проекция Меркатора, используемая здесь, заканчивается на 85° севернее и южнее экватора).

Линий румба предстают как прямые.

Расчет проекции обрабатывается классом MapModel2D, в случае с 2D и MapModel3D, в случае с 3D проекцией. По своему принципу обе проекции функционируют одинаково, их единственные реальные отличия в том, что MapModel3D вводит дополнительную координату (z) и так же заменёны методы toPixel() с toWorldUnit(), которые преобразует координаты объекта широту/долготу в (x,y,z) мировые единицы, и координаты пикселя (x,y). Основная функциональность всей системы основана на точном преобразовании широты/долготы в пиксельные/мировые единицы, и наоборот. Эти преобразования обрабатываются toPixel(), toWorldUnit() и toPosition(). Обратите внимание, что вся навигация, используемая этим классом, находятся внутри класса NavCalculator и будут рассмотрены в следующем разделе этой главы.

Минута на пиксель/Минута на Мировую Единицу(Minutes per pixel/Minutes per World Unit) — Количество Пикселей или Мировых Единиц в минуту служит базовой линией для всех преобразований координат и получается путем деления общего количества минут долготы, составляющих карту (т.е. 360 * 60), на ширину холст, для рендеринга проекции (Так же называемом viewport): minutesPerPixel = (mapWidthInLongitude * 60) / (double) viewportWidth;

toPixel — В отличие от общепринятого, этот метод не получен из обратной Функции Гудермана. Принимая набор координат широты/долготы, инкапсулированных в объекте Position как параметры, метод возвращает эквивалентный пиксель (x,y), инкапсулированный в качестве объекта Point. Это преобразование можно суммировать следующим образом [2]:

  1. Получим Элемент Упорядоченного Списка, расстояние между координатой долготы данного положения и центром долготы карты.
  2. Преобразуем полученное расстояние в пиксели, разделив его на количество пикселей которые содержатся в одной минуте. Обратитесь к нему как distanceInPixels.
  3. Вычислите x-координату, отнимая или прибавляя её к координате x-центра холста (координата x-центра холста — это ширина холста, разделенная на два) в зависимости от собственного местоположения и центра карты: Если центр карты находится к западу от главного меридиана, и если положение, которое должно быть преобразовано, находится к западу от центра, то полученная x-координата представляет собой разницу между x-центром и distanceInPixels, полученном в шаге 2 выше. Однако если центр находится на Западе, а местоположение находится к востоку от центра, то отсюда следует что x-координата соответствует с сумме x-центра и его distanceInPixels. Противоположное верно для восточного центра и местоположения к западу от этого центра или восточного центра и местоположение к востоку от этого центра.
  4. Для Элементов Упорядоченного Списка разница y-координаты в меридиональных частях, между центром широты карты и широтой местоположения служит в качестве базовой линии. Преобразуйте разницу в пиксели, разделив её на количество пикселей

В течение одной минуты. Обратитесь к нему как dmp1.

  1. Подобные Элементам Упорядоченного Списка выше в шаге 3, вычислите y-координату путем вычитания или

прибавления её к координате y-центра холста (холст y-центра — высота холста, деленная на два) в зависимости от собственного местоположения и центра карты: То есть, если центр находится на севере и местоположение находится к северу от центра, то полученные y-координаты соответствуют разности между dmp и координатой y-центра. Однако если центр находится на севере, но местоположение южнее центра, то полученная y-координата равна их сумме. Противоположное верно если центр лежит в южном полушарии.

Далее преобразует координатную пару широты/долготы в вектор мировых-единиц JME:

try {
    int worldWidth = 800;
    MapModel3D m = new MapModel3D(worldWidth);
    Vector3f v = m.toWorldUnit(new Position(-53, 8.0));
} catch (InvalidPositionException e) { e.printStackTrace(); }

Чтобы преобразовать мировые единицы в координаты широты/долготы, используйте к модели карты метод toPosition:

try {
     int worldWidth = 800; MapModel3D m = new MapModel3D(worldWidth);
     Position pos = m.toPosition(new Vector3f(10, 10, 10));
     System.out.println("Latitude: " + pos.getLatitude() + " Longitude: " + pos.getLongitude());
} catch (InvalidPositionException e) {
     e.printStackTrace();
}

Навигационные вычисления выполняются внутри класса NavCalculator.

Плавание по Локсодромии(Mercator Sailing) — Плавание по Локсодромии определяется как «процесс решения проблем, связанных с курсом, расстоянием, разностью широт и разностью долгот, рассматривая их применительно к карте Меркатора» [1]. По сути, это относится к построению линии румба на карте Меркатора, в которой линия румба будет в виде прямой линии. То есть, учитывая постоянный пеленг β к северу от линии румба, долготу λ0 где линия проходит экватор, λ1 — являющийся любой точкой долготы линии румба, а φ — являющийся любой точкой широты на линии румба, тогда ее проекция Меркатора может быть выведена в виде:

  • x = λ1
  • y = m(λ1 − λ0)

Где наклон m является cot(β), кроме того λ и φ могут быть выражены как

  • x = λ1
  • y = tanh−1(sin(φ) φ = sin−1(tanh(m(λ1 − λ0)))

То есть, tan(course) = (differenceinlongitude)/(differenceinmeridionalparts) и distance = (differenceinlatitude/cos(course)), где разница в меридиональных частях определяется в терминах Сфероида Кларка.

Это выполняется следующим образом, где RLSailing и Position являются классами-оболочками.

public RLSailing mercatorSailing(Position p1, Position p2) {
     double dLat = computeDLat(p1.getLatitude(), p2.getLatitude());
     if (dLat == 0) {
          RLSailing rl = planeSailing(p1, p2); return rl;
     }
     double dLong = computeDLong(p1.getLongitude(), p2.getLongitude());
     double dmp = (float) computeDMPClarkeSpheroid(p1.getLatitude(), p2.getLatitude());
     trueCourse = (float) Math.toDegrees(Math.atan(dLong / dmp));
     double degCrs = convertCourse((float) trueCourse, p1, p2);
     distance = (float) Math.abs(dLat / Math.cos(Math.toRadians(trueCourse)));

     RLSailing rl = new RLSailing(degCrs, (float) distance);
     trueCourse = rl.getCourse();
     return rl;
}

Где dmp означает разницу в меридиональных частях.

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

Хотя другие датумы (например, WGS 84) одинаково действительны, навигационный модуль выполняет все вычисления в контексте сфероида Кларка 1880 года, который имеет экваториальный радиус 6,378,249.145 метров, полярный радиус 6,356,514.870 метров и обратное уплощение 293.465 метров. Меридиональная часть для любой широты L поэтому определяется как: M = 7915.704468 ∗ log(tan(45 + (L/2))) − 23.268932 ∗ (sin(L)) − 0.052500 ∗ (sin(L))3 − 0.000213 ∗ (sin(L))5

Где m1 и m2 относятся к меридиональным частям точки смещения и место назначения, соответственно разность меридиональных частей рассчитывается как |m1 − m2| Если обе точки севернее или южнее экватора, или как их сумма, если одна из точек находится на севере, а другая к югу от экватора:

public static double computeDMPClarkeSpheroid(double lat1, double lat2) {
     double absLat1 = Math.abs(lat1); double absLat2 = Math.abs(lat2);
     double m1 = (7915.704468 * (Math.log(Math.tan(Math.toRadians(45 + (absLat1 / 2)))) / Math.log(10)) - 23.268932 *
 Math.sin(Math.toRadians(absLat1)) - 0.052500 * Math.pow(Math.sin(Math.toRadians(absLat1)), 3) - 0.000213 *
 Math.pow(Math.sin(Math.toRadians(absLat1)), 5));
double m2 = (7915.704468 * (Math.log(Math.tan(Math.toRadians(45 + (absLat2 / 2)))) / Math.log(10))
- 23.268932 * Math.sin(Math.toRadians(absLat2)) - 0.052500 * Math.pow(Math.sin(Math.toRadians(absLat2)), 3) - 0.000213 * 
Math.pow(Math.sin(Math.toRadians(absLat2)), 5));
     if ((lat1 <= 0 && lat2 <= 0) || (lat1 > 0 && lat2 > 0)) {
          return Math.abs(m1 - m2);
     } else {
          return m1 + m2;
     }
}

Преобразование курса(Course Conversion) — преобразование истинного курса в эквивалентный компасный курс (т.е. преобразование истинного курса к курсу целей над землей (COG), где «истинный курс» определяется как курс, направляемый от истинного севера) используемый методом mercatorSailing, достигается путем вычитания вариации курса от истинного курса, где вариация представляет собой угловую разницу между истинным севером и направлением магнитного поля Земли (следовательно, вариация называется Востоком или Западом в зависимости от положения цели относительно истинного севера). Учитывая истинный курс между двумя местоположениями, COG рассчитывается вызовом NavCalculator.convertCourse(tc, p1, p2)

Разница в Широте(Difference in Latitude) — Разница в широте зависит от полушария, в котором оба местоположения могут быть определены путем вызова NavCalculator.computeDLat(lat1, lat2).

Разница в Долготе(Difference in Longitude) — Как и разница в широте, разница в долготе зависит от того, с какой стороны от главного меридиана находятся оба местоположения, и может быть определена путем вызова NavCalculator.computeDLong(long1, long2).

Пеленг(Bearing) — Направление, в котором одна цель находится относительно другой. Учитывая широту двух точек (φ0 и φ1) и долготу двух точек (λ0 и λ1), пеленг (θ) определяется следующим образом: Пусть dLon — разность долготы λ0 и λ1, тогда

  • x = (sin(dLon) ∗ cos(φ1)
  • y = cos(φ0) ∗ sin(φ1) − sin(φ0) ∗ cos(φ1) ∗ cos(dLon))
  • θ = 2arctan√ θ = atan2(y, x)
  • y

x2+y2+x

Что можно задать следующим образом:

try {
     double bearing = NavCalculator.computeBearing(new Position(-53.6, 8.1), new Position(-53, 8.
  } catch (InvalidPositionException e) {
     e.printStackTrace();
  }

Смотрите так же:


    1. Натаниэль Боудич (1995), Американский практический навигатор. Правительство Соединенных Штатов, Издание национальной океанической службы.

    2. Gebruers C., «JMarine

Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.