Во многих из проектов, в которых я участвовал, была необходимость использовать географические данные в том или ином виде. Даже самые простые сайты, как правило, имеют список стран или городов на какой-нибудь из своих страниц – магазины хотят знать, куда доставлять товары; социальные сети хотят знать, откуда пользователь; и так далее.
Что далеко ходить – вот даже здесь на Хабре есть выпадающие списки стран, штатов и городов:
Мне (как, наверняка, и вам) много раз приходилось хранить подобные данные (скажем, список стран) и в массивах, и в базах данных, и в файлах конфигурации. Потом нудно добавлять варианты на других языках, когда у проекта появляется альтернативная языковая версия.
Я вижу сразу несколько проблем и буду только рад если кто-то оспорит этот список:
- Добавление географических данных и переводов засоряет рабочий проект, его хранилище данных. Не хочу лишних таблиц, не имеющих отношения к основному бизнесу!
- Географические данные в проекте – это постоянное повторение, изобретение велосипеда заново. Набор стран и городов на планете меняется крайне редко, зачем же тогда отводить этим данным тёплое место в приложении?
- Если в команде нет лингвистов и полиглотов, то в списки городов и стран могут запросто пробраться ошибки. Сколько русских до сих пор пишет «Таиланд» с и кратким?
Географические данные – идеальный кандидат для отдельного пакета. Хочу ввести одну команду в любимом менеджере пакетов (будь то composer, npm или CocoaPods) и сразу получить возможность работать с географическими наименованиями. Хочу иметь что-то вроде модного http://momentjs.com/, но про географию. Поставил один пакет – закрыл эту страницу, так сказать.
Удивительно, но таких пакетов пока не существует, поэтому я начал работу над своим. Для начала – версия на PHP. Эта статья является описанием моего подхода, а основными целями публикации можно считать сбор мнений от других разработчиков; оценку необходимости, актуальности пакета.
Предлагаемая реализация
Вот таким мне представляется оптимальный API для PHP на текущий момент:
// Точка входа в пакет – класс планеты
// В будущем надо добавить возможность создавать объект страны или города без родителя
$planet = new Planet();
// Планета, дай мне все свои страны, и на выходе преобразуй в массив
$planet->getCountries()->toArray();
// Хочу, чтобы имена стран были короткими по возможности – к примеру, США вместо Соединённых Штатов Америки
$planet->getCountries()->useShortNames()->toArray();
// Дайте мне все области Таиланда
$countries = $planet->getCountries();
$thailand = $countries->find(['code' => 'TH']);
$thailand->getStates()->toArray();
// Хочу теперь их на русском
$thailand->getStates()->setLanguage('ru')->toArray();
// Хочу теперь и в другой форме (к примеру, "в Таиланде" вместо "Таиланд")
$thailand->getStates()->setLanguage('ru')->inflict('in')->toArray();
// А где там у нас столица? Есть ли код geonames? А координаты точные?
$capital = $thailand->getCapital();
$capital->getGeonamesId();
$capital->getLatitude();
$capital->getLongitude();
Этого уже достаточно чтобы очень быстро добавить списки из первого изображения на свой сайт.
Для полного счастья хотелось бы ещё:
// Поиск городов конкретной страны по почтовым индексам
$russia->find(['zip' => '626430']);
// Глобальный поиск по почтовым индексам
$planet->find(['zip' => 'EC3R 6DN']);
// Глобальный поиск по координатам
$planet->find([
'latitude' => 51.5078788,
'longitude' => -0.0899208
]);
Мне важно мнение людей на Хабре, но не стану кривить душой – я начал уже писать пакет для PHP не дожидаясь реакции публики. Пилотная версия есть на GitHub, и где-нибудь через месяц в ней появятся 3-4 первых языка и весь базовый функционал. Если кто-то хочет поучаствовать в разработке (особенно интересуют пакеты для других языков – JavaScript, Ruby, et cetera), то буду очень рад получить от вас личное сообщение.
Связь с моделями приложения
Предвижу вопросы вроде «но как же тогда запоминать город пользователя?», и ответ тут достаточно прост – в своей БД (или куда вы там записываете данные) используйте стандартные идентификаторы, такие как коды ISO 3166-1 для стран, коды GeoNames для городов и штатов. Проблем сопоставить код с его содержанием и переводом не будет, и привязаны к этому конкретному пакету вы не станете.
Вопрос
Главный вопрос, он же – цель этой статьи: пользовались ли бы вы таким пакетом в своих приложениях? Или предпочли бы и дальше сами хранить географические данные?
Автор: dusterio