Post-Image

Измерение расстояния по координатам

Рвав-рвав, собака Смайл нынче землемер!

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

Вообще надо сказать, что, пока обдумывал материал в голове, что отделаюсь “легким испугом”, типа: ну вот будет у меня 1-я точка как 0, и вторая как 25, чего не посчитать-то? А вот фига, все оказалось куда интереснее. При том то, что удалось нарыть, можно еще и оптимизировать дополнительно.

Пример:

  • Таблицы “Маршрут PQ” и “Маршрут DAX” содержат название маршрута, а также координаты начальной и конечной точки каждого маршрута:

    art_018_screen_1

    Задача:

    На основе представленных данных необходимо определить расстояние между 2-мя точками маршрута, используя два уровня вычисления, а именно Power Query и DAX.

    Метод 1 – уровень Power Query:

  • Для начала географическим координатам необходимо присвоить правильные типы данных, поскольку с текстовыми столбцами мы далеко не уедем:

    art_018_screen_2

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

  • Далее, для начала расчета, необходимо перевести заданные координаты в радианы. Можно было создать еще 4 дополнительных столбцах, но лучше написать следующую функцию с незамысловатым названием:

    art_018_screen_3

  • Применив указанную функцию к нашим данным, мы получим искомые значения:

    art_018_screen_4

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

    art_018_screen_5

    Рвав-рвав, вот теперь помучайтесь, составляя код с картинки :-Р На всякий случай добавлю меда в ложку дегтя: значение “6371” – это общепринятый радиус нашей планеты в километрах.

  • Проверить получившийся результат:

    art_018_screen_6

    Метод 2 – уровень DAX:

  • Для выполнения поставленной задачи на уровне DAX достаточно создать один расчетный столбец со следующей формулой, правда и тут без тригонометрии не обойтись:

    Расстояние, км = 
    VAR _NumberPI = 3.141592653589794
    VAR _ValueDegrees = 180
    VAR _CorrectionFactor =
        DIVIDE ( _NumberPI, _ValueDegrees, 0 )
    VAR _RadiusEarth = 6371 //Общепринятая веричина радиуса Земли в километрах, для расчета в милях нужно использовать 3959
    RETURN
        ACOS (
            SIN ( 'Маршрут DAX'[Широта - старт] * _CorrectionFactor )
                * SIN ( 'Маршрут DAX'[Широта - финиш] * _CorrectionFactor )
                + COS ( 'Маршрут DAX'[Широта - старт] * _CorrectionFactor )
                    * COS ( 'Маршрут DAX'[Широта - финиш] * _CorrectionFactor )
                    * COS ( ( 'Маршрут DAX'[Долгота - финиш] * _CorrectionFactor ) - ( 'Маршрут DAX'[Долгота - старт] * 0.0174532925199433 ) )
        ) * _RadiusEarth

  • Проверить получившийся результат:

    art_018_screen_7

  • Для итоговой проверки можно воспользоваться каким-нибудь интернет-сервисом:

    art_018_screen_8

    Рвав-рвав, вот такие дела. При промышленном применении данного функционала нужно иметь ввиду, как минимум, следующие моменты: расстояние считается по прямой, и маршрут по городам из примера “Санкт-Петербург -> Москва” на самом деле несколько не верен, поскольку его величина рассчитывается от Дворцовой площади до Красной площади.

    Хе-хе, для авиаперевозок самое то, убежал договариваться.

    Ваш Смайл