Web-геосервисы. Обзор современных решений

0u8ujnh7xzhzt6m8mp2ed630fei.jpeg

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

В этой статье я рассмотрю гео-задачи, которые наиболее часто встают перед программистами, сделаю небольшой обзор сервисов, предлагающих решения для этих задач, и поделюсь опытом использования этих сервисов.

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

Оглавление


Отображение карт на сайте


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

Для отображения карт используются два основных вида API:

  • Javascript API (интерактивное)
  • Static API (статичное)


Javascript API


Все сервисы, которые я разрабатывал, работают в основном с Россией, поэтому я расскажу о тех API, которыми пользовался сам и которые популярны у нас. Знаю, что есть API и у bing, и других провайдеров карт, но я ими не пользовался.

Javascript API позволяет показать на сайте интерактивную карту с возможностью изменения масштаба, отображения маркеров, взаимодействия с картой (перетаскивание маркеров, отображение всплывающих подсказок и прочее).

Javascript API Яндекс.Карт


Javascript API Google Maps


2ГИС API


  • Очень хорошие карты, но есть не везде
  • Пока бесплатно
  • Функциональность API послабее чем у Яндекса/Гугла, но может расширяться с помощью модулей Leaflet
  • Зато есть карты этажей для торговых центров
  • api.2gis.ru/doc/maps/ru/quickstart


Static API


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

Static API Яндекс.Карт


Static API Google maps


2ГИС Static API


  • На сайте почему-то числится как «устаревшее»
  • Пока бесплатно
  • Максимальный размер 1280×1280
  • Есть не везде
  • api.2gis.ru/doc/maps/1.0/static


Геокодирование


Геокодирование — процесс, который позволяет узнать координаты объекта по его адресу. Ну или обратное геокодирование — по координатам узнать, что за гео-объект там находится. Фактически все сервисы геокодирования работают с адресами, введенными в произвольном формате, заодно приводя их к своему стандарту. Полностью бесплатных сервисов геокодирования на рынке в данный момент я не нашел.

Типичные применения геокодирования — отобразить на карте введенный пользователем адрес, или наоборот (обратное) — пользователь поставил на карте метку, нужно её превратить в адрес.

Геокодер Яндекс.Карт


  • Есть бесплатный тариф, ограниченный 25 000 запросов в сутки.
  • Кроме количества запросов также ограничен лицензионным соглашением — результаты кодирования нельзя сохранять и использовать без карты (но можно кешировать), их нужно отображать только на картах яндекса и только в рамках общедоступных сервисов (доступных всем или с открытой бесплатной регистрацией).
  • Отлично работает в России, и прямой и обратный.
  • tech.yandex.ru/maps/geocoder


«Подсказки» от DaData


  • У DaData есть сервис «подсказки», который позволяет реализовать автодополнение вводимых пользователем адресов.
  • Он включает в себя функции геокодера (может выдавать координаты по адресу и адрес по координатам).
  • Работает только в России, покрытие хромает — в миллионниках на уровне 75–95%, в среднем по России около 50%
  • 10 000 запросов в сутки бесплатно, но оферта не позволяет его использовать полностью в автоматическом режиме — для автоматического геокодинга нужно использовать сервис «Стандартизация».
  • dadata.ru/api/suggest/address


Google Maps Geocoding API


OpenStreetMaps Nominatim


  • OpenSource решение, которое вы можете развернуть на собственном сервере.
  • Не пользовался, возможно в комментариях кто-то напишет о своем опыте использования
  • nominatim.org/release-docs/develop/api/Overview


2ГИС


  • В документации к Javascript API задекларировано наличие функций геокодирования, но по факту как ими пользоваться — в документации я не нашел. Возможно, пока находится в разработке.


zfvt-4myl-bujpmdet-49-br-h0.png

Разбор и автодополнение адресов


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

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

Отдельно стоит отметить сервис «стандартизация» от DaData — по адресам из России они возвращают еще массу разной полезной информации, по 10 копеек за каждый адрес:
dadata.ru/api/clean/address

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

Определение района в рамках города


Для определения района в рамках города я для себя нашел на данный момент два решения. Оба работают только для России.

Первое, и самое очевидное — DaData. Уже много было написано об этом сервисе, это действительно хороший сервис для работы с российскими адресами (и это не реклама). Попробуйте сами, убедитесь.

Если не хотите зависеть от стороннего сервиса — есть другое решение, которое я применял и продолжаю применять до сих пор. Это определение района по коду ОКАТО адреса. У каждого адреса в рамках России есть свой код ОКАТО — 11 цифр. Из них первые 5–8, в зависимости от города, однозначно указывают на район.

Я для тех городов, которые мне нужны, просто составил базу кодов ОКАТО для районов, получился примерно такой массив:

Пример кодов ОКАТО
glvzfkojdmgvtmmkbbzs1u4pydc.png


Следующий вопрос — как узнать код ОКАТО адреса? DaData возвращает его в рамках своих сервисов «Подсказки» и «Стандартизация». Есть сайт окато-октмо.рф который по адресу показывает код ОКАТО, используя ту же дадату. Наша задача — самостоятельно узнать код ОКАТО по адресу, не завися ни от какого сервиса.

Для этого нам нужно скачать свежую базу данных ФИАС и настроить поиск по ней. На хабре уже есть статья с примером как импортировать базу ФИАС в MSSQL. В общем, настраиваете поиск по ФИАСУ, находите там нужный вам адрес, узнаете его код ОКАТО, по коду ОКАТО из списков районов узнаете район — всё, задача решена.

Если не хотите париться с загрузкой 60 гигабайт XML файлов в свою базу, есть более дешевый, но и менее функциональный, чем dadata, сервис, который позволяет работать с базой ФИАС:
kladr-api.ru/docs

Поиск ближайших станций метро


Нужная функция, особенно для жителей Москвы, когда вам нужно по адресу найти ближайшие к нему станции метро. Для этой задачи в данный момент я знаю два решения:

Яндекс Геокодер


Сначала нужно узнать координаты адреса. Потом, как при обратном геокодировании, передаем в качестве параметров запроса эти координаты, и вид возвращаемого топонима kind=metro.
Отдельным параметром задаются размеры области, в пределах которой надо искать ближайшую станцию. Опытным путём я подобрал значения от 0,02 до 0,05 градусов в зависимости от города (в Москве радиус 2 километра от метро еще считается шаговой доступностью, а в Казани расстояние между станциями 1,5 километра).

Также есть проблема у такого метода, что иногда ближайшее по координатам метро не всегда ближайшее фактически (например находится на другом берегу реки, или вроде того). Определять ближайшее по доступности метро можно только с помощью сервисов построения маршрутов и матриц расстояний, о них будет в статье дальше. Для грубого определения ближайшей станции — геокодер яндекса вполне подходит, и дает выполнить до 25000 запросов в сутки бесплатно.

DaData


Да, и в этой задаче может помочь DaData — в рамках платных тарифов сервиса «подсказки» или «стандартизация» по каждому адресу также возвращается 3 ближайшие станции метро и расстояния до них.

Поиск организаций


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

Яндекс поиск по организациям


  • tech.yandex.ru/maps/geosearch
  • Бесплатно до 500 запросов в сутки, при условии отображения результатов на общедоступной карте.
  • Результаты поиска нельзя сохранять или отображать на картах не от яндекса.


Google Places Api


  • developers.google.com/places/web-service/usage-and-billing
  • Очень сложная система тарификации, до конца не разобрался. Возможно, кто пользовался, напишет в комментариях.
  • Как я понял, базовые запросы бесплатно, но вся доп. информация (контакты, отзывы, …) тарифицируется отдельно.


2ГИС


Ходят слухи, что у них есть платное закрытое API для поиска по организациям. Мне к нему доступ получить пока не удалось, да и поиска по организациям от яндекса для наших задач вполне хватает.

Определение местоположения пользователя по IP


Частая задача в вебе — понять, из какого города на ваш сайт пришел посетитель. Для этой задачи есть решения в виде online-сервисов или самостоятельных решений для тех, кто не хочет зависеть от сторонних сервисов.

Онлайн сервис для определения города по IP — тут я могу посоветовать (для России) снова DaData: dadata.ru/api/detect_address_by_ip
Лимит — 10 000 запросов в сутки. Если ваша посещаемость превышает 10 000 уников в сутки, есть смысл рассмотреть решения, которые устанавливаются на ваш сервер.

Подробно о них можно почитать в обзоре от DaData, как они выбирали, что использовать.

Вкратце продублирую информацию:
IpGeoBase  — раньше был неплохой сайт, который ежедневно обновлялся и давал базу ip адресов и соответствующих им городов в понятном машинно-читаемом формате, легко импортируемом в любую базу данных. К сожалению, перестал обновляться в 2017 году.
ipgeobase.ru

SypexGeo — обновляется до сих пор, поставляется в виде скрипта php и базы данных к нему в собственном формате. Работает быстро, определяет хорошо
sypexgeo.net/ru/download

MaxMind предлагает скачать бесплатные базы со сниженной точностью и отдельно API к ним на различных языках программирования. Более точные базы доступны в рамках платных продуктов.
dev.maxmind.com/geoip/geoip2/geolite2

Определение местоположения пользователя по координатам


Задача схожа с задачей обратного геокодирования, с небольшими различиями.

Иногда нам нужно определить местоположение пользователя, когда мы точно знаем его координаты (например получили их используя датчики GPS устройства или Geolocation API в браузере). Тут есть два варианта — обратное геокодирование нам возвращает название того места, где находится пользователь. Но что произойдет, если пользователь находится где-то на трассе между городами, или в пригороде или просто в чистом поле и хочет посмотреть объявления о продаже участков на этом поле? Не всегда обратный геокодер с этим справится.

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

ORDER BY (|lng - :lng| + |lat - :lat|) ASC LIMIT 1


Построение маршрута


Иногда бывает нужно построить маршрут от одной точки до другой. Например, составить схему проезда от местоположения пользователя до вашего офиса. Бесплатных решений этой задачи я не нашел, буду благодарен, если кто-то поделится. Платные решения есть от Яндекса и от Гугла — основное их отличие в том, что Яндекс продает подписку с годовой оплатой, а гугл тарифицирует запросы поштучно и списывает деньги с карты раз в месяц по итогу месяца.
Также у гугла есть премиум-подписка, которая дает некоторые дополнительные функции (например увеличение максимального размера картинки Static API) и депозит на лимиты.

Яндекс


Общая особенность всех сервисов Яндекса для маршрутов — они работают на территории России, Абхазии, Азербайджана, Армении, Беларуси, Грузии, Казахстана, Кыргызстана, Молдовы, Таджикистана, Турции, Узбекистана и Украины.

Построение маршрута между 2 точками


  • tech.yandex.ru/routing/router
  • Тарифы от 120 000 рублей в год
  • Поддерживает построение пешеходных, автомобильных маршрутов и использование общественного транспорта, а также их комбинации
  • Учитывает пробки, в том числе прогнозируемые на заданное время в будущем


Матрица расстояний


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

  • tech.yandex.ru/routing/distance_matrix
  • Тарифы от 120 000 рублей в год
  • Поддерживает построение пешеходных, автомобильных маршрутов и использование общественного транспорта, а также их комбинации
  • Учитывает пробки, в том числе прогнозируемые на заданное время в будущем


API для логистических компаний


Уникальная разработка яндекса для логистических компаний. Комбинирует возможности предыдущих двух сервисов и предлагает готовое решение для определенного количества сотрудников/автомобилей на линии. В описании ничего не сказано об ограничениях по странам.

  • tech.yandex.ru/routing/vrp
  • Тарифы от 300 000 рублей в год за 10 активных машин/сотрудников


Google


Главное отличие от яндекса — тарификация по принципу Pay-as-you-go, то есть за каждый запрос. Для небольших объемов тарифы будут выгоднее у Гугла, для больших — у Яндекса.
Также у гугла нет ограничения по странам, где они строят маршруты.

Google Directions Api


  • developers.google.com/maps/documentation/directions/intro
  • Тариф 5$ либо 10$ за 1000 запросов. 10 — если используется оптимизация с учетом пробок и промежуточных путевых точек. 5 — если просто маршрут между 2 точками.
  • По функциям аналог сервиса Яндекса для построения маршрутов между 2 точками, но имеет больше настроек
  • В частности, умеет предлагать несколько альтернативных маршрутов


Google Distance Matrix API


Google Roads API


Уникальный сервис гугла, позволяющий работать с дорогами, по которым едет ваш транспорт.
Автоматически привязывает точки вашего маршрута к дорогам, показывает лучшую схему движения и всю информацию об участках дорог, которые повстречаются вам на пути.
Умеет к точкам привязывать ближайшие к ним участки дорог (например по GPS треку который скачет туда-сюда — показать по каким дорогам по факту был пройден маршрут).
Умеет показывать ограничения скорости на дорогах на маршруту.

Заключение


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

Многие сервисы по мере роста популярности переходят на всё более жесткие системы монетизации — как бесплатные когда-то карты гугла стали полностью платными, так же и Яндекс постепенно к этому идет.

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

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

© Habrahabr.ru