Пространственные координаты и расстояние в километрах

Это работает для меня. Например, используя chai для утверждений.

const chai = require('chai');
const expect = chai.expect;

describe('test', function () {

  function generateException() {
    throw new Error('test error');
  }


  it('should give an error', async ()=> {
    try {
      await generateException();
      expect(true).to.be.false;
    } catch(err) {
      console.log(err.message);
      expect(err.message).to.equal('test error');
    }
  })
})

Кажется, есть разница в способе использования Promise.reject() против throw new Error(). Когда функция generateException выдает ошибку, ваши тесты работают. Однако, если это было Promise.reject(), оно никогда не попадет в блок catch.

Если вы сделаете что-то вроде let result = await generateException();, вы увидите, что это ошибка, которую вы ожидаете, если функция geenerateException использует отклонение обещания.

Вы можете связать обещания с await, если захотите.

function generateException() {
  return new Promise(reject => {
   return reject(new Error('Promise Rejected');
})

it('should give an error', async ()=> {
  await generateException().catch(error => {
    expect(error.message).to.equal('Promise Rejected');

  })
});

Чтение частей этой статьи об асинхронном коде может немного помочь.

14
задан Community 23 May 2017 в 12:02
поделиться

5 ответов

У Вас есть серьезный случай магических чисел в коде. Выражение:

 (60 * 1.1515 * 1.609344 * 1000)

появляется дважды, но нет большого объяснения его. С некоторой справкой: 1.609344 число километров в миле; 60 число минут в градусе; 1000 число метров в километре; и 1.1515 число статутных миль в морской миле (спасибо, DanM). Одна морская миля является продолжительностью одной минуты широты на экватор.

Я предполагаю, что Вы используете сферическую наземную модель, а не сфероидальную землю? Алгебра не достаточно сложна, чтобы быть сфероидальной.

Первая формула - преобразование между двумя парами широты и долготы - нечетно. Вам нужны и дельта-lat (Δλ) и в дельта-lon (Δφ) для разбираний в ответе. Далее, расстояние между парами:

(60° N, 30° W), (60° N, 60° W)
(60° N, 60° W), (60° N, 90° W)

должно быть то же - но я вполне уверен, Ваш код производит различные ответы.

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

[... время передает... распаковку, сделанную...]

Учитывая сферический треугольник с углами A, B, C в вершинах и сторонах a, b, c напротив тех вершин (то есть, примыкают от B до C, и т.д.), Формула Косинуса:

cos a = cos b . cos c + sin b . sin c . cos A

Применяя это к проблеме, мы можем назвать две точки данными B и C, и мы создаем правильный сферический треугольник с прямым углом в A.

ASCII-творчество в его худшем:

                  + C
                 /|
                / |
            a  /  | b
              /   |
             /    |
            /     |
         B +------+ A
              c

Сторона c равна различию в долготе; сторона b равна различию в широте; угол A составляет 90 °, поэтому потому что = 0. Поэтому я верю уравнению для:

cos a = cos Δλ . cos Δφ + sin Δλ . sin Δφ . cos 90°

a = arccos (cos Δλ . cos Δφ)

Угол в радианах затем преобразовывается в расстояние путем умножения радиусом Земли. С другой стороны, данный в градусах (и части градуса), затем существует 60 морских миль до одного градуса, следовательно 60 * 1,1515 статутных мили, и 60 * 1.1515 * 1,609344 километра до одного градуса. Если Вы не хотите расстояния в метрах, я не вижу потребность в факторе 1 000.

Paul Tomblin указывает на Формуляр Авиации v1.44 как источник уравнения - и действительно, это там, вместе с более численно стабильной версией для того, когда разница в положении является небольшой.

Идя в базовую тригонометрию, мы также знаем что:

cos (A - B) = cos A . cos B + sin A . sin B

Применение этого дважды в уравнении, которое я дал, могло бы хорошо закончиться в формуле в Формуляре Авиации.

(Моя ссылка: "Астрономия: Принципы и Практика, Четвертый Выпуск" Roy E и Clarke D (2003); моя копия является первым выпуском с 1977, Adam Hilger, ISBN 0-85274-346-7.)


Выезд NB (Google) 'определяет: "морская миля"'; кажется, что морская миля - теперь 1 852 м (1,852 км) по определению. Множитель 1.1515 соответствует старому определению морской мили как приблизительно 6 080 футов. Используя bc с масштабом 10, я добираюсь:

(1852/(3*0.3048))/1760
1.1507794480

Который факторные работы для Вас зависит от того, какова Ваша основа.


Смотря на вторую проблему от первых принципов, у нас есть немного отличающаяся установка, и нам нужно 'другое' уравнение сферической тригонометрии, Формула Синуса:

sin A   sin B   sin C
----- = ----- = -----
sin a   sin b   sin c

Адаптация предыдущей схемы:

                  + C
                 /|
                / |
            a  /  | b
           |  /   |
           |X/    |
           |/     |
         B +------+ A
              c

Вам дают начальную точку B, удите рыбу X = 90º - B, длина (угол) a, и удите рыбу = 90 °. Что Вы, после b (дельта в широте) и c (дельта в долготе).

Так, мы имеем:

sin a   sin b
----- = ----
sin A   sin B

Или

        sin a . sin B
sin b = -------------
            sin A

Или, начиная с = 90 °, грешите = 1, и грех B = sin(90 ° - X), =, потому что X:

sin b = sin a . cos X

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

Данный a, b (просто вычисленный) и A и B, мы можем применить формулу косинуса для получения c. Обратите внимание, что мы не можем просто повторно применить формулу синуса для получения c, так как у нас нет значения C и, потому что мы играем со сферической тригонометрией, нет никакого удобного правила, что C = 90 ° - B (сумма углов в сферическом треугольнике может быть больше, чем 180 °; считайте равносторонний сферический треугольник со всеми углами равным 90 °, который совершенно выполним).


57
ответ дан 1 December 2019 в 05:55
поделиться

Выезд http://www.movable-type.co.uk/scripts/latlong.html

Тот сайт имеет много различных формул и кода JavaScript, который должен выручить Вас. Я успешно перевел его и в C# и в SQL Server UDF, и я использую их повсеместно.

Например, чтобы JavaScript вычислил расстояние:

var R = 6371; // km
var φ1 = lat1.toRadians();
var φ2 = lat2.toRadians();
var Δφ = (lat2-lat1).toRadians();
var Δλ = (lon2-lon1).toRadians();

var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
        Math.cos(φ1) * Math.cos(φ2) *
        Math.sin(Δλ/2) * Math.sin(Δλ/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

var d = R * c; 

Приятного отдыха!

5
ответ дан 1 December 2019 в 05:55
поделиться

Относительно Вашего обновленного вопроса: не был Должен

double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[0];

быть

double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[1];
1
ответ дан 1 December 2019 в 05:55
поделиться

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

Большая проблема была этим: метод Расстояния (для вычислений расстояния между двумя точками) вычислял большие круговые расстояния. Который, конечно, имеет смысл - это - кратчайший путь между двумя точками. Однако большое круговое расстояние между двумя точками, которые лежат на той же параллели (строка широты) НЕ является тем же как расстоянием между теми двумя точками при перемещении непосредственно вдоль строки широты, если Вы не на экватор.

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

Так или иначе там у Вас есть он.

0
ответ дан 1 December 2019 в 05:55
поделиться

Ваше преобразование между км и радианами является неправильным. Морская миля является 1/60-й из градуса, таким образом предполагая, что 1.15... Ваше преобразование от миль до морских миль, и 1.6... Ваше преобразование от км до статутных миль,

   nm = km /  (1.1515 * 1.609344);
   deg = nm / 60;
   rad = toRadians(deg);

Другими словами, я думаю, что Вы выключены фактором 1 000.

2
ответ дан 1 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: