Как бы мы ни относились к качеству адресов ФИАС, работать с ними необходимо, ведь это единственная общероссийская адресная книга.
Поэтому рано или поздно нам придется решить проблему связи местонахождения недвижимости, юридического и физического адресов с адресом из ФИАС.
В данной статье описан опыт работы со списком адресообразующих элементов ФИАС, загруженным в базу данных под управлением PostgreSQL. Для работы с адресообразующими элементами ФИАС создано несколько функций на языке PL/pgSQL.
Полный текст статьи состоит из 4 частей.
Первая половина этой части статьи содержит комментарии по реализации функции.
Второй содержит исходный текст функции.
Тем читателям, которых интересуют только исходные тексты, мы предлагаем сразу перейти к Приложение .
Родословная адресообразующего элемента
Начнем с примера.Вызов fstf_AddressObjects_AddressObjectTree('bfc1236d-b5d2-4734-a238-3b1e4830e963') вернет следующий список записей.
Таблица 1. Результат выполнения функции fstf_AddressObjects_AddressObjectTree
АОГИД | Куррстатус | Статус акта | AOLevel | Короткое имя | Официальное имя |
---|---|---|---|---|---|
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 | 0 | 1 | 1 | край | Красноярск |
625497d3-22de-4390-b4b4-2febfbfc15ce | 0 | 1 | 3 | округ | Балахтинский |
39da6405-b3e6-4baf-b332-d47b73b4d5fb | 0 | 1 | 6 | п | Могущественный |
bfc1236d-b5d2-4734-a238-3b1e4830e963 | 0 | 1 | 7 | ул.
|
Новый |
- пластинка с характеристикой самой Новой улицы;
- три родительские записи о селе, районе и области, к которым принадлежит улица.
Полный текст функции приведен в Приложении в подразделе Создание функции fstf_AddressObjects_AddressObjectTree
С самого начала
Если вы знаете, как структурированы таблицы ФИАС, то можете пропустить этот раздел.Необходимость такой функции продиктована тем, что список адресообразующих элементов ФИАС (ADDROBJ) представляет собой древовидную структуру, в которой каждый элемент ссылается на идентификатор (AOGUID) родительской записи по значению поля ParentGUID. .
Те.
Просматривая исходные записи списка, вы обычно видите длинный список улиц.
Чтобы определить, в каком населенном пункте находится улица, необходимо по значению ParentGUID найти записи с данным идентификатором элемента.
Рис.
1. Иерархия адресообразующих элементов ФИАС.
Это не опечатка и не оговорка.
По значению ParentGUID можно найти не одну, а несколько записей.
Это означает, что идентификатор элемента, формирующего адрес, не является первичным ключом для таблицы, содержащей список ADDROBJ. Дело в том, что список адресообразующих элементов вместе с каждым элементом хранит историю его «переименования».
Те.
Под одним идентификатором элемента хранится не только текущее имя элемента, но и его предыдущие имена.
То есть отдельная запись в списке ADDROBJ хранит данные об адресообразующем элементе, а также характеристики календарного периода, в течение которого название элемента было актуально.
Таблица 2. История улицы «Красноярский край, Таймырский Долгано-Ненецкий район, Дудинка, Левинские пески, Береговая улица»
Идентификатор записи AOID | Идентификатор предыдущей записи PrevID | Идентификатор следующей записи NextID | Подписать согласно КЛАДР CurrStatus | Признак релевантности ActStatus | Дата начала периода StartDate | Дата окончания периода EndDate |
---|---|---|---|---|---|---|
fcf51361-5494-4edc-a6bc-d5c0d471c729 | 2a993f3b-5743-426c-8b7d-b5c7affe49cd | 0 | 1 | 25.11.2015 0:00 | 06.06.2079 0:00 | |
2a993f3b-5743-426c-8b7d-b5c7affe49cd | 9199c92b-18a5-431a-8b13-f54abe36e84f | fcf51361-5494-4edc-a6bc-d5c0d471c729 | 7 | 0 | 30.09.2015 0:00 | 25.11.2015 0:00 |
9199c92b-18a5-431a-8b13-f54abe36e84f | b06ff65e-aadb-42eb-9c70-a8548a40645c | 2a993f3b-5743-426c-8b7d-b5c7affe49cd | 6 | 0 | 28.09.2015 0:00 | 30.09.2015 0:00 |
b06ff65e-aadb-42eb-9c70-a8548a40645c | a997aa7c-f2b1-4b7e-9471-5fc1f51a6752 | 9199c92b-18a5-431a-8b13-f54abe36e84f | 5 | 0 | 08.04.2013 0:00 | 28.09.2015 0:00 |
a997aa7c-f2b1-4b7e-9471-5fc1f51a6752 | b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b | b06ff65e-aadb-42eb-9c70-a8548a40645c | 4 | 0 | 11.01.2013 0:00 | 08.04.2013 0:00 |
b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b | 327b28cc-5171-43c6-bd88-a0a2172bbf71 | a997aa7c-f2b1-4b7e-9471-5fc1f51a6752 | 3 | 0 | 07.12.2012 0:00 | 11.01.2013 0:00 |
327b28cc-5171-43c6-bd88-a0a2172bbf71 | fb7b54db-7efb-4aaf-b4cb-2364b35b80b3 | b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b | 2 | 0 | 01.02.2012 0:00 | 07.12.2012 0:00 |
327b28cc-5171-43c6-bd88-a0a2172bbf71 | fb7b54db-7efb-4aaf-b4cb-2364b35b80b3 | b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b | 1 | 0 | 01.02.2012 0:00 | 07.12.2012 0:00 |
Для этого каждая запись о периоде релевантности элемента содержит два указателя на предыдущий (PrevID) и последующие периоды (NextID).
Первый период адресообразующего элемента не имеет указателя на предыдущий период, а последний (текущий) — указателя на следующий период.
Рис.
2. Основные поля записи адресообразующего элемента ФИАС.
Период релевантности характеризуется датами начала и окончания периода StartDate и EndDate соответственно.
При этом даты начала первого периода и окончания последнего имеют условные значения.
Датой начала первого периода принимается «01.01.1900 0:00», а датой окончания последнего (текущего) периода принимается «06.06.2079 0:00».
Текущее (действительное на данный момент) наименование адресообразующего элемента указывается в записи последнего периода при условии, что он не заполнен, т. е.
дата окончания периода больше или равна текущей дате.
Для упрощения поиска записи о текущем периоде элемента помимо даты начала и окончания периода введены еще два поля: CurrStatus и ActStatus. ActStatus принимает вполне ожидаемые значения: «1» — текущая версия характеристик элемента, «0» — не текущая или историческая версия, как указано в справочнике.
Сложнее ситуация со значениями поля CurrStatus. Используя его значения, решаются две проблемы задачи одновременно: устанавливается идентификатор каждой версии записи об адресообразующем элементе и присваивается признак релевантности записи.
Поэтому последняя текущая запись элемента содержит в этом поле значение «0», а все исторические записи нумеруются в порядке появления – «1» — самая старая запись, следующая — «2» и т.д. В таблице 2 приведен перечень записей с вариантами описания улицы Береговой в селе Левинские Пески.
В этом списке предыдущая запись текущей записи содержит цифру «7» в поле CurrStatus.
Как это работает
Рис.
3. Упрощенная реализация функции fstf_AddressObjects_AddressObjectTree.
Для реализации функции предлагается использовать рекурсивный запрос, аналогичный показанному на рис.3, где a_AOGUID — идентификатор адресообразующего элемента, a_CurrStatus — признак релевантности по КЛАДР.
Оба значения передаются в функцию через параметры.
Как и любой рекурсивный запрос, этот состоит из двух частей: первая часть содержит первую запись элемента с идентификатором a_AOGUID, следующая рекурсивная часть последовательно содержит все текущие родительские записи по отношению к записям, полученным в ходе предыдущих итераций.
Переход к родительскому элементу осуществляется с использованием ссылки ParentGUID текущей записи.
Здесь важно, чтобы каждая итерация приводила только к одной записи.
Для этого на значение атрибута CurrStatus накладывается ограничение.
Пример результата применения рекурсивного запроса при отсутствии уникальной записи хотя бы на одном шаге итерации показан на рис.
3. Возникает вопрос: почему ограничение на значение CurrStatus реализовано через вложенный подзапрос, а не присвоением реальных значений? Во-первых, потому что текущая запись об элементе не всегда имеет CurrStatus = 0, как показывает таблица 4. Во-вторых, функция должна возвращать результат для нерелевантных имен элементов.
В том числе даже в том случае, когда на пути между начальным и конечным элементами находится элемент, для которого не объявлена текущая запись.
Таблица 3. Результат выполнения функции над элементом с неуникальным атрибутом выбора записи
АОГИД | Куррстатус | Статус акта | AOLevel | Короткое имя | Официальное имя |
---|---|---|---|---|---|
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 | 0 | 1 | 1 | край | Красноярск |
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 | 0 | 1 | 1 | край | Красноярск |
3d4c8618-9e22-4838-8f89-80da6851da90 | 0 | 1 | 3 | округ | Рыбинский |
719b789d-2476-430a-89cd-3fedc643d821 | 51 | 0 | 4 | г | Заозерный |
719b789d-2476-430a-89cd-3fedc643d821 | 51 | 1 | 4 | г | Заозерный |
.ao.currstatus = (SELECT MIN(iao.currstatus) FROM fias_AddressObjects iao WHERE ao.aoguid = iao.aoguid)
который присутствует во второй части рекурсивного запроса, не совсем корректен, исходя из правила присвоения значений атрибуту CurrStatus. Действительно, если среди записей адресообразующего элемента нет текущей (CurrStatus=0), то самой «новой» является запись с максимальным, т.е.
последним использованным значением атрибута CurrStatus. При использовании вышеуказанного условия из записей неактуального элемента выбирается самая старая.
Таблица 4. Элемент с повторяющимся ненулевым значением CurrStatus.
АОГИД | Куррстатус | Статус акта | AOLevel | Короткое имя | Официальное имя |
---|---|---|---|---|---|
719b789d-2476-430a-89cd-3fedc643d821 | 51 | 0 | 4 | г | Заозерный |
719b789d-2476-430a-89cd-3fedc643d821 | 51 | 1 | 4 | г | Заозерный |
ao.currstatus = CASE WHEN 0 < ALL(SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE ao.aoguid = iao.aoguid)
Теги: #fias #postgresql #хранимая процедура #postgresql
-
Как Появилась Комбинация Wasd?
19 Oct, 24 -
Ноутбуки В Аду
19 Oct, 24 -
С Праздником Вас, Хабразащитники!
19 Oct, 24