Как получить координаты по адресу 1с
В основе повествования лежит Google Maps JavaScript API V3(все примеры работы с сервисом получены именно отсюда) и конечно платформа 1с: Предприятие 8.2. Компоненты 1с, используемые в примере, так же присутствуют в версии 8.1, так что с большой долей вероятности все нижеописанное будет работать и там.
Подробнее о Google.Maps
- Использование Javascript-библиотеки на клиентской стороне, так называемое «Client-Side Geocoding». Этот способ Google позиционирует как основной.
- Серверное использование, «Server-Side Geocoding». Этот способ предпочтителен для систем, где не происходит интерактивной работы с пользователем.
И немного про 1с
Мы будем использовать режим обычных форм, работающий в толстом клиенте 1с. К новомодному управляемому режиму работы с формами, появившемуся в версии 8.2 этот способ не подойдет без доработок.
Что конкретно мы сделаем:
- Создадим html-файл, содержащий javascript-функции для работы с картой
- Создадим внешнюю обработку для 1с, отображающую карту и имеющую контролы, позволяющие отображать метки, найденные по координатам или адресу
Итак, к делу:
1. Создаем файл html
Для работы с сервисом нам необходим файл, который будет содержать необходимые нам javascript-функции и будет открываться из 1с. Я не буду приводить его пример, поскольку за меня это сделали здесь: Здравствуй, мир!, а перейду к описанию.
Добавляем функции, которые при открытии html-документа получают координаты пункта «Москва» и инициализируют карту с автоматическим позиционированием на нем:
var map = null;
function initialize()
getLocation('Москва', function (results, status)
if (status == google.maps.GeocoderStatus.OK)
GoogleLocation = results[0].geometry.location;
initializeMap(GoogleLocation);
addMarkerForLocation(GoogleLocation.lat(), GoogleLocation.lng());//пример отображения метки по координатам
addMarkerForAddress('Москва Тушино');//пример отображения метки по адресу
> else alert('Координаты не определены');
>);
>
2. Создаем обработку в 1с
На форме обработки 1с добавляем контрол типа «ПолеHTMLДокумента»(назовем его «ПолеHTMLДок») — он будет отображать сформированный нами ранее файл html (назовем его google.html). На практике возможно использование так же ActiveX-объекта «Microsoft Web Browser», но, это по вкусу, особенно учитывая то, что использоваться будет в любом случае IE.
После того, как добавили поле HTML документа, нам необходимо сделать так, чтобы при открытии обработки автоматически открывалась карта. Для этого добавляем обработчик формы «ПриОткрытии», и добавляем в него: ЭлементыФормы.ПолеHTMLДок.Перейти(«c:\google\google.html»);
Этого достаточно, чтобы при запуске нашей внешней обработки в 1с автоматически открывался наш html-файл, в котором при загрузке страницы стартует функция Initialize(), заполняющая и центрирующая карту.
Если все ок, давайте добавим возможность добавления меток по событию в 1с:
Для этого добавим на форму текстовое поле ввода «Адрес», «Широта», «Долгота» и две кнопки — «Добавить метку по адресу» и «Добавить метку по координатам».
И конечно соответствующие кнопкам обработчики:
ЭлементыФормы.ПолеHTMLДок.Документ.parentWindow.eval("addMarkerForAddress('" + Адрес + "')");
ЭлементыФормы.ПолеHTMLДок.Документ.parentWindow.eval("addMarkerForLocation(" + Формат(Широта, "ЧГ=") + "," + Формат(Долгота, "ЧГ=") + ")");
Как вы уже поняли, оба обработчика при нажатии кнопок вызывают те функции Javascript, которые были заданы нами в html-файле и создают на карте отметки. Собственно, для первой версии этого уже более чем достаточно.
Несомненно, на практике этот способ можно улучшить — к примеру тем, что в 1с возможно вовсе обойтись без файла html, используя метод объекта ПолеHTMLДокумента.УстановитьТекст() — при этом код самой страницы возможно хранить в базе 1с в виде текста и не заморачиваться с поддержкой внешнего файла html.
Так же стоит подумать над тем, что Google ограничивает нас в количестве запросов на определение координат — 2500 запросов в сутки с одного ip. Логично было бы добавить хранение в базе наиболее используемых координат, что, кроме экономии запросов даст возможность дополнительного функционала в виде, к примеру, возможности отбирать и отображать нужные метки в пределах заданных географических координат относительно заданного центра.
Внимание! Перед использованием обработки следует ознакомиться с здесь почитайте комментарии), либо предлагают решение с получением ключа карт. Во многих публикациях для отображения карт используется "Поле HTML документа" на форме 1С. Этот объект уже давно устарел и не поддерживает возможности HTML 5. В итоге, чтобы отобразить страницу на форме 1С приходится долго "плясать с бубном".
Программист, которому впервые дали задание вывести на карту точку будет тратить лишнее время и СтартМани на поиски лучшего варианта, корректировать реестр Windows, как предложено здесь и в итоге столкнётся с тем, что стабильного рабочего варианта найти не удастся.
Мы предлагаем вариант решения, который будет работать везде и без специальных условий. Мы принципиально не используем объект WebBrowser Control, чтобы всё работало всегда и у всех.
Пример 1. Метка на карте
Для добавления метки на карте достаточно знать её координаты.
Результат нажатия на кнопку “Показать метку” будет таким:
Как это работает?
Для кнопки “Показать метку” назначена процедура:
Функция для получения текста HTML:
Все экспортные функции и процедуры обработки описаны вспомогательными комментариями, поэтому будет легко догадаться о назначении параметров.
Функция “ДобавитьМетку” добавляет на карту метку с описанием.
Если необходимо на одной карте показать сразу несколько меток, то функцию “ДобавитьМетку” нужно вызывать несколько раз.
Для отображения результата составленного текста HTML используется процедура “ПоказатьНаКартеНаКлиенте”.
При выполнении этой процедуры в первый раз - появится окно с выбором программы-браузера. После выбора - откроется окно с картой.
Пример 2: Маршрут на карте
Процедура кнопки “Показать маршрут”:
Пример 3: Получение координат из адреса (геокодирование)
Не всегда в типовой базе 1С имеются данные о координатах пункта назначения. Но зато есть адрес, представленный стройкой. Иногда даже заполненный по всем правилам КЛАДР (ФИАС).
Для таких случаев имеется возможность преобразовать строку почтового адреса в координаты: долготу и широту.
Функция “ПолучитьКоординатыПоАдресу” выполняет обращение к сервису геокодирования и разбирает ответ в структуру, содержащую координаты и адрес, для которого были определены координаты.
Пример 4. Расчет длины пути маршрута
Этот пример появился в версии 2.0 нашей обработки.
Эту задачу можно решить тремя способами.
Способ 1 - платный
и убрав директиву вначале текста страницы HTML
Длина маршрута записывается скриптом в отдельный тег <div> с идентификатором "dist", для того, чтобы потом было удобней парсить.
Отображение маршрута на карте не реализовано для повышения производительности. В этом примере карта вообще не нужна для отображения, поэтому в своих разработках вам придётся подумать как её скрыть. К сожалению, нерисовать карту нельзя. Длина не вычислится.
Если вынести операцию получения длины на отдельную базу и опубликовать на ней веб сервис, то можно реализовать псевдо вычисление на сервере. База пользователя будет обращаться к веб сервису, передавая в него точки маршрута. После этого каждые n секунд будет опрашивать веб сервис на появление в нем результата вычисления.
В базе, с опубликованным веб сервисом, должен быть всегда запущен клиент.
При получении точек маршрута web-сервис запишет их как входящее задание на вычисление, например, в свой регистр сведений. Клиент каждые m секунд будет опрашивать регистр сведений на получение новых заданий. При появлении таких - берет первое (самое старое) невыполненное задание и начинает рисовать карту на своей форме. После отрисовки - возвращает результат в регистр сведений.
Примерно так:
Способ 3 - возможно, лучше всех
В предыдущем способе формируется текст страницы HTML для выполнения расчёта длины маршрута на клиенте средствами браузера. Этот текст можно попробовать использовать на сервере, применив COM-объект "AltBrowser.Browser". Применив методы простого парсинга можно получить значение из контейнера div и использовать в 1С.
Этот способ в данной статье не рассматривается.
Заключение
Все сложные операции с формированием текста HTML страницы карты и методами взаимодействия с сервисом Яндекс.Карты в нашей обработке имеют открытый код, который всегда можно доработать под свои нужды.
Обработка находится в составе конфигурации. Выложена целая конфигурация, так как в ней находится общая форма с примером использования обработки.
Внимание! Перед использованием обработки следует ознакомиться с здесь почитайте комментарии), либо предлагают решение с получением ключа карт. Во многих публикациях для отображения карт используется "Поле HTML документа" на форме 1С. Этот объект уже давно устарел и не поддерживает возможности HTML 5. В итоге, чтобы отобразить страницу на форме 1С приходится долго "плясать с бубном".
Программист, которому впервые дали задание вывести на карту точку будет тратить лишнее время и СтартМани на поиски лучшего варианта, корректировать реестр Windows, как предложено здесь и в итоге столкнётся с тем, что стабильного рабочего варианта найти не удастся.
Мы предлагаем вариант решения, который будет работать везде и без специальных условий. Мы принципиально не используем объект WebBrowser Control, чтобы всё работало всегда и у всех.
Пример 1. Метка на карте
Для добавления метки на карте достаточно знать её координаты.
Результат нажатия на кнопку “Показать метку” будет таким:
Как это работает?
Для кнопки “Показать метку” назначена процедура:
Функция для получения текста HTML:
Все экспортные функции и процедуры обработки описаны вспомогательными комментариями, поэтому будет легко догадаться о назначении параметров.
Функция “ДобавитьМетку” добавляет на карту метку с описанием.
Если необходимо на одной карте показать сразу несколько меток, то функцию “ДобавитьМетку” нужно вызывать несколько раз.
Для отображения результата составленного текста HTML используется процедура “ПоказатьНаКартеНаКлиенте”.
При выполнении этой процедуры в первый раз - появится окно с выбором программы-браузера. После выбора - откроется окно с картой.
Пример 2: Маршрут на карте
Процедура кнопки “Показать маршрут”:
Пример 3: Получение координат из адреса (геокодирование)
Не всегда в типовой базе 1С имеются данные о координатах пункта назначения. Но зато есть адрес, представленный стройкой. Иногда даже заполненный по всем правилам КЛАДР (ФИАС).
Для таких случаев имеется возможность преобразовать строку почтового адреса в координаты: долготу и широту.
Функция “ПолучитьКоординатыПоАдресу” выполняет обращение к сервису геокодирования и разбирает ответ в структуру, содержащую координаты и адрес, для которого были определены координаты.
Пример 4. Расчет длины пути маршрута
Этот пример появился в версии 2.0 нашей обработки.
Эту задачу можно решить тремя способами.
Способ 1 - платный
и убрав директиву вначале текста страницы HTML
Длина маршрута записывается скриптом в отдельный тег <div> с идентификатором "dist", для того, чтобы потом было удобней парсить.
Отображение маршрута на карте не реализовано для повышения производительности. В этом примере карта вообще не нужна для отображения, поэтому в своих разработках вам придётся подумать как её скрыть. К сожалению, нерисовать карту нельзя. Длина не вычислится.
Если вынести операцию получения длины на отдельную базу и опубликовать на ней веб сервис, то можно реализовать псевдо вычисление на сервере. База пользователя будет обращаться к веб сервису, передавая в него точки маршрута. После этого каждые n секунд будет опрашивать веб сервис на появление в нем результата вычисления.
В базе, с опубликованным веб сервисом, должен быть всегда запущен клиент.
При получении точек маршрута web-сервис запишет их как входящее задание на вычисление, например, в свой регистр сведений. Клиент каждые m секунд будет опрашивать регистр сведений на получение новых заданий. При появлении таких - берет первое (самое старое) невыполненное задание и начинает рисовать карту на своей форме. После отрисовки - возвращает результат в регистр сведений.
Примерно так:
Способ 3 - возможно, лучше всех
В предыдущем способе формируется текст страницы HTML для выполнения расчёта длины маршрута на клиенте средствами браузера. Этот текст можно попробовать использовать на сервере, применив COM-объект "AltBrowser.Browser". Применив методы простого парсинга можно получить значение из контейнера div и использовать в 1С.
Этот способ в данной статье не рассматривается.
Заключение
Все сложные операции с формированием текста HTML страницы карты и методами взаимодействия с сервисом Яндекс.Карты в нашей обработке имеют открытый код, который всегда можно доработать под свои нужды.
Обработка находится в составе конфигурации. Выложена целая конфигурация, так как в ней находится общая форма с примером использования обработки.
Внимание! Перед использованием обработки следует ознакомиться с здесь почитайте комментарии), либо предлагают решение с получением ключа карт. Во многих публикациях для отображения карт используется "Поле HTML документа" на форме 1С. Этот объект уже давно устарел и не поддерживает возможности HTML 5. В итоге, чтобы отобразить страницу на форме 1С приходится долго "плясать с бубном".
Программист, которому впервые дали задание вывести на карту точку будет тратить лишнее время и СтартМани на поиски лучшего варианта, корректировать реестр Windows, как предложено здесь и в итоге столкнётся с тем, что стабильного рабочего варианта найти не удастся.
Мы предлагаем вариант решения, который будет работать везде и без специальных условий. Мы принципиально не используем объект WebBrowser Control, чтобы всё работало всегда и у всех.
Пример 1. Метка на карте
Для добавления метки на карте достаточно знать её координаты.
Результат нажатия на кнопку “Показать метку” будет таким:
Как это работает?
Для кнопки “Показать метку” назначена процедура:
Функция для получения текста HTML:
Все экспортные функции и процедуры обработки описаны вспомогательными комментариями, поэтому будет легко догадаться о назначении параметров.
Функция “ДобавитьМетку” добавляет на карту метку с описанием.
Если необходимо на одной карте показать сразу несколько меток, то функцию “ДобавитьМетку” нужно вызывать несколько раз.
Для отображения результата составленного текста HTML используется процедура “ПоказатьНаКартеНаКлиенте”.
При выполнении этой процедуры в первый раз - появится окно с выбором программы-браузера. После выбора - откроется окно с картой.
Пример 2: Маршрут на карте
Процедура кнопки “Показать маршрут”:
Пример 3: Получение координат из адреса (геокодирование)
Не всегда в типовой базе 1С имеются данные о координатах пункта назначения. Но зато есть адрес, представленный стройкой. Иногда даже заполненный по всем правилам КЛАДР (ФИАС).
Для таких случаев имеется возможность преобразовать строку почтового адреса в координаты: долготу и широту.
Функция “ПолучитьКоординатыПоАдресу” выполняет обращение к сервису геокодирования и разбирает ответ в структуру, содержащую координаты и адрес, для которого были определены координаты.
Пример 4. Расчет длины пути маршрута
Этот пример появился в версии 2.0 нашей обработки.
Эту задачу можно решить тремя способами.
Способ 1 - платный
и убрав директиву вначале текста страницы HTML
Длина маршрута записывается скриптом в отдельный тег <div> с идентификатором "dist", для того, чтобы потом было удобней парсить.
Отображение маршрута на карте не реализовано для повышения производительности. В этом примере карта вообще не нужна для отображения, поэтому в своих разработках вам придётся подумать как её скрыть. К сожалению, нерисовать карту нельзя. Длина не вычислится.
Если вынести операцию получения длины на отдельную базу и опубликовать на ней веб сервис, то можно реализовать псевдо вычисление на сервере. База пользователя будет обращаться к веб сервису, передавая в него точки маршрута. После этого каждые n секунд будет опрашивать веб сервис на появление в нем результата вычисления.
В базе, с опубликованным веб сервисом, должен быть всегда запущен клиент.
При получении точек маршрута web-сервис запишет их как входящее задание на вычисление, например, в свой регистр сведений. Клиент каждые m секунд будет опрашивать регистр сведений на получение новых заданий. При появлении таких - берет первое (самое старое) невыполненное задание и начинает рисовать карту на своей форме. После отрисовки - возвращает результат в регистр сведений.
Примерно так:
Способ 3 - возможно, лучше всех
В предыдущем способе формируется текст страницы HTML для выполнения расчёта длины маршрута на клиенте средствами браузера. Этот текст можно попробовать использовать на сервере, применив COM-объект "AltBrowser.Browser". Применив методы простого парсинга можно получить значение из контейнера div и использовать в 1С.
Этот способ в данной статье не рассматривается.
Заключение
Все сложные операции с формированием текста HTML страницы карты и методами взаимодействия с сервисом Яндекс.Карты в нашей обработке имеют открытый код, который всегда можно доработать под свои нужды.
Обработка находится в составе конфигурации. Выложена целая конфигурация, так как в ней находится общая форма с примером использования обработки.
Солидный продукт с той же функциональностью предлагает «Яндекс» — он называется «Геокодер». Но сервис «Яндекса» бесплатен только для открытых некоммерческих проектов. Стандартный же тариф — от 120 000 ₽ в год — подходит не всем.
Мы подумали — если сделать бесплатную или недорогую альтернативу «Геокодеру», разработчики наверняка скажут спасибо. И сделали. В статье расскажу, как устроен «Адрес по координатам»: как мы наладили поиск, собрали справочник и упаковали в готовый метод.
Где берем данные и чем ищем адрес
Подступаясь к задаче, мы изучили готовые решения: где взять справочник координат с адресами и как потом искать по этому справочнику географические объекты. Оказалось, за нужными инструментами даже не придется далеко ходить.
Адресные объекты берем в ФИАС — Федеральной информационной адресной системе. Это самый полный из открытых и официальных адресных справочников. Подробно о нем мы уже писали на «Хабре», а сейчас важны четыре факта:
- в ФИАС хранятся все адресные объекты страны, от регионов и ниже — до зданий и дополнительных территорий;
- справочник свободно доступен в форматах DBF и XML;
- ФИАС не идеален — в нем отсутствуют десятки тысяч домов и множество улиц, особенно новых;
- каждому адресному объекту в справочнике соответствует уникальный ID — ФИАС-код. Код объекта иногда меняют, но для нашей статьи это не так важно.
Координаты загружаем из OpenStreetMap (OSM). OSM — проект со свободной лицензией: энтузиасты собирают координаты всевозможных объектов и выкладывают для всех желающих.
Список источников публикуют на специальной странице в «Вики» проекта
Выгрузки состоят из PBF-файлов — этот формат используют вместо XML как более компактный. Превратить PBF в OSM XML ничего не стоит, с этим справится куча одобренных сообществом утилит.
Для собственного справочника мы берем адресные объекты из ФИАС, а затем ищем их координаты в OSM. Если нашли, сохраняем объединенные данные. Получается такое пересечение ФИАС и OSM.
И все это замечательно, но есть одна проблема: с качеством данных в OSM дела обстоят непросто. Координаты объектов часто не соответствуют реальности. Например, полигоны для регионов и районов адекватны. А для городов и ниже — уже не очень.
Полигоны — это многоугольники, ограничивающие площади на карте. Они состоят из связанного набора точек с координатами. Полигонами обозначают границы регионов, районов, городов и даже зданий
Основная работа, и с большим отрывом — собрать из OSM адекватные данные и отсеять брак. Задача настолько объемная, что я отвел под нее в статье отдельный раздел.
Дома, которых нет в ФИАС, загружаем тоже из OSM. Выше я уже говорил, что в ФИАС отсутствуют десятки тысяч домов. Это даже не проблема, а просто реальность, фон. Поэтому мы пополняем свой справочник домами из OSM. Но только теми, для которых в ФИАС существует улица. У пришедших из OSM зданий нет ФИАС ID, поэтому мы идентифицируем их как ФИАС-код родителя + номер дома.
По справочнику ищем с помощью прекрасного Lucene — нашего многолетнего помощника. За наводку спасибо сведущему индийцу, написавшему пост Indexing Geographical Data With Lucene (хорошее дополнение — материал A dive into spatial search algorithms — о k-d-деревьях, на которых построен алгоритм поиска).
Как только мы узнали об у́дали Lucene, проблема с поиском решилась почти сама. Делов осталось — пройтись наждачкой.
- Загрузили в Lucene свой справочник координат и адресов, получили поисковый индекс. Для легкости убрали из него почти все, оставив лишь ID адресов и координаты.
- Наладили поиск по индексу: на вход — координаты, на выход — ID найденных адресных объектов. Другой информации поиск не возвращает, поскольку индекс мы донельзя скукожили.
- Насытили выдачу, загружая из «большого» ФИАС данные по найденным ID. Добавляем много всего, от нужного всем адреса одной строкой до признака столицы региона у городов.
- Придумали, как сортировать и отдавать полученные объекты.
Как собрали базу координат и адресов
Для начала выложу багаж: прочитав статью, быстро сделать подобный справочник не получится. Мы собираем его с 2014 года, постоянно дополняя. Об этом чертовски длинном пути я и расскажу.
Самое сложное при составлении справочника — перебрать кординаты, которые пришли из OSM. На старте мы выверяли их как могли, в том числе руками. Главная цель тогда — получить опорные точки в крупных городах и сделать из них эталонный справочник. Теперь, когда таких точек много, проверять новые данные вручную почти не приходится. За раз мы добавляем в эталонный справочник 200 000–300 000 адресов с координатами, и вот как это делаем.
Формируем из OSM-тегов полные адреса́. В OSM-выгрузках составные части адресов разбросаны по разным тегам:
- addr:city — д. Булатниково;
- addr:street — Центральная улица;
- addr:housenumber — 103.
Прогоняем каждый новый адрес через API стандартизации «Дадаты». Сервис приводит адреса к единому формату «Как в ФИАС»:
- исправляет опечатки;
- расшифровывает сокращения вроде «НиНо» и «Мск»;
- меняет старые названия на новые;
- находит по индексу пропущенный в адресе город;
- определяет ФИАС-код.
142718, Московская обл, Ленинский р-н, с Булатниково, ул Центральная, д 103.
ФИАС-код — a8b6a52f-e96d-4ec3-a0ff-641013ab0445
Стандартизованные дома, улицы и населенные пункты мы храним как одну точку. Для улицы и населенного пункта эта точка — центр. В итоге все адресные объекты лежат в одной таблице, внутри — адрес, ФИАС ID, широта и долгота.Адрес | ФИАС ID | Широта | Долгота |
---|---|---|---|
142718, Московская обл, Ленинский р-н, с Булатниково, ул Центральная, д 103 | a8b6a52f-e96d-4ec3-a0ff-641013ab0445 | 55.558773 | 37.667103 |
119034, г Москва, пер Турчанинов, д 6 стр 2 | 8c925e61-9173-48b3-999e-dc85c86d89e7 | 55.737096 | 37.597190 |
Разбираем адреса, которые «Дадата» не стандартизовала. Адреса́, которые не получилось сопоставить с ФИАС, сервис помечает флажком. Их проверяем вручную, вариантов здесь несколько.
- Адрес пришел не в положенных тегах выгрузки OSM, а черт знает где. Встречали и вовсе не заполненные адресные теги, и город в теге улицы, и еще много всего.
- В OSM лежит экзотический объект вроде детской площадки, вузовского футбольного поля или вовсе кладбища. В ФИАС ничего такого нет, да и для наших целей эти результаты не годятся. Такие объекты просто отсеиваем.
- Ошибка — и не ошибка вовсе. Например, из OSM пришел район города, которого в ФИАС нет. Или в ОSМ объект находится в населенном пункте, а в ФИАС этот населенный пункт присоединили к городу и удалили. Тогда мы допиливаем алгоритм под загруженные данные и запускаем снова.
Проверяем, насколько адекватны загруженные координаты. Для этого специальной утилитой смотрим, попадают ли координаты нового объекта в полигон родительского региона или района. Если адрес сообщает, что объект находится в Омской области, будь добр по координатам попадать в ее полигон. Вхождения в город не требуем — не все города точно освещены в OSM, для многих данные не обновляют.
Эталонные полигоны мы загружаем из OSM и храним как есть — в формате GeoJSON. Чтобы выбрать, к какому полигону примерить точку, смотрим в отдельную таблицу. В ней мы сопоставили префиксы КЛАДР-кодов и ID полигонов: находишь для адреса КЛАДР-код и видишь, какой полигон выбрать.
КЛАДР-код — это уникальный идентификатор, который использовали еще до появления ФИАС. Находить этот код для адреса умеет миллион сервисов
Утилита разрешает объекту отстоять от положенного полигона на 1 700 метров. Это правило добавили из-за шоссе, которые часто выходят за границы региона. Но расстояние больше 1 700 метров — признак ошибки, так говорит статистика.
На этом для городов и улиц проверка заканчивается.
Еще раз, построже, проверяем загруженные координаты домов. В дело снова вступает упомянутая утилита, и вот что она делает.
- Берет адрес нового дома и находит для него соседей в эталонном справочнике.
- По координатам считает расстояние между непроверенным новым домом и надежными соседними.
Проверку проходят только дома, которые удалены от надежных коллег не более чем на 150 метров. Причем каждый новый одобренный дом мы учитываем при разборе следующих. Вот как это работает.
Допустим, в эталонном справочнике хранятся дома № 1, 2 и 3 по улице Коммунаров. В новых данных пришли дома № 5, 6 и 7 по той же улице. Судя по координатам, новые дома стоят рядом. Утилита видит, что дом № 5 находится рядом с домами № 1, 2 и 3 и добавляет его в эталонный справочник. Значит, дома № 6 и 7 тоже проходят проверку.
А дальше решается судьба пришедших из OSM данных:
- дома, прошедшие обе проверки: на полигоны и на соседей, добавляем в эталонный справочник;
- если объект не попадает в полигон, новые данные не подходят. То же самое, если расстояние между домом и соседями слишком велико;
- дома, у которых нет соседей, мы пока откладываем. Они лежат в отдельной базе, когда-нибудь разберем.
В первой таблице — все объекты c ФИАС ID до домов: регионы, населенные пункты, улицы. Во второй — дома́ и ссылка на родителя из первой таблицы
Две таблицы нужны, чтобы назначить ключи отсутствующим в ФИАС домам. У них нет собственного ФИАС-кода, поэтому делаем вот как:
- в одну таблицу собираем адресные объекты до дома, у каждого из них свой ФИАС-код;
- во вторую — только дома́, при этом ссылаясь на родителя в первой таблице.
Справочник готов, осталось протестировать. За ночь прогоняем сервис по функциональным тестам и тестируем производительность. Скорость проверяем на Москве, запрашивая все дома в радиусе трех километров. Чтобы уж наверняка. Конечно, обложили все автотестами.
Главное после обновления — чтобы не стало хуже.
Обратное геокодирование глазами пользователя
На вход метод принимает три параметра: координаты, количество результатов и радиус поиска. Радиус по умолчанию — 100 метров, максимальный — километр. Точное значение задают в настройках.
Обратно метод возвращает найденные объекты: дома, улицы и населенные пункты. При этом сортирует их по убыванию точности.
- Дома́.
- Улицы.
- Населенные пункты.
- Города́.
После всех этих рокировок метод наконец-то возвращает объекты, которые нашел.
Внутри — много разного о найденных объектах: строки с полным и сокращенным адресом, актуальное и устаревшие названия, почтовый индекс, ФИАС-код родительского объекта и так далее.
Все данные, которые отдает метод — в документации
Покрытие по координатам для разных регионов разное, вот так с домами:
- Москва — 96%,
- Санкт-Петербург — 88%,
- другие города-миллионники — 74%,
- остальная Россия — 47%.
- Москва — 92%,
- Санкт-Петербург — 79%,
- другие города-миллионники — 75%,
- остальная Россия — 67%.
Уже думаем, что добавить к методу: разрешить фильтрацию по типам объектов, возвращать расстояния до заданной точки, еще что-нибудь. Следим за спросом и решаем, вкладывать ли силы.
А в остальном все уже на проде. До 10 000 запросов в сутки — бесплатно, больше — по подписке от 5 000 ₽ в год. Если нужны адреса по координатам для коммерческого проекта, а «Геокодер» слишком дорог — попробуйте API «Дадаты».
Читайте также: