Получение и расшифровка адреса из яндекса в 1С



Определение составных частей адреса — страна, регион, населенный пункт из текстового поля определяются с использованием Яндекс API.

Обработка разбирает составные часты адреса с использованием Яндекс API.  

Подобные решения есть и на Инфостарте, например , эта публикация //infostart.ru/public/587079/ . 

Документацию Яндекса на эту тему можно найти здесь

https://tech.yandex.ru/maps/doc/geocoder/desc/concepts/About-docpage/

Функционал геокодирования, реализованный в обработке, мы использовали для:

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

Первоначальный вариант был еще на первой версии API, здесь рабочий вариант на сегодняшний день.

В обработке в поле Адрес указывается разбираемый адрес. 

Кнопка Разобрать адрес вызывает функционал геокодирования Яндекса и результат отображает в форме обработки ниже.

Несколько примеров работы обработки

Первый пример — с неполным адресом . По введенному адресу Яндекс находит 10 похожих адресов.  

Второй пример — с адресом, содержащим ошибки в написании. Тем не менее , использование Яндекс API дает отличный -единственный результат

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

// Адрес - вводится на форме и разбирается Яндексом
//

&НаКлиенте
Процедура Разобрать(Команда)

НайденныеАдреса.Очистить();

//НайденныеАдреса- таблица значений на форме
//
// Колонки   (все колонки строки неограниченной длины)
//
// АдресИсправленный  - Адрес , исправленный Яндексом
// Страна
// Регион
// Округ- округ/район
// Населенный пункт
// Улица
// Дом


Запрос = Новый HTTPСоединение("geocode-maps.yandex.ru", , , , , , Новый ЗащищенноеСоединениеOpenSSL());

АдресOutput = КаталогВременныхФайлов() + "geores.xml";

Запрос.Получить("1.x/?&geocode=" + Адрес, АдресOutput);

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(АдресOutput);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);

ЧтениеXML.Закрыть();

Найдено = ДокументДОМ.ПолучитьЭлементыПоИмени("featureMember");

Для каждого НайденныйАдрес из Найдено Цикл

НовыйАдрес=НайденныеАдреса.Добавить();
СписокTextСтрана = НайденныйАдрес.ПолучитьЭлементыПоИмени("CountryName");

Если СписокTextСтрана.Количество()>0 Тогда
Страна=СписокTextСтрана[0].ТекстовоеСодержимое;
НовыйАдрес.Страна=Страна;
КонецЕсли;

АдресИсправленный=Адрес;
СписокTextАдрес = НайденныйАдрес.ПолучитьЭлементыПоИмени("AddressLine");
Если СписокTextАдрес.Количество()>0 Тогда
АдресИсправленный=СписокTextАдрес[0].ТекстовоеСодержимое; //Адрес, исправленный Яндексом
КонецЕсли;
НовыйАдрес.АдресИсправленный=АдресИсправленный;

СписокTextРегион = НайденныйАдрес.ПолучитьЭлементыПоИмени("AdministrativeAreaName");
Если СписокTextРегион.Количество()>0 Тогда
Регион=СписокTextРегион[0].ТекстовоеСодержимое;
НовыйАдрес.Регион=Регион;
КонецЕсли;

СписокTextОкруг = НайденныйАдрес.ПолучитьЭлементыПоИмени("SubAdministrativeAreaName");
Если СписокTextОкруг.Количество()>0 Тогда
Округ=СписокTextОкруг[0].ТекстовоеСодержимое;
НовыйАдрес.Округ=Округ;
КонецЕсли;

СписокTextНаселенныйПункт = НайденныйАдрес.ПолучитьЭлементыПоИмени("LocalityName");
Если СписокTextНаселенныйПункт.Количество()>0 Тогда
НаселенныйПункт=СписокTextНаселенныйПункт[0].ТекстовоеСодержимое;
НовыйАдрес.НаселенныйПункт=НаселенныйПункт;
КонецЕсли;

СписокTextУлица = НайденныйАдрес.ПолучитьЭлементыПоИмени("ThoroughfareName");
Если СписокTextУлица.Количество()>0 Тогда
Улица=СписокTextУлица[0].ТекстовоеСодержимое;
НовыйАдрес.Улица=Улица;
КонецЕсли;

СписокTextДом = НайденныйАдрес.ПолучитьЭлементыПоИмени("PremiseNumber");
Если  СписокTextДом.Количество()>0 Тогда
Дом= СписокTextДом[0].ТекстовоеСодержимое;
НовыйАдрес.Дом=Дом;
КонецЕсли;
КонецЦикла;

КонецПроцедуры



23 Comments

  1. androgin

    Я, конечно, извиняюсь, но зачем городить такой огромный и затратные код, да еще и на сервере, если все можно сделать на клиенте?!

    Тем более все прекрасно работает в АвтоПодборе без нажатия на всякие кнопки ))))

    (файлик прикрепил ))) )

    &НаКлиенте
    Процедура СтрокаПоискаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
    ТекстПоиска = СокрЛП(Текст);
    Если СтрДлина(ТекстПоиска) > 5 Тогда // чтобы зря не гонять на сервер яндекса. Значение ставьте своё
    РазобратьАдресПоиска(ТекстПоиска);
    КонецЕсли;
    КонецПроцедуры
    
    &НаКлиенте
    Процедура РазобратьАдресПоиска(АдресПоиска)
    
    Соединение = Неопределено;
    
    Попытка
    Соединение = Новый HTTPСоединение(«geocode-maps.yandex.ru», , , , , , Новый ЗащищенноеСоединениеOpenSSL());
    Исключение
    Сообщить(«Не удалось установить соединение с сервером геодирования Яндекс. Проверьте правильность адреса сервера.»);
    Возврат;
    Конецпопытки;
    
    Если Соединение = Неопределено Тогда
    Возврат;
    КонецЕсли;
    
    ТелоОтвета = «»;
    Попытка
    Запрос = Новый HTTPЗапрос;
    Запрос.АдресРесурса = «/1.x/?format=json&geocode=»+АдресПоиска;
    Ответ = Соединение.Получить(Запрос);
    ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
    Соединение = Неопределено;
    Исключение
    Сообщить(ИнформацияОбОшибке().Описание);
    Возврат;
    КонецПопытки;
    
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ТелоОтвета);
    СтруктураАдреса = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть();
    
    // в СтруктураАдреса лежат адреса для разбора
    
    КонецПроцедуры

    Показать

    Reply
  2. ВикторП

    (1)

    Переход на сервер — это осталось от переноса рабочего кода в эту демо- обработку . На сервере — я ищу объекты из базы, например Регион из справочника.

    В Вашем примере после ввода каждой буквы начиная с 6 тоже будут обращения к серверу Яндекса 🙂

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

    Reply
  3. ВикторП

    (2) Да, на эту публикацию у меня есть ссылка.

    Отличие — в разборе ответа.

    Мой разбор был сделан до поддержки json платформой 1с. у меня разбор через DOM.

    Reply
  4. kiruha

    (3)

    Часто админы запрещают с сервера обращаться куда бы то ни было

    Reply
  5. ВикторП

    (5) Вариантов 2- 1. Можно открыть яндекс 2. можно выполнять на клиенте — но там тоже был «закидон», с которым я не разобрался, с какой- то периодичностью — что- то типа 150 , не проходило обращение к серверу Яндекса

    Reply
  6. androgin

    (3) так вот мой вариант менее затратный и объективный. Он может соазу показывать найденные адреса в поле поиска. И пользователю останется лишь выбрать нужный из найденный и система дальше его уже разложит.

    Уж намного лучше, чемс сервера гонять данные туда-сюда на клиент.

    Reply
  7. ВикторП

    (7) Хорошо. Для такого варианта использования обработки — да .

    В реальной работе с геоданными у меня ввода с клавиатуры нет, разбираемый адрес читается из файла , ищется наличие такого адреса в инф базе и при отсутствии — обращается на сервер Яндекса для разбора

    Reply
  8. androgin

    (8) Это все равно не логично.

    Возвращается куча адресов и пользователю снова приходится просматривать это список.

    двойная работа

    Reply
  9. androgin

    (8) ну и само использование временного файла уже можно не использовать.

    Тож быстрее

    Reply
  10. ВикторП

    (9) нелогично что? Что Яндекс возвращает по введенному тексту несколько адресов , так я понимаю?

    Я делаю так- когда возвращается один- записываю в базу этот ответ (геокординаты и измененный адрес), когда много адресов —

    ответственный сотрудник выбирает нужный.

    У нас ситуация еще хуже — для соотнесения данных к региону одного адреса мало , нужно еще доп информация не из Яндекса.

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

    Reply
  11. androgin

    (11) временный файл — вы его сами в коде создаете! Ни от кого он не присылается)))

    И опят же: сами говорите, что пользователю приходится выбирать из списка. А значит сервер-клиент.

    А если клиент обрабатывает — то и нелогично это

    Reply
  12. ВикторП

    (12) Спс, использование временного файла убрал.

    Reply
  13. androgin

    (13) ай-ай…

    как нехорошо то))

    кусок своего кода заменили моим)))

    а где «спасибо» в статье? ))))

    Reply
  14. ВикторП

    (14) см (13)

    Reply
  15. ВикторП

    (14) при неиспользовании временного файла уменьшение времени работы обработки не зафиксировано- в обоих случаях время работы меньше 1 секунды

    Reply
  16. androgin

    (16) я так понимаю, вы недавно в 1С, если подобное заявляете.

    То, что с временным файлом задействована файловая система — вас в принципе ни разу не волновало и вы понятия не имеете, что роли системы могут просто не позволить создавать эти файлы.

    Не говоря уже функциональности кода

    Reply
  17. androgin

    (15) спасибо не в комментариях говорят, уж если код вывесили на всеобщее обозрение

    Reply
  18. ВикторП

    (17) можете привести примеры ролей , которые не позволяют создать временный файл?

    Использование временного файла выигрыша во времени работы обработки не даёт. Метрика- время. Вы про какую метрику говорите?

    Что не так с функциональностью кода, уважаемый критик?

    (18)Код вывешен для разработчиков, его использование — например, для разбора ответа сервера геокодирования- поля уже определены + рабочая демо обработка

    Reply
  19. androgin

    (19) вебклиент, корпоративный комп, БезопасныйРежим.

    продолжать?

    Reply
  20. ВикторП

    Да, пожалуйста

    Reply
  21. Pim

    Плохо, что нельзя получить адрес в формате ФИАС. На худой конец, КЛАДР…

    Reply
  22. ВикторП

    Никто не обещал

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *