Address Processor
github.com/Tensionix/address-processor ↗
Адрес — худшее, чем можно сводить таблицы, и одновременно единственное, что есть почти в любых муниципальных данных. Один и тот же дом в двух выгрузках выглядит как «г. Сургут, ул. Ленина, д. 12» и «Сургут, Ленина 12»; «пр-т Мира, 5к1» и «проспект Мира, дом 5, корпус 1». Сопоставление по точному совпадению даёт десятую часть попаданий, сверка глазами — час на сотню строк и ошибки, которых никто не замечает. Строка ищет пару сначала по точному совпадению, затем по разобранным частям, затем по нормализованному отпечатку и только потом приблизительно. Порядок не случаен: строгое совпадение никогда не проигрывает приблизительному — иначе похожая строка из соседнего района обошла бы верную. Программа выравнивает таблицы по эталонному столбцу адресов, собирает чистые адреса из таблиц, документов Word и ODT, текста, CSV, разметки и PDF с текстовым слоем, ведёт справочник со слотами — индекс, муниципалитет, населённый пункт, улица, дом, код территории — и раскладывает его по выбранной иерархии.
Audion Address Processor
English · Руководство · ОКТМО · Справочник · Установка
Содержание
- Зачем это сделано
- Как решается
- Что умеет
- Принципы
- Документация
- Техническая часть
- Источники
- Настройки
- Диагностика
Работа с российскими адресными данными: сопоставление таблиц по адресу, сборка чистых адресов из разнородных источников, эталонный справочник, коды территорий, сортировка и разбор на составляющие.
Зачем это сделано
Адрес — худшее, по чему можно сводить таблицы, и одновременно единственное, что есть в большинстве муниципальных данных.
Один и тот же дом в двух выгрузках выглядит так: г. Сургут, ул. Ленина, д. 12 и Сургут, Ленина 12. Или пр-т Мира, 5к1 и проспект Мира, дом 5, корпус 1. Или в одной таблице адрес в одном столбце, а в другой разложен на четыре.
Сопоставление по точному совпадению даст десять процентов попаданий. Сравнение на глазок — час работы на сотню строк и ошибки, которые никто не заметит.
Как решается
Пять этапов сопоставления с уточняющими проходами, от строгого к мягкому. Строка ищет пару сначала точным совпадением, затем по разобранным составляющим, затем по приведённому к общему виду отпечатку, и лишь потом приблизительно.
Порядок не случаен: строгое совпадение никогда не проигрывает приблизительному. Если дом нашёлся точно, мягкий поиск уже не рассматривается — иначе похожая строка из соседнего района перебьёт верную. Найденная пара сразу изымается из пула кандидатов, поэтому один и тот же дом не может быть выдан дважды.
Полный разбор проходов — в Справочнике.
Что умеет
Выравнивать таблицы по эталонному адресному столбцу — и переносить рядом стоящие столбцы вместе с адресами, чтобы данные не разъехались.
Собирать чистые адреса из чего угодно: таблиц, документов Word и ODT, текста, CSV, разметки и PDF с текстовым слоем.
Вести эталонный справочник со слотами: индекс, муниципалитет, населённый пункт, улица, дом, код территории и технические ключи.
Сортировать и разбирать справочник по выбранной иерархии слотов — от региона к дому или в любом другом порядке.
Переносить колонки между книгами по адресу дома — не копированием строк, а через Excel, с сохранением формул, оформления, листов и порядка строк основной книги.
Опираться на реестр ОКТМО Росстата. Регион и муниципалитет выбираются из официального реестра, названия населённых пунктов раскрываются в падежные формы и сужают поиск до нужной территории. Реестр скачивается кнопкой прямо из окна — см. ОКТМО.
Читать кривые шапки. Двухуровневый заголовок собирается целиком: строка без значений-данных, стоящая под объединённым родительским заголовком, считается подзаголовком независимо от того, какими словами он написан. Столбец «Проектная мощность, мест» над «по корпусам» становится «Проектная мощность, мест по корпусам», а не безымянным column_5, и сама строка подзаголовков не уезжает в данные.
Принципы
Исходники не меняются. Результат всегда пишется в отдельную папку. Что пришло — то и осталось.
Столбцы задаются как в Excel. A, B, AC — теми же буквами, что видны в заголовке таблицы, а не порядковыми номерами.
Настройки можно не править руками. Всё лежит в файле настроек, но столбцы безопасно задаются прямо в окне.
Каждый прогон оставляет отчёт. Рядом с результатом в report/ появляется JSON: что нашлось, чем нашлось, что осталось без пары.
Окно и командная строка делают одно и то же. Любая операция запускается и без окна — командой address_cli.cmd, с теми же умолчаниями полей, — см. Справочник.
Таблица на выходе читаема. Ширина столбцов подбирается по содержимому, длинный текст переносится, высота строк растёт. Мелочь, но без неё выгрузку приходится доводить руками каждый раз.
Документация
| Документ | О чём |
|---|---|
| Руководство пользователя | Окно, рабочие папки, все команды по шагам |
| ОКТМО и ключи проекта | Реестр Росстата, скачивание, обновление, кэш, ключи, пины |
| Технический справочник | Слоты, проходы сопоставления, настройки, отчёты |
| Установка и запуск | Portable-окружение, сборка окна, обслуживание |
| Карта файлов проекта | Где что лежит в исходниках |
Техническая часть
Источники
.xlsx, .docx, .odt, .txt, .csv, .md и .pdf с текстовым слоем. Старые .doc и .xls конвертируются отдельной командой.
Текст из PDF читает библиотека PyMuPDF, а она распространяется под GNU AGPL 3.0. Собственный код программы остаётся под Apache 2.0, но сборка целиком — программа вместе с PyMuPDF — идёт на условиях GNU AGPL 3.0; подробнее — в файле NOTICE.
Настройки
config/project.yaml. В окне доступны безопасные поля для столбцов — файл править не обязательно.
Диагностика
Отдельный разбор работы обработчика и безопасная очистка полностью пустых строк — без риска зацепить строки с данными в одном столбце.
Программа портативная: распакованная папка и есть установленная программа. Реестр не трогается, удаление — удалить папку.
$name = "Audion_Address_Processor_v2.0.1_Full.zip"
Invoke-WebRequest "https://audion.dev/get/address-processor/2.0.1/Audion_Address_Processor_v2.0.1_Full.zip" -OutFile $name
Invoke-WebRequest "https://audion.dev/get/address-processor/2.0.1/Audion_Address_Processor_v2.0.1_Full.zip.sha256" -OutFile "$name.sha256"
$want = (Get-Content "$name.sha256").Split(" ")[0]
$have = (Get-FileHash $name -Algorithm SHA256).Hash.ToLower()
if ($want -ne $have) { throw "сумма не сошлась: загрузка повреждена" }
Expand-Archive $name -DestinationPath ".\address-processor"