Из записной книжки программиста.
Январь
Я, конечно, знал, что Земля не идеальный шар, что он как-то приплюснут и называется то ли эллипсоидом, то ли геоидом, то ли еще как-то. Из университетских лекций в памяти держится название сферы вращения, ну да, ну и что дальше-то. Надо было посчитать расстояние между двумя точками на Земле, и пытаться восстановить в памяти весь курс трехмерной геометрии, да еще сделать поправки на неидеальность шара, — задача, конечно, интересная, но такой подход был бы совсем непрактичным. Хочется же и получить быстро результат, и порадоваться, и закрыть задачу.
Когда Яндекс открывал свои «Самолетики», они ввернули в заметке в их корпоративном блоге какое-то умное слово — ортодромии. Ну явно для того, чтобы поумничать. Кто же не знает, что ортодромия — это не про нашу Землю, это лишь кратчайший путь на поверхности сферы вращения. Мне-то нужно найти конкретный модуль по употребимому английскому названию и именно для Земли. Это название — great circle. Ищем.
На спане быстро нашлась пара модулей, про один из которых в первой же строке документации написано, что он broken, а второй вроде ничего. Разве что название космической длины. Не страшно, берем в дело, радуемся и закрываем задачу.
Февраль
Стало скучно, что мы тут уже месяц считаем расстояние по ровненькому шару, а Украина до сих пор не выбрала президента. Что же там есть на спане еще? Йоу! Есть модуль Geo::Ellipsoid, и в нем с десяток разных формул, по которым описывают форму Земли. Хочу.
Так, что нужно? Интерфейс странноват, но понятен. Попробую на старом примере, посчитаю расстояние от Москвы до Киева. Как хорошо, что в папке /test у меня все это сохранилось, не надо заново искать координаты.
use v5.10;
use strict;
use Geo::Ellipsoid;
my @moscow = (55.7522, 37.6156);
my @kiev = (50.4333, 30.5167);
my $geo = new Geo::Ellipsoid(
ellipsoid => 'WGS84',
units => 'degrees',
distance_units => 'kilometers'
);
my $dist = $geo->range(
$moscow[0], $moscow[1], $kiev[0], $kiev[1]
);
say $dist;
В очередной раз напрягся, восстанавливая в памяти, что из longitude и latitude широта, а что — долгота, но вроде не перепутал и получил ответ, поохожий на правду. С GIS::Distance было 757 километров, с Geo::Ellipsoid — 759. (А оно должно было стать больше или меньше? Хотя какая разница, если все равно города на разной высоте относительно моря.)
Закоммичу, пожалуй.
Три минуты спустя
Коллега, прочитавший пришедший в почту дифф коммита, пишет: «Хм, а GIS:Distance::Formula::GeoEllipsoid?». Что это? Позырю. Блядь, я же забыл, что GIS::Distance может еще считать и по эллипсоиду. Читал же, когда его пробовал в прошлый раз. GIS::Distance это обертка, которая делегирует все расчеты другим модулям. Вместо того, чтобы приделывать новый модуль, можно было бы просто указать параметр ellipsoid => 'WGS84' к существующему. Незадача какая, сраный спан без аннотированных перекрестных ссылок.