Наверное, каждый программист рано или поздно сталкивается с пробемой нормализации адресов, которые были введены пользователями в произвольном или "частично произвольном" формате. И здесь нет какой-либо серебряной пули, люди пишут множество различных проверок, замен подстрок и т.д., в конце концов, можно отредактировать записи вручную или заставить пользователей это сделать. Но если количество адресов достаточно большое и измеряется десятками и сотнями тысяч становится совсем грустно... Как один из вариантов решения данной проблемы - использование сторонних сервисов (например, Яндекс Геокодер и прочие). В нашем случае, был выбран сервис DaData.ru по причине его тесной связи с КЛАДР и ФИАС, кроме того, сервис показал хорошие результаты - из примерно 84 000 адресов, около 4 000 были помечены как требующие ручной проверки, из них 20% были корректными, а остальные, в большинстве случаев, были заполнены изначально неправильно (например, указан только город и всё).
Единственный существенный недостаток сервиса - то, что он платный, стоимость стандартизации одного адреса составляет 5-10 коп. (https://dadata.ru/pricing/), 100 адресов даются бесплатно после регистрации. Важное уточнение - стандартизируются только российские адреса.
DaData имеет очень простой в использовании API - https://dadata.ru/api/clean/ .
Первое, что нужно сделать - зарегистрироваться в сервисе и получить API-Ключ и Секретный ключ.
Весь код нормализации адресов:
Процедура НормализоватьАдреса()
КлючиДоступа = Новый Структура;
КлючиДоступа.Вставить("APIКлюч" , "<Ваш API-Ключ>");
КлючиДоступа.Вставить("СекретныйКлюч", "<Ваш Секретный ключ>");
ТаблицаДанных = ПолучитьСтруктуруТаблицыАдресов();
// заполнение таблицы исходными адресами
ДобавитьАдресДляНормализации(ТаблицаДанных, "мск сухонска 11/-89");
ДобавитьАдресДляНормализации(ТаблицаДанных, "москва Сухонская улица 11 89");
НормализоватьАдресаТаблицы(ТаблицаДанных, КлючиДоступа);
// TODO: дальнейшая работа с ТаблицаДанных
КонецПроцедуры
Функция ПолучитьСтруктуруТаблицыАдресов()
ТаблицаДанных = Новый ТаблицаЗначений;
ТаблицаДанных.Колонки.Добавить("ИсходныйАдрес");
// Поля таблицы, совпадающие по имени с полями ответа сервиса.
ТаблицаДанных.Колонки.Добавить("result"); // Нормализованный адрес
ТаблицаДанных.Колонки.Добавить("postal_code"); // Индекс
ТаблицаДанных.Колонки.Добавить("region_with_type"); // Регион
ТаблицаДанных.Колонки.Добавить("city_with_type"); // Город
ТаблицаДанных.Колонки.Добавить("settlement_with_type"); // Населенный пункт
ТаблицаДанных.Колонки.Добавить("city_district_with_type"); // Район
ТаблицаДанных.Колонки.Добавить("street_with_type"); // Улица
ТаблицаДанных.Колонки.Добавить("house"); // Дом
ТаблицаДанных.Колонки.Добавить("flat"); // Квартира
ТаблицаДанных.Колонки.Добавить("qc"); // Код проверки
Возврат(ТаблицаДанных);
КонецФункции
Процедура ДобавитьАдресДляНормализации(ТаблицаДанных, Адрес)
Строка = ТаблицаДанных.Добавить();
Строка.ИсходныйАдрес = Адрес;
КонецПроцедуры
Процедура НормализоватьАдресаТаблицы(ТаблицаДанных, КлючиДоступа)
Для Каждого СтрокаАдреса Из ТаблицаДанных Цикл
ОтветСервиса = ЗапросСервисаНормализации(СтрокаАдреса.ИсходныйАдрес, КлючиДоступа);
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ОтветСервиса);
Данные = ПрочитатьJSON(Чтение)[0];
Чтение.Закрыть();
ЗаполнитьЗначенияСвойств(СтрокаАдреса, Данные);
КонецЦикла;
КонецПроцедуры
Функция ЗапросСервисаНормализации(Адрес, КлючиДоступа)
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type" , "application/json");
Заголовки.Вставить("Authorization", "Token " + КлючиДоступа.APIКлюч);
Заголовки.Вставить("X-Secret" , КлючиДоступа.СекретныйКлюч);
Запрос = Новый HTTPЗапрос("/api/v2/clean/address", Заголовки);
Запрос.УстановитьТелоИзСтроки("[""" + Адрес + """]", КодировкаТекста.UTF8,
ИспользованиеByteOrderMark.НеИспользовать);
Соединение = Новый HTTPСоединение("dadata.ru", 443,,,,,
Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено),);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ОтветСервера = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Возврат(ОтветСервера);
КонецФункции
Приведенный код будет работать на платформе 8.3.6 и более, поскольку в нем применены функции для работы с JSON (http://v8.1c.ru/o7/201410json/). Если версия платформы меньше - нужно использовать сторонний парсер.
Описание работы кода:
Основная функция в которой происходит заполнение таблицы адресов и их нормализация - НормализоватьАдреса.
Создается таблица значений, в которой будут хранится исходные и обработанные адреса (функция ПолучитьСтруктуруТаблицыАдресов). Следует заметить, что в эту таблицу можно добавить дополнительные поля, имена которых совпадают с именами свойств возвращаемого JSON-объекта - https://dadata.ru/api/clean/#response , а данных в ответе очень много, вплоть до площади квартиры и ее стоимости.
Далее, с помощью процедуры ДобавитьАдресДляНормализации заполняем таблицу исходными адресами.
Последнее, что нужно сделать - вызвать процедуру НормализоватьАдресаТаблицы и передать ей в качестве аргументов таблицу с исходными адресами и ключи доступа к сервису.
Для каждой строки, указанной в таблице делается POST-запрос (https://dadata.ru/api/v2/clean/address) , в заголовках указываются ключи доступа, в теле запроса - исходный адрес, а в качестве результата сервис возвращает JSON-массив с одним элементом, в свойствах которого содержится вся необходимая информация.
Вот и всё. За бортом остались: обработка всевозможных ошибок, хранение адресов.