Как стать автором
Поиск
Написать публикацию
Обновить

ГАР БД ФИАС или очень полная БД ФИАС

Время на прочтение6 мин
Количество просмотров26K

01.06.2020 ИФНС опубликовала новый формат выгрузки данных
17.12.2020 Мягко намекнула, что в 2021 будет использоваться только он
01.09.2021 Это свершилось: теперь просто "полная БД ФИАС" перестала обновляться и требуется использовать ГАР БД ФИАС

Частично импортируем ГАР БД ФИАС в MySQL на PHP.

Новость, мягко говоря, не очень, для тех кому нужно получить иерархию улиц и список домов с почтовыми индексами, особенно учитывая, что КЛАДР до сих жив. А не очень из-за того, что файлик данных с 12Гб резко пополнел до 28Гб. Конечно, можно возразить, что скачал один раз и по чуть-чуть обновляйся. Да, можно, если хранить нужные файлы данных целиком и постоянно накатывать на них обновления, но... наличие багов (даже в полной версии) добавит радости.

Небольшой офф

Возможно имеет смысл написать небольшую библиотеку, функционал которой - скачивать только необходимую часть zip архива для распаковки конкретного файла с web сервера, поддерживающего докачку. Весьма актуально, т.к. из этих 28Гб требуется значительно меньшая часть. Если вы знаете, что это уже есть где-то "из коробки" или реализовано отдельной библиотекой - пожалуйста, напишите.

Теперь новая БД содержит иерархическую информацию об адресных объектах в двух вариантах:
- по административно-территориальному устройству (для упорядоченного осуществления функций государственного управления) - на основе этого код ОКАТО
- по муниципальному устройству (для организации местного самоуправления) - соответственно, ОКТМО
Не каждый объект "доступен" в обоих иерархиях. Например, если мы возьмём г. Карабулак, то по административно-территориальному устройству он находится в республике Ингушетия, а по муниципальному устройству расположен городском округе города Карабулак, который в свою очередь в республике Ингушетия и "не участвует" в административно-территориальном устройстве.

Моей целью является получение двух таблиц только с актуальной на момент импорта информацией об иерархической структуре адресов (от региона до, обычно, улицы) и списка жилых домов (не интересуют гаражи, шахты, подвалы...) с почтовыми индексами. NB! При выборе адреса в реальных проектах рекомендую сохранять полный иерархический путь, а не только идентификатор - впоследствии адрес может стать неактуальным (выбрать его нельзя - дома реально нет, а сохранить информацию корректно необходимо).

Таблица gar_addr, ключевое поле id. Иерархию определяют указывающие на него owner_adm и owner_mun. Субъекты РФ (и Байконур) имеют level=1, owner_adm=owner_mun=0. Содержит информацию о названиях адресных объектов (NAME, TYPENAME) и говорящие за себя OKATO, OKTMO, KLADR. OBJECTGUID, ранее в ФИАС именовался AOGUID, является идентификатором адресного объекта (уникальный для актуальных записей; не уникальный, если используются исторические устаревшие записи). OBJECTID аналогичен по значению OBJECTGUID, но уже целочисленный.

Таблица gar_house - список домов. owner_* указывает на gar_addr.id.
Содержит номер дома в 3 полях: основной и 2 дополнительных (и это не я придумал, ADDNUM2 в актуальных данных отсутствует, хотя ранее использовался) и, соответственно, их типы (например: дом, литера, корпус). Описание этих значений в AS_HOUSE_TYPES...XML. ОКАТО и ОКТМО, почтовый индекс.

Импорт и частичное описание структуры.
Всё описанное ниже реализовано в исходниках.

a) Прежде чем начать, проверим zip файл. Убедимся, что он похож на нужный нам и в нём хотя бы есть файлы as_addr_obj... для каждого интересующего нас региона.

Ранее в ФИАС был один файл со всеми регионами, теперь данные о каждом регионе в своей директории.

b) Импортируем файлы AS_ADDR_OBJ_(дата)_(идентификатор).XML, содержащие информацию об адресных объектах.

Все элементы однотипные, выбираем только ISACTUAL=1 и ISACTIVE=1. И получить мы можем только название объекта и поля OBJECTID, OBJECTGUID. Теперь в этом файле нет указания на дочерний объект, нет данных об ОКАТО, ОКТМО - все они находятся в отдельном XML файле.

c) Проверим, что OBJECTID является уникальным. Если нет - надо разбираться, что это вызвало и писать в ИФНС. Ранее в ФИАС такая проблема часто возникала. Проиндексируем таблицу по этому полю - по нему будет определяться адресный объект при обработке последующих XML с данными.

d) Импортируем файлы AS_HOUSES... - дома. Аналогично, интересуют только актуальные записи и дополнительно отсеиваем по типам (дом, здание, строение, корпус). И в этом файле тоже нет данных, какому адресному объекту принадлежит дом.

e) Проиндексируем дома по OBJECTID и убедимся, что все записи уникальны.

f,g) Настало время создать иерархию. Анализируем файлы AS_ADM_HIERARCHY_... и AS_MUN_HIERARCHY_... отбирая только актуальные записи. Пара OBJECTID и PARENTOBJID указывает на OBJECTID объекта.

В этих файлах собрана информация по всем объектам региона. В моём случае PARENTOBJID может быть только адресный объект, но реально в PARENTOBJID может быть и дом. Дочерним у него будет является, например, квартира (файлы AS_APARTMENTS_...).

h) Проиндексируем gar_addr по owner_adm и owner_mun

i) И начнём искать ошибки :) Отметим достижимыми все субъекты РФ. И далее будем отмечать достижимыми все записи, родители которых тоже достижимы, до тех пора, пока количество достижимых не изменится. Так делаем по обоим полям - owner_adm, owner_mun. Если owner_adm = owner_mun = 0, то оказалось так, что мы не можем выбрать этот объект - это ошибка. Информация об этом будет сохранена в отчёте, а запись удалена. Отправляется bug-report

Самизнаетекому

ГАР, полная выгрузка
В файле AS_ADDR_OBJ_20210906_2a908987-3309-454e-9364-b75afd551e12.XML
есть объект с ISACTUAL="1" ISACTIVE="1"

<OBJECT ID="1823960" OBJECTID="95254004" OBJECTGUID="e3b0cdce-8a09-4955-8a43-a85ae759cfde" CHANGEID="138210670" NAME="2-й Мартозанова" TYPENAME="пер" LEVEL="8" OPERTYPEID="10" PREVID="0" NEXTID="0" UPDATEDATE="2020-01-15" STARTDATE="2020-01-15" ENDDATE="2079-06-06" ISACTUAL="1" ISACTIVE="1">

однако, его OBJECTID="95254004" вообще не встречается в AS_ADM_HIERARCHY_20210906_221e769c-cfac-4af6-9a20-04cc9c2e1fe5.XML AS_MUN_HIERARCHY_20210906_214fdb76-13c8-49cf-90ef-b5f05c4ee6df.XML

Таких проблем в выгрузке от 07.09.2021 - 107 (из 1405143+107 записей)

j) Теперь проверяем дома. Удаляем и логируем записи без owner_*, т.к. до них мы не сможем добраться. Логично считать ошибкой отсутствие owner в любом из типе устройств - дом же есть, значит до него надо как-то добраться. Разбираться с такими ситуациями придётся вручную (аналогично предыдущему пункту).

В выгрузке от 07.09.2021 - по owner_adm все дома достижимы; по owner_mun - 1639 домов (из 25842972 интересующих) не имеют владельца.

Надеяться, что дом обычно расположен на конкретной улице и owner_adm должен совпадать с owner_mun не получится. Крайне малое количество домов имеют разных владельцев, например один и тот же дом "Х":
Башкортостан, Уфимский р-н, Зубовский с/с, д. "Х"
Башкортостан, Уфимский м.р-н, с.п. Зубовский сельсовет, тер. СНТ Авиатор, ул N1, д. "Х"

В выгрузке от 07.09.2021 - не совпадающих owner_adm и owner_mun всего 2231 объект и есть огромное желание пренебречь одним из столбцов owner_*.

k) Настало время заполнить OKATO, OKTMO и KLADR. Информация о них в файле AS_ADDR_OBJ_PARAMS_... и надо выбрать VALUE из актуальных записей соответствующего TYPEID (6,7,11). Какие данные ещё есть в этом файле указано в AS_PARAM_TYPES_....XML

Всё просто. Из плюсов, что при обработки иерархии мы не знаем к какому объекту относится OBJECTID - здесь же всё однозначно, искать надо только по таблице addr.

l) Аналогично собираем данные OKATO, OKTMO, POSTALCODE для домов. Это уже другой файл - AS_HOUSES_PARAMS_... с аналогичной предыдущему структурой.

m) Удаляем вспомогательные столбцы и индексы

n,o) Выполняем слияние всех таблиц по регионам в одну общую.
p) Создаём нужные индексы
q) Переименовываем временные таблицы в нормальные имена

Чтобы получить этот результат надо обработать:

XML файлы

Описание

Исходные данные, Гб.

AS_ADDR_OBJ_...

Адресные объекты

0.53

AS_HOUSES_...

Дома

18.77

AS_ADM_HIERARCHY_...

Административно-территориальное и муниципальное устройство. Как минимум один набор необходим.

22.18

AS_MUN_HIERARCHY_...

21.68

AS_ADDR_OBJ_PARAMS_...

Параметры адресных объектов, не обязательно если вам не нужны ОКАТО, ОКТМО

3.74

AS_HOUSES_PARAMS_...

Параметры домов (здесь "спрятаны" почтовые индексы)

61.07

У меня этот процесс занял 28 часов 13 минут.

Приложения:
Исходный код, реализующий импорт. (для Windows; для Linux придётся переписать bat на *sh и команды извлечения файла из архива - поискать exec в php файлах).

P.S.

MySQL dump - только адресные объекты (67Мб).
Вероятно, в дальнейшем дамп будет удалён - потеряет свою актуальность; формат, используемый мной, изменится. Обычно информацию по домам и их индексам я группирую по владельцам - что позволяет уменьшить размер БД до 400Мб и использовать её даже на слабых VDS.

P.P.S. locdb.ru давно не обновлялся, но, надеюсь, скоро выложу актуальную базу. "Живых" населённых пунктов стало значительно больше: не только не менее 1000 жителей, также учитываются населённые пункты с большим количеством домов.

Теги:
Хабы:
Всего голосов 6: ↑6 и ↓0+6
Комментарии21

Публикации

Ближайшие события