PostgreSQLのFIASアドレス。 パート2

これは記事の2番目の部分であり、PostgreSQLの制御下でデータベースにロードされたFIASのアドレス生成要素のリストを操作した経験を示しています。 記事の最初の部分はここにあります











記事全体は4つのパートで構成されています。 この記事の前半では、関数の実装に関するコメントを提供しています。 第二に-関数のソースコード。 ソーステキストのみに興味がある読者のために、付録に直接進むことを提案します。



アドレス形成要素のフルネーム



fsfn_AddressObjects_TreeActualName関数の主なアイデアは、すべての祖先の名前とともに1行で接続された要素の名前を返すことです。 たとえば、家系図検索関数(fstf_AddressObjects_AddressObjectTree)が次の値のリストを返すようにします。



表5.関数fstf_AddressObjects_AddressObjectTreeの結果( 'bfc1236d-b5d2-4734-a238-3b1e4830e963')

AOGUID Currstatus ActStatus アオレベル ショートネーム 正式名称 オブジェクトグループ
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 0 1 1 エッジ クラスノヤルスク 地域
625497d3-22de-4390-b4b4-2febfbfc15ce 0 1 3 地区 バラクチンスキー テリトリー
39da6405-b3e6-4baf-b332-d47b73b4d5fb 0 1 6 n マイティ 局所性
bfc1236d-b5d2-4734-a238-3b1e4830e963 0 1 7 st 新しい 通り


次に、fsfn_AddressObjects_TreeActualName( 'bfc1236d-b5d2-4734-a238-3b1e4830e963')が返されます:



「クラスノヤルスク準州、バラクチンスキー地区、p。モグチー、ノバヤ通り」



この関数には、マスクの別のオプションのパラメーター配列(a_MaskArray)があり、これを使用して、要素のすべての名前ではなく、必要な名前のみを結果に含めることができます。



関数のテキストは、アプリケーションセクション「fsfn_AddressObjects_TreeActualName関数の作成」に記載されています。



仕組み



この関数の実装の基礎は、fstf_AddressObjects_AddressObjectTreeの呼び出し(記事の最初の部分で説明)とそれに返されるレコードのループです。このループでは、すべての名前を1行に連結することでアドレス形成要素のフルネームが形成されます。 この文字列は、最終的にfsfn_AddressObjects_TreeActualName関数によって返されます。



詳細は以下で説明します。



まず、関数の結果に、現在の要素のすべての祖先の名前を必ずしも含める必要がない場合があります。 たとえば、クラスノヤルスク地域では、「クラスノヤルスク地域、バラクチンスキー地区、モグチィ、ノバヤ通り」の代わりに、短縮形の「バラクチンスキー地区、モグチイ、ノバヤ通り」がより頻繁に使用されます。 また、クラスノヤルスク市では、「クラスノヤルスク地域、クラスノヤルスク、ペシャンカ、セルゲイラソ通り」という住所の代わりに、「ペシャンカ、セルゲイラゾ通り」をよく使用します。



アドレス形成要素のフルネームを書き込むさまざまな形式を管理できるようにするために、要素のグループへの一連のポインター(マスク)を含むマスクのパラメーター配列(a_MaskArray)が導入されています。



表6.関数マスクのリスト

価値 ご注意
{ST} マスク-通り
{ZC} マスク-郵便番号
{DT} マスク-都市部
{LP} マスク-部下の町
{LM} マスク-メイン決済
{TP} マスク-連合の主題の領域
{TM} マスク-連合の主題(地域)
{CY} マスク-国


次に、マスクの配列に従って完全な名前の構築を実装するために、各アドレス形成要素を特定のグループに関連付ける補助関数fsfn_AddressObjects_ObjectGroupが作成されました。



表7. fsfn_AddressObjects_ObjectGroupによって返される値

価値 ご注意
グループタグ-国
地域 グループタグ-地域
市区町村 グループ機能-一次決済
テリトリー グループタグ-地区
局所性 グループのサインは、メインに従属する決済です
モーター負荷 グループサイン-道路
RailWayObject グループのサインは鉄道です
村議会 グループのサインは村議会です
通り グループのサインは、村の通りです
AddlTerritory グループタグ-追加地域
PartAddlTerritory グループタグ-追加地域の一部


fsfn_AddressObjects_ObjectGroupによって返される値のリストを表5に示します。



この関数を作成する目的は、要素グループの定義のすべての機能(必要に応じて、「クランチ」)を1か所に収集することです。 この関数の詳細な実装については、アプリケーションセクション「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');
      
      







ご清聴ありがとうございました!



All Articles