Это вторая часть статьи, в которой изложен опыт работы со списком адресообразующих элементов ФИАС, загруженным в базу данных под управлением PostgreSQL. С первой частью статьи можно ознакомиться здесь.
Полный текст статьи состоит состоит из 4 частей. В первой половине этой части статьи изложены комментарии к реализации функции. Во второй — исходный текст функции. Тем из читателей, кого интересуют только исходные тексты, предлагаем сразу перейти к Приложению.
Основная идея функции fsfn_AddressObjects_TreeActualName в том, чтобы возвратить соединенные в одну строку название элемента вместе с названиями всех его предков. Например, пусть функции поиска родословной элемента (fstf_AddressObjects_AddressObjectTree) возвращает следующий список значений.
Таблица 5. результат выполнения функции fstf_AddressObjects_AddressObjectTree('bfc1236d-b5d2-4734-a238-3b1e4830e963')
Тогда fsfn_AddressObjects_TreeActualName('bfc1236d-b5d2-4734-a238-3b1e4830e963') должна возвратить:
«Красноярский край, Балахтинский р-н, п Могучий, ул Новая»
У функции есть еще одни необязательный параметр массив масок (a_MaskArray), с помощью которого можно включать в результат не все названия элементов, а только те, которые нужны.
Текст функции приведен в разделе Приложения «Создание функции fsfn_AddressObjects_TreeActualName».
Основу реализации функции составляет вызов fstf_AddressObjects_AddressObjectTree (описанная в первой части статьи) и цикл по возвращаемым ей записям, в теле которой формируется полное наименование адресообразующего элемента путем сцепления (конкатенации) всех наименований в одну строку. Эта строка в конце концов будет возвращения функцией fsfn_AddressObjects_TreeActualName.
Далее будут поясняться детали.
Во-первых, порой нет необходимости в том, чтобы результат функции обязательно включал наименования всех предков текущего элемента. Например, в пределах Красноярского края вместо «Красноярский край, Балахтинский р-н, п Могучий, ул Новая», чаще используют укороченную форму «Балахтинский р-н, п Могучий, ул Новая». А внутри города Красноярска вместо адреса «Красноярский край, г Красноярск, д Песчанка, ул Сергея Лазо» чаще используют «д Песчанка, ул Сергея Лазо».
Для того чтобы иметь возможность управлять разными формами написания полного наименования адресообразующего элемента введен параметр массив масок (a_MaskArray), который содержит последовательность указателей (масок) на группы элементов.
Таблица 6. Список масок функции
Во-вторых, для того чтобы реализовать построение полного наименования в соответствии с массивом масок создана вспомогательная функция fsfn_AddressObjects_ObjectGroup, которая относит каждый адресообразующий элемент к определенной группе.
Таблица 7. Значения, возвращаемые функцией fsfn_AddressObjects_ObjectGroup
Список значений, возвращаемых функцией fsfn_AddressObjects_ObjectGroup, приведен в Таблица 5.
Цель создания этой функции в том чтобы собрать в одном месте все особенности (если хотите, то «костыли») определения группы элемента. С детальной реализацией этой функции можно ознакомиться в разделе Приложения «Создание функции fsfn_AddressObjects_ObjectGroup».
Комбинация значений функции и поля AOLevel (уровень адресообразующего элемента) вместе с проверкой на присутствие маски группы массиве масок позволяет определять должно ли название текущего элемента включаться в строку результата.
Например, признаком того, что название основного населенного пункта должно включаться в полное наименование элемента, является истинность следующего выражения:
Спасибо за внимание!
Полный текст статьи состоит состоит из 4 частей. В первой половине этой части статьи изложены комментарии к реализации функции. Во второй — исходный текст функции. Тем из читателей, кого интересуют только исходные тексты, предлагаем сразу перейти к Приложению.
Полное наименование адресообразующего элемента
Основная идея функции fsfn_AddressObjects_TreeActualName в том, чтобы возвратить соединенные в одну строку название элемента вместе с названиями всех его предков. Например, пусть функции поиска родословной элемента (fstf_AddressObjects_AddressObjectTree) возвращает следующий список значений.
Таблица 5. результат выполнения функции fstf_AddressObjects_AddressObjectTree('bfc1236d-b5d2-4734-a238-3b1e4830e963')
AOGUID | CurrStatus | ActStatus | AOLevel | ShortName | FormalName | ObjectGroup |
---|---|---|---|---|---|---|
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 | 0 | 1 | 1 | край | Красноярский | Region |
625497d3-22de-4390-b4b4-2febfbfc15ce | 0 | 1 | 3 | р-н | Балахтинский | Territory |
39da6405-b3e6-4baf-b332-d47b73b4d5fb | 0 | 1 | 6 | п | Могучий | Locality |
bfc1236d-b5d2-4734-a238-3b1e4830e963 | 0 | 1 | 7 | ул | Новая | Street |
Тогда fsfn_AddressObjects_TreeActualName('bfc1236d-b5d2-4734-a238-3b1e4830e963') должна возвратить:
«Красноярский край, Балахтинский р-н, п Могучий, ул Новая»
У функции есть еще одни необязательный параметр массив масок (a_MaskArray), с помощью которого можно включать в результат не все названия элементов, а только те, которые нужны.
Текст функции приведен в разделе Приложения «Создание функции fsfn_AddressObjects_TreeActualName».
Как это работает
Основу реализации функции составляет вызов fstf_AddressObjects_AddressObjectTree (описанная в первой части статьи) и цикл по возвращаемым ей записям, в теле которой формируется полное наименование адресообразующего элемента путем сцепления (конкатенации) всех наименований в одну строку. Эта строка в конце концов будет возвращения функцией fsfn_AddressObjects_TreeActualName.
Далее будут поясняться детали.
Во-первых, порой нет необходимости в том, чтобы результат функции обязательно включал наименования всех предков текущего элемента. Например, в пределах Красноярского края вместо «Красноярский край, Балахтинский р-н, п Могучий, ул Новая», чаще используют укороченную форму «Балахтинский р-н, п Могучий, ул Новая». А внутри города Красноярска вместо адреса «Красноярский край, г Красноярск, д Песчанка, ул Сергея Лазо» чаще используют «д Песчанка, ул Сергея Лазо».
Для того чтобы иметь возможность управлять разными формами написания полного наименования адресообразующего элемента введен параметр массив масок (a_MaskArray), который содержит последовательность указателей (масок) на группы элементов.
Таблица 6. Список масок функции
Значение | Примечание |
---|---|
{ST} | Маска — улица |
{ZC} | Маска — почтовый индекс |
{DT} | Маска — городской район |
{LP} | Маска — подчиненный населенный пункт |
{LM} | Маска — основной населенный пункт |
{TP} | Маска — района субъекта федерации |
{TM} | Маска — субъект федерации (регион) |
{CY} | Маска — страна |
Во-вторых, для того чтобы реализовать построение полного наименования в соответствии с массивом масок создана вспомогательная функция fsfn_AddressObjects_ObjectGroup, которая относит каждый адресообразующий элемент к определенной группе.
Таблица 7. Значения, возвращаемые функцией fsfn_AddressObjects_ObjectGroup
Значение | Примечание |
---|---|
Country | Признак группы — Страна |
Region | Признак группы — Регион |
City | Признак группы — Основной населенный пункт |
Territory | Признак группы — район |
Locality | Признак группы — населенный пункт подчиненный основному |
MotorRoad | Признак группы — автомобильная дорога |
RailWayObject | Признак группы — железная дорога |
VillageCouncil | Признак группы — сельсовет |
Street | Признак группы — улица в населенном пункте |
AddlTerritory | Признак группы — дополнительная территория |
PartAddlTerritory | Признак группы — часть дополнительной территории |
Список значений, возвращаемых функцией fsfn_AddressObjects_ObjectGroup, приведен в Таблица 5.
Цель создания этой функции в том чтобы собрать в одном месте все особенности (если хотите, то «костыли») определения группы элемента. С детальной реализацией этой функции можно ознакомиться в разделе Приложения «Создание функции fsfn_AddressObjects_ObjectGroup».
Комбинация значений функции и поля AOLevel (уровень адресообразующего элемента) вместе с проверкой на присутствие маски группы массиве масок позволяет определять должно ли название текущего элемента включаться в строку результата.
Например, признаком того, что название основного населенного пункта должно включаться в полное наименование элемента, является истинность следующего выражения:
v_ObjectGroup='City' AND '{LM}' <@ a_MaskArray AND v_AOLevel =4
ПРИЛОЖЕНИЕ
Создание функции fsfn_AddressObjects_ObjectGroup
BEGIN TRANSACTION;
DROP FUNCTION IF EXISTS fsfn_AddressObjects_ObjectGroup(a_AOGUID VARCHAR(36),a_CurrStatus INTEGER);
/*****************************************************************************/
/* Возвращает признак группы адресообразующего элемента по его идентификатору */
/* fias_AddressObjects */
/*****************************************************************************/
CREATE OR REPLACE FUNCTION fsfn_AddressObjects_ObjectGroup(
a_AOGUID VARCHAR(36), /* Глобальный уникальный идентификатор */
/* адресообразующего элемента*/
a_CurrStatus INTEGER default NULL /* Статус актуальности КЛАДР 4: */
/* 0 - актуальный, */
/* 1-50 - исторический, */
/* т.е. элемент был переименован, */
/* в данной записи приведено одно */
/* из прежних его наименований, */
/* 51 - переподчиненный */
)
RETURNS VARCHAR(50) /* Группа адресообразующего элемента */
AS
$BODY$
DECLARE
c_CountryGroupValue CONSTANT VARCHAR(50):='Country';
c_RegionGroupValue CONSTANT VARCHAR(50):='Region';
c_CityGroupValue CONSTANT VARCHAR(50):='City';
c_TerritoryGroupValue CONSTANT VARCHAR(50):='Territory';
c_LocalityGroupValue CONSTANT VARCHAR(50):='Locality';
c_MotorRoadValue CONSTANT VARCHAR(50):='MotorRoad';
c_RailWayObjectValue CONSTANT VARCHAR(50):='RailWayObject';
c_VillageCouncilValue CONSTANT VARCHAR(50):='VillageCouncil';
c_StreetGroupValue CONSTANT VARCHAR(50):='Street';
c_AddlTerritoryValue CONSTANT VARCHAR(50):='AddlTerritory';
c_PartAddlTerritoryValue CONSTANT VARCHAR(50):='PartAddlTerritory';
v_ShortTypeName VARCHAR(10); /* Тип адресообразующего элемента */
v_AddressObjectName VARCHAR(100); /* Название адресообразующего элемента */
v_AOLevel INTEGER; /* Уровень адресообразующего элемента*/
v_CurrStatus INTEGER; /* Текущий статус адресообразующего элемента*/
v_ObjectGroup VARCHAR(50); /* Группа адресообразующего элемента */
v_Return_Error Integer :=0; /* Код возврата */
--**************************************************************************
--**************************************************************************
BEGIN
SELECT INTO v_CurrStatus COALESCE(a_CurrStatus,MIN(addrobj.currstatus))
FROM fias_AddressObjects addrobj WHERE addrobj.AOGUID=a_AOGUID;
SELECT INTO v_ShortTypeName,v_AddressObjectName,v_AOLevel
ShortName,FormalName,AOLevel
FROM fias_AddressObjects addrobj
WHERE addrobj.AOGUID=a_AOGUID AND addrobj.currstatus = v_CurrStatus
LIMIT 1;
IF v_AOLevel = 1 AND UPPER(v_ShortTypeName) <> 'Г' THEN /* уровень региона */
v_ObjectGroup:=c_RegionGroupValue;
ELSIF v_AOLevel = 1 AND UPPER(v_ShortTypeName) = 'Г' THEN /* уровень города */
/* как региона */
v_ObjectGroup:=c_CityGroupValue;
ELSIF v_AOLevel = 3 THEN /* уровень района */
v_ObjectGroup:=c_TerritoryGroupValue;
ELSIF (v_AOLevel = 4 AND UPPER(v_ShortTypeName) NOT IN ('С/С','С/А','С/О','С/МО'))
OR (v_AOLevel = 1 AND UPPER(v_ShortTypeName) <> 'Г') THEN /* уровень города */
v_ObjectGroup:=c_CityGroupValue;
ELSIF v_AOLevel IN (4,6) AND UPPER(v_ShortTypeName) IN ('С/С','С/А','С/О','С/МО')
AND UPPER(v_ShortTypeName) NOT LIKE ('Ж/Д%') THEN /* уровень сельсовета */
v_ObjectGroup:=c_VillageCouncilValue;
ELSIF v_AOLevel = 6 AND UPPER(v_ShortTypeName) NOT IN ('С/С','С/А','С/О','С/МО',
'САД','СНТ','ТЕР',
'АВТОДОРОГА',
'ПРОМЗОНА',
'ДП','МКР')
AND UPPER(v_ShortTypeName) NOT LIKE ('Ж/Д%') THEN /* уровень населенного */
/* пункта */
v_ObjectGroup:=c_LocalityGroupValue;
ELSIF UPPER(v_ShortTypeName) IN ('АВТОДОРОГА') THEN /* уровень */
/* автомобильной дороги */
v_ObjectGroup:=c_MotorRoadValue;
ELSIF v_AOLevel IN (6,7) AND UPPER(v_ShortTypeName) LIKE ('Ж/Д%') THEN
/* уровень элемент */
/* на железной дороге */
v_ObjectGroup:=c_RailWayObjectValue;
ELSIF v_AOLevel = 7 AND UPPER(v_ShortTypeName) NOT LIKE ('Ж/Д%')
AND UPPER(v_ShortTypeName) NOT IN ('УЧ-К','ГСК','ПЛ-КА','СНТ','ТЕР')
OR (v_AOLevel = 6 AND UPPER(v_ShortTypeName) IN ('МКР') ) THEN
/* уровень улицы */
v_ObjectGroup:=c_StreetGroupValue;
ELSIF v_AOLevel = 90 OR v_AOLevel = 6 AND UPPER(v_ShortTypeName) IN ('САД',
'СНТ','ТЕР','ПРОМЗОНА','ДП')
OR v_AOLevel = 7
AND UPPER(v_ShortTypeName) IN ('УЧ-К','ГСК','ПЛ-КА','СНТ','ТЕР') THEN
/* уровень дополнительных */
/* территорий */
v_ObjectGroup:=c_AddlTerritoryValue;
ELSIF v_AOLevel = 91 THEN /* уровень подчиненных дополнительным территориям */
/* объектов */
v_ObjectGroup:=c_PartAddlTerritoryValue;
END IF;
RETURN v_ObjectGroup;
END;
$BODY$
LANGUAGE plpgsql;
COMMENT ON FUNCTION fsfn_AddressObjects_ObjectGroup(a_AOGUID VARCHAR(36),
a_CurrStatus INTEGER)
IS 'Возвращает признак группы адресного объекта по его идентификатору в таблице fias_AddressObjects';
--ROLLBACK TRANSACTION;
COMMIT TRANSACTION;
SELECT fsfn_AddressObjects_ObjectGroup('719b789d-2476-430a-89cd-3fedc643d821',51);
SELECT fsfn_AddressObjects_ObjectGroup('db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1');
SELECT fsfn_AddressObjects_ObjectGroup('625497d3-22de-4390-b4b4-2febfbfc15ce');
SELECT fsfn_AddressObjects_ObjectGroup('39da6405-b3e6-4baf-b332-d47b73b4d5fb');
SELECT fsfn_AddressObjects_ObjectGroup('bfc1236d-b5d2-4734-a238-3b1e4830e963');
Создание функции fsfn_AddressObjects_TreeActualName
BEGIN TRANSACTION;
DROP FUNCTION IF EXISTS fsfn_AddressObjects_TreeActualName(a_AOGUID VARCHAR(36),a_MaskArray VARCHAR(2)[10]) CASCADE;
/*****************************************************************************/
/* Возвращает строку с полным названием адресообразующего элемента */
/*****************************************************************************/
CREATE OR REPLACE FUNCTION fsfn_AddressObjects_TreeActualName(
a_AOGUID VARCHAR(36) DEFAULT NULL, /* Идентификтор */
/* адресообразующего элемента */
a_MaskArray VARCHAR(2)[10] default '{TP,LM,LP,ST}' /* Массив масок, */
/* управляющий содержанием строки */
/* с адресом дома*/
)
RETURNS VARCHAR(1000) AS
$BODY$
DECLARE
c_CountryGroupValue CONSTANT VARCHAR(50):='Country'; /* Признак группы - Страна*/
c_RegionGroupValue CONSTANT VARCHAR(50):='Region'; /* Признак группы - Регион*/
c_CityGroupValue CONSTANT VARCHAR(50):='City'; /* Признак группы - Основной */
/* населенный пункт*/
c_TerritoryGroupValue CONSTANT VARCHAR(50):='Territory';/* Признак группы - район */
c_LocalityGroupValue CONSTANT VARCHAR(50):='Locality';/* Признак группы - */
/* населенный пункт, */
/* подчиненный основному */
c_MotorRoadValue CONSTANT VARCHAR(50):='MotorRoad';/* Признак группы - */
/* автомобильная дорога */
c_RailWayObjectValue CONSTANT VARCHAR(50):='RailWayObject';/* Признак группы - */
/* железная дорога */
c_VillageCouncilValue CONSTANT VARCHAR(50):='VillageCouncil';
/* Признак группы - сельсовет */
c_StreetGroupValue CONSTANT VARCHAR(50):='Street';
/* Признак группы - */
/* улица в населенном пункте */
c_AddlTerritoryValue CONSTANT VARCHAR(50):='AddlTerritory';/* Признак группы - */
/* дополнительная территория*/
c_PartAddlTerritoryValue CONSTANT VARCHAR(50):='PartAddlTerritory';/* Признак группы */
/* - часть дополнительной территории*/
c_StreetMask CONSTANT VARCHAR(2)[1] :='{ST}';/* Маска улица */
c_PostIndexMask CONSTANT VARCHAR(2)[1] :='{ZC}';/* Маска почтовый индекс */
c_DistrictMask CONSTANT VARCHAR(2)[1] :='{DT}';/* Маска городской район*/
c_PartLocalityMask CONSTANT VARCHAR(2)[1] :='{LP}';/* Маска подчиненный */
/* населенный пункт*/
c_MainLocalityMask CONSTANT VARCHAR(2)[1] :='{LM}';/* Маска основной */
/* населенный пункт*/
c_PartTerritoryMask CONSTANT VARCHAR(2)[1] :='{TP}';/* Маска района */
/* субъекта федерации*/
c_MainTerritoryMask CONSTANT VARCHAR(2)[1] :='{TM}';/* Маска субъект федерации */
/* (регион)*/
c_CountryMask CONSTANT VARCHAR(2)[1] :='{CY}';/* Маска страна*/
v_ShortTypeName VARCHAR(10); /* Тип адресообразующего элемента */
v_AddressObjectName VARCHAR(100); /* Название адресообразующего элемента */
v_AOLevel INTEGER; /* Уровень адресообразующего элемента*/
v_MinCurrStatus INTEGER; /* Минимальное значение текущего статуса */
/* адресообразующего элемента*/
v_TreeAddressObjectName VARCHAR(1000); /* Полное в иерархии название элемента*/
v_ObjectGroup VARCHAR(50); /* Группа адресообразующего элемента */
v_TreeLeverCount INTEGER; /* Счетчик цикла*/
v_Return_Error_i Integer := 0; /* Код возврата*/
cursor_AddressObjectTree RefCURSOR; /* курсор по иерархии адреса*/
v_Return_Error Integer :=0; /* Код возврата */
--******************************************************************************
--******************************************************************************
BEGIN
SELECT INTO v_MinCurrStatus MIN(addrobj.currstatus)
FROM fias_AddressObjects addrobj
WHERE aoguid=a_AOGUID;
OPEN cursor_AddressObjectTree FOR SELECT rtf_ShortTypeName,
REPLACE(rtf_AddressObjectName,' ',' '),
rtf_AOLevel,fsfn_AddressObjects_ObjectGroup(rtf_AOGUID )
FROM fstf_AddressObjects_AddressObjectTree(a_AOGUID)
ORDER BY rtf_AOLevel;
v_TreeLeverCount:=0;
v_TreeAddressObjectName:='';
FETCH FIRST FROM cursor_AddressObjectTree INTO v_ShortTypeName,v_AddressObjectName,
v_AOLevel,v_ObjectGroup;
WHILE FOUND
LOOP
v_TreeLeverCount:=v_TreeLeverCount+1;
IF v_ObjectGroup=c_CountryGroupValue AND c_CountryMask <@ a_MaskArray
AND v_AOLevel =0 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
v_AddressObjectName||' '||v_ShortTypeName;
ELSIF v_ObjectGroup=c_RegionGroupValue
AND c_MainTerritoryMask <@ a_MaskArray
AND v_AOLevel <=2 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
CASE WHEN UPPER(v_ShortTypeName) LIKE
UPPER('%Респ%') THEN 'Республика ' ||
v_AddressObjectName ELSE v_AddressObjectName||
' '||v_ShortTypeName END;
ELSIF v_ObjectGroup=c_TerritoryGroupValue
AND c_PartTerritoryMask <@ a_MaskArray
AND v_AOLevel =3 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
v_AddressObjectName||' '||v_ShortTypeName;
ELSIF v_ObjectGroup=c_CityGroupValue
AND c_MainLocalityMask <@ a_MaskArray AND v_AOLevel =4 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
CASE WHEN UPPER(LEFT(v_AddressObjectName,6+
LENGTH(v_ShortTypeName)))='ЗАТО '||
UPPER(TRIM(v_ShortTypeName))||'.' THEN
v_AddressObjectName
ELSE v_ShortTypeName ||' '|| v_AddressObjectName END;
ELSIF v_ObjectGroup=c_LocalityGroupValue
AND c_DistrictMask <@ a_MaskArray AND v_AOLevel =5 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
v_AddressObjectName||' '||v_ShortTypeName ;
ELSIF v_ObjectGroup=c_LocalityGroupValue
AND c_PartLocalityMask <@ a_MaskArray
AND v_AOLevel =6 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
v_ShortTypeName ||' '|| v_AddressObjectName;
ELSIF v_ObjectGroup=c_StreetGroupValue
AND c_StreetMask <@ a_MaskArray
AND v_AOLevel =7 THEN
v_TreeAddressObjectName:=v_TreeAddressObjectName||
CASE WHEN v_TreeAddressObjectName='' THEN ''
ELSE ', ' END ||
v_ShortTypeName ||' '|| v_AddressObjectName;
END IF;
FETCH NEXT FROM cursor_AddressObjectTree INTO v_ShortTypeName,
v_AddressObjectName,
v_AOLevel,v_ObjectGroup;
END LOOP;
CLOSE cursor_AddressObjectTree;
RETURN v_TreeAddressObjectName;
END;
$BODY$
LANGUAGE plpgsql ;
COMMENT ON FUNCTION fsfn_AddressObjects_TreeActualName(a_AOGUID VARCHAR(36),
a_MaskArray VARCHAR(2)[10])
IS 'Возвращает строку с полным названием адресообразующего элемента';
--ROLLBACK TRANSACTION;
COMMIT TRANSACTION;
SELECT fsfn_AddressObjects_TreeActualName('bfc1236d-b5d2-4734-a238-3b1e4830e963','{TM,TP,LM,LP,ST}');
SELECT fsfn_AddressObjects_TreeActualName('bfc1236d-b5d2-4734-a238-3b1e4830e963');
Спасибо за внимание!
Поделиться с друзьями
Комментарии (8)
heleo
01.12.2016 16:15Я смотрю у Вас в правилах создание объектов бд с использованием begin\commit блоков. При генерации таблиц так же пользуетесь транзакцией или всяческие constraint внутрь create table (..) вместо alter table…?
gladkovs
01.12.2016 17:00Да, при создании таблиц я особенно часто использую транзакции. Сначала begin\rollback, а когда уверен, что ничего не забыл, использую begin\commit блоков.
kxl
Я для своих проектов сделал базу на основе КЛАДР версии ФИАС. Получилось, как мне кажется, намного проще. Всего две таблицы — Socrs и AddressElements. Первая повторяет исходную в КЛАДР, а вторая:
gladkovs
Ваш вопрос требует развернутого ответа. Я, обязательно, отвечу Вам завтра на свежую голову.
gladkovs
Степень простоты или сложности решения оценивается в зависимости от задачи. Я принимаю неявный упрек в том, что в публикации не описал решаемую задачу, а лишь ограничился тем, что использую структуру справочника ADDROBJ.DBF.
Задача состоит в том, чтобы по адресу, поступившему откуда-то извне (например, от заказчика), найти соответствующий адрес в справочнике ФИАС. При этом, внешний адрес может содержать устаревшие названия улиц и населенный пунктов. Как Вы знаете, переименование названий адресообразующих элементов не такое уж редкое явление.
Поэтому в структуре таблицы, созданной из справочника, были сохранены записи об истории переименования каждого элемента. Я надеялся, что смогу по устаревшему названию элемента находить актуальное. К сожалению, эта надежда не оправдалась. Как написано в первой части статьи лишь в 6,8% от числа элементов, имеющих записи об истории переименования, присутствуют различия в названиях одного и того же элемента. Да и в этих случаях, речь идет скорее об исправлении ошибок, чем об истории переименования адресообразующих элементов. Поэтому, мне не удалось использовать ФИАС, как базовый справочник для решения поставленной задачи. Сейчас он используется как один из источников данных для моего внутреннего справочника адресов.
Подробнее проблемы связанные и использованием адресов ФИАС изложены: .
Описанная задача решается как часть основной задачи – задачи геопривязки, т.е. по предоставленному извне адресу найти объект на карте. Но объектами на карте не обязательно являются дома в населенных пунктах. Такими объектами могут быть, например, дома в дачных или садовых товариществах, или здания цехов на территории промышленной зоны.
Вот как выглядят адреса таких и подобных мест:
«Республика Хакасия, г Абакан, пр-кт Дружбы Народов, дворовая территория домов 15 17 19 тер»
«Республика Хакасия, г Абакан, ул Пушкина, дворовая территория дома 21 тер»
Для идентификации таких мест код ФИАС расширен полями:
Смотри документ «Сведения о составе информации государственного адресного реестра федеральной информационной адресной системы» на сайте .
Не буду обманывать, задача геопривязки дополнительных территорий еще не решена, но она стоит в ближайших планах компании, в которой я работаю. Поэтому и эти поля я не убирал из структуры таблицы.
gladkovs
Извините. В ответе не отобразились ссылки на сайты. Документ который упоминается в ответе, можно найти запросу ФИАС (ФЕДЕРАЛЬНАЯ ИНФОРМАЦИОННАЯ АДРЕСНАЯ СИСТЕМА) на сайте налоговой службы.
Мое описание проблем с адресами ФИАС можно найти по названию публикации «Эх, ФИАС, ФИАС… Почему ты не адресный реестр?».
kxl
Я не думал упрекать. Структура ФИАС слишком замудрена. Кстати у меня тоже можно найти предыдущие наименования — они будут с другим кодом Actuality (также содержится в Code). Таблица для переименований мне не нужна, если, конечно, не придется искать реорганизованные пункты. Тогда можно будет и добавить её.
gladkovs
Я сам себя упрекаю…