この章では、トポロジ内のノードおよびエッジのデータを編集する方法について説明します。編集操作には、ノードとエッジの追加、移動および削除と、エッジの座標の更新が含まれます。
この章では、トポロジ・データを編集する2つの方法について説明し、そのうちの一方の方法(特殊なキャッシュを作成して使用する方法)が、ほとんどの場合にもう一方の方法より適している理由を説明します。また、主な編集操作の実行結果および影響についても説明します。この章の内容は次のとおりです。
この章では、主にMDSYS.SDO_TOPO_MAPパッケージに含まれるPL/SQL Application Program Interface (API) (第4章を参照)について説明します。ただし、クライアント側のJava APIを使用してトポロジの編集操作を実行することもできます。Java APIの概要は、1.8.2項およびJavadoc生成のドキュメントを参照してください。
トポロジ・データを編集するには、常にPL/SQL APIまたはJava APIを使用します。ノード、エッジまたはフェイスの情報表を直接変更して編集操作を実行しないでください。
複数のスキーマが関係している場合のトポロジの編集上の注意事項は、1.10.2項を参照してください。
トポロジを編集する必要がある場合は、PL/SQL APIまたはJava APIを使用します。いずれの場合も、Oracle Spatialではメモリー内のトポロジ・キャッシュ(具体的にはTopoMapオブジェクト(2.1.1項を参照))が使用されます。
PL/SQL APIを使用する場合、キャッシュを明示的に作成および使用するか、またはSpatialにキャッシュを自動的に作成および使用させることができます。
Java APIを使用する場合、キャッシュを明示的に作成および使用する必要があります。
Spatialにキャッシュを自動的に作成および管理させる方が、自分でキャッシュを作成および使用する場合より実行する手順が少ないため簡単です。ただし、Spatialにキャッシュを作成および管理させるとデータベース・アクティビティおよびディスク・アクセスが増加するため、多くの位相要素を編集する必要がある場合は非効率的です。
TopoMapオブジェクトは、トポロジに関連付けられたメモリー内キャッシュに関連付けられます。キャッシュを明示的に作成および使用してトポロジを編集する場合、トポロジに関連付けるTopoMapオブジェクトを作成し、そのトポロジのすべてまたは一部をキャッシュにロードし、オブジェクトを編集し、定期的にトポロジを更新してデータベースに変更を書き込み、キャッシュ内の変更をコミットしてキャッシュをクリアする必要があります。
この方法では、Spatialにキャッシュを自動的に作成および使用させる場合より多くの手順が必要ですが、一般的に数百または数千の位相要素に影響を及ぼすほとんどのトポロジ編集セッションでは、処理速度および効率が大幅に向上します。ほとんどの説明および図では、この方法を使用しています。
SDO_TOPO_MAP.LOAD_TOPO_MAPファンクションまたはプロシージャのコール時のallow_updates
パラメータの値によって、TopoMapオブジェクトを更新可能または読取り専用に指定できます。
読取り専用のTopoMapオブジェクトを使用すると、位相要素(プリミティブ)はロードされますが、ロックされません。
更新可能なTopoMapオブジェクトを使用すると、位相要素(プリミティブ)はロードされてからロックされます。更新可能なTopoMapオブジェクトの矩形ウィンドウを指定した場合は、指定したウィンドウ内にある位相要素のみを編集できます。(TopoMapオブジェクトには、ユーザーが直接編集できないロックされた位相要素が含まれる場合もありますが、必要に応じてOracle Spatialによって間接的に変更できます。)
更新可能なTopoMapオブジェクトの使用時に発生する事柄の詳細は、SDO_TOPO_MAP.LOAD_TOPO_MAPファンクションまたはプロシージャの「使用上の注意」を参照してください。
次のプロシージャによって、更新可能なTopoMapオブジェクトが読取り専用に設定されます。
1回のユーザー・セッションに存在できる更新可能なTopoMapオブジェクトは常に1つのみです。ただし、複数の異なるユーザー・セッションで、同じトポロジに基づいた複数の更新可能なTopoMapオブジェクトを使用することはできます。これには、編集ウィンドウに、他の更新可能なTopoMapオブジェクト内にある位相要素が含まれていないことが条件となります。読取り専用のTopoMapオブジェクトは、複数のユーザー・セッション内およびユーザー・セッション間で複数設定できます。
編集ウィンドウ(SDO_TOPO_MAP.LOAD_TOPO_MAPファンクションまたはプロシージャのコール時に指定)が重ならないかぎり、複数のユーザーが同時に1つのトポロジを編集できます。
トポロジを編集する多くのSDO_TOPO_MAPパッケージ・ファンクションおよびプロシージャ(SDO_TOPO_MAP.ADD_NODE、SDO_TOPO_MAP.MOVE_EDGEなど)では、トポロジ名またはNULL値のいずれかを最初のパラメータtopology
に指定して、編集方法を指定します。
トポロジ名を指定した場合、Spatialによってユーザー・セッションに更新可能なTopoMapオブジェクトが存在するかどうかが確認され、更新可能なTopoMapオブジェクトが存在しない場合、Spatialは内部TopoMapオブジェクトを作成し、そのキャッシュを使用して編集操作を実行し、変更をコミットして(または、例外が発生した場合は、処理の開始時点のセーブポイントまで変更をロールバックして)TopoMapオブジェクトを削除します。(更新可能なTopoMapオブジェクトがすでに存在する場合、例外が発生します。)たとえば、次の文ではMY_TOPO
トポロジから、ノードID値が99のノードが削除されます。
CALL SDO_TOPO_MAP.REMOVE_NODE('MY_TOPO', 99);
NULL値を指定した場合、Spatialによってユーザー・セッションに更新可能なTopoMapオブジェクトが存在するかどうかが確認され、更新可能なTopoMapオブジェクトが存在する場合、SpatialはTopoMapオブジェクトのキャッシュで操作を実行します。(更新可能なTopoMapオブジェクトが存在しない場合、例外が発生します。)たとえば、次の文では、現行の更新可能なTopoMapオブジェクトから、ノードID値が99のノードが削除されます。
CALL SDO_TOPO_MAP.REMOVE_NODE(null, 99);
トポロジの情報を取得するSDO_TOPO_MAPパッケージ・ファンクションには、最初の2つのパラメータとしてtopology
およびtopo_map
を取るものがあります。このようなファンクションには、SDO_TOPO_MAP.GET_EDGE_COORDS、SDO_TOPO_MAP.GET_NODE_STARなどがあります。これらのファンクションを使用するには、次のように一方のパラメータに有効な値を指定し、もう一方のパラメータにNULL値を指定します。
topology
パラメータに有効な値を指定した場合、Spatialによって指定したトポロジの情報が取得されます。Spatialは内部TopoMapオブジェクトを作成し、そのキャッシュを使用して操作を実行し、TopoMapオブジェクトを削除します。たとえば、次の文では、CITY_DATA
トポロジから、ID値が1のエッジのエッジ座標が戻されます。
SELECT SDO_TOPO_MAP.GET_EDGE_COORDS('CITY_DATA', null, 1) FROM DUAL;
topology
パラメータにNULL値を指定し、topo_map
パラメータに有効な値を指定した場合、Spatialによって指定したTopoMapオブジェクト(更新可能または読取り専用のいずれか)が使用され、指定したトポロジの情報が取得されます。たとえば、次の文では、CITY_DATA_TOPOMAP
TopoMapオブジェクトから、ID値が1のエッジのエッジ座標が戻されます。
SELECT SDO_TOPO_MAP.GET_EDGE_COORDS(null, 'CITY_DATA_TOPOMAP', 1) FROM DUAL;
topology
とtopo_map
の両方のパラメータにNULLまたは無効な値を指定した場合、例外が発生します。
トポロジの編集操作の情報を取得するSDO_TOPO_MAPパッケージ・ファンクションには、パラメータを取らないものがあります。このようなファンクションには、SDO_TOPO_MAP.GET_FACE_ADDITIONS、SDO_TOPO_MAP.GET_NODE_CHANGESなどがあります。これらのファンクションでは、現行の更新可能なTopoMapオブジェクトが使用されます。更新可能なTopoMapオブジェクトが存在しない場合、例外が発生します。たとえば、次の文では、現行の更新可能なTopoMapオブジェクトに追加されたノードのノードID値を持つSDO_NUMBER_ARRAYオブジェクト(1.6.7項を参照)が戻されます。
SELECT SDO_TOPO_MAP.GET_NODE_ADDITIONS FROM DUAL;
図2-1に、PL/SQL APIを使用し、TopoMapオブジェクトおよびそれに関連付けられたキャッシュを明示的に使用して位相要素を編集する処理の推奨手順を示します。
図2-1 TopoMapオブジェクトのキャッシュを使用したトポロジの編集(PL/SQL API)
図2-1に示した基本的な手順は次のとおりです。
SDO_TOPO_MAP.CREATE_TOPO_MAPプロシージャを使用してTopoMapオブジェクトを作成します。
これによって、指定したトポロジに関連付けられたオブジェクトを編集するためのメモリー内キャッシュが作成されます。
SDO_TOPO_MAP.LOAD_TOPO_MAPファンクションまたはプロシージャを使用して、トポロジ全体または矩形ウィンドウを、トポロジからTopoMapオブジェクトのキャッシュに更新用としてロードします。
メモリー内Rツリー索引が、ロードするエッジおよびフェイスに作成されるように指定できます。これらの索引ではメモリー・リソースがいくらか消費され、索引の作成および定期的な再作成に時間がかかりますが、セッションで多くの位相要素を編集する場合は、これらの索引によってパフォーマンスが大幅に向上します。(また、読取り専用のTopoMapオブジェクトを使用する問合せのパフォーマンスも向上します。)
様々なトポロジの編集操作(たとえば、1000個のノードの追加)を実行します。
定期的にSDO_TOPO_MAP.VALIDATE_TOPO_MAPファンクションをコールして、キャッシュを検証します。
SDO_TOPO_MAP.CREATE_EDGE_INDEXおよびSDO_TOPO_MAP.CREATE_FACE_INDEXプロシージャを使用して、TopoMapオブジェクト内のエッジおよびフェイスの既存のメモリー内Rツリー索引を再作成できます。また、索引が存在しない場合は、新しい索引を作成できます。索引のパフォーマンスを最適化するには、位相要素を数多く編集したときに、これらの索引を定期的に再作成する必要があります。
キャッシュ内の編集を廃棄する場合は、SDO_TOPO_MAP.CLEAR_TOPO_MAPプロシージャをコールします。コミットしていない更新がある場合は、このプロシージャは失敗します。コミットされていない更新が存在しない場合は、このプロシージャによってキャッシュ内のデータが消去され、キャッシュが読取り専用に設定されます。
SDO_TOPO_MAP.UPDATE_TOPO_MAPプロシージャをコールして、トポロジを更新します。
トポロジの編集操作が終了するまで、必要に応じて手順3および4(オブジェクトの編集、キャッシュの検証、Rツリー索引の再作成およびトポロジの更新)を繰り返します。
SDO_TOPO_MAP.COMMIT_TOPO_MAPプロシージャをコールして、トポロジの変更をコミットします。(SDO_TOPO_MAP.COMMIT_TOPO_MAPプロシージャによって、変更のコミット前に、SDO_TOPO_MAP.UPDATE_TOPO_MAPプロシージャの操作が自動的に実行されます。)コミット操作後、キャッシュは読取り専用(更新不可)になります。ただし、同じTopoMapオブジェクトを使用して追加の編集操作を実行する場合、そのオブジェクトを再びロードして使用できます(必要に応じてキャッシュをクリアしてから、手順2から5を繰り返します)。
追加の編集操作を実行するには、SDO_TOPO_MAP.CLEAR_TOPO_MAPプロシージャをコールしてTopoMapオブジェクトのキャッシュをクリアして、手順2に戻ります。
SDO_TOPO_MAP.ROLLBACK_TOPO_MAPプロシージャをコールすると、コミットされていないすべてのトポロジの変更をいつでも廃棄できます。ロールバック操作後、キャッシュがクリアされます。
SDO_TOPO_MAP.DROP_TOPO_MAPプロシージャをコールして、TopoMapオブジェクトを削除します。
このプロシージャによって、TopoMapオブジェクトが削除され、そのオブジェクトが使用していたすべてのリソースが解放されます。(TopoMapオブジェクトを削除しなかった場合、ユーザー・セッションの終了時にそのオブジェクトが自動的に削除されます。)また、コミットされていないキャッシュ内のトポロジの変更がロールバックされます。
アプリケーションが異常終了した場合、データベースにコミットされていないすべての変更は廃棄されます。
非常に多くのトポロジの編集操作を実行する予定の場合、それらの操作を複数の編集セッションに分割できます。各セッションで、前述の手順1から7を実行します。
図2-2に、クライアント側のJava APIを使用して位相要素を編集する処理の推奨手順を示します。Java APIの概要は、1.8.2項およびJavadoc生成のドキュメントを参照してください。Java APIでは、TopoMapオブジェクトとそれに関連付けられたキャッシュを作成および管理する必要があります。
図2-2に示した基本的な手順は次のとおりです。
TopoMap
クラスのコンストラクタを使用してトポロジとデータベースの接続を指定し、TopoMapオブジェクトを作成します。
これによって、指定したトポロジに関連付けられたオブジェクトを編集するためのメモリー内キャッシュが作成されます。
TopoMap
クラスのloadTopology
またはloadWindow
メソッドを使用して、トポロジ全体または矩形ウィンドウを、トポロジからTopoMapオブジェクトのキャッシュに更新用にロードします。
メモリー内Rツリー索引が、影響を受けるエッジおよびエッジのフェイスに作成されるように指定できます。これらの索引ではメモリー・リソースがいくらか消費され、索引の作成および定期的な再作成に時間がかかりますが、データベース接続中に多くの位相要素を編集する場合は、これらの索引によってパフォーマンスが大幅に向上します。
様々なトポロジの編集操作(たとえば、1000個のノードの追加)を実行し、TopoMap
クラスのupdateTopology
メソッドをコールしてトポロジを更新します。
定期的にTopoMap
クラスのvalidateCache
メソッドをコールして、キャッシュを検証します。
TopoMapオブジェクトのロード時(手順2)にメモリー内Rツリー索引を作成した場合、TopoMap
クラスのcreateEdgeIndex
およびcreateFaceIndex
メソッドをコールして、索引を定期的に(たとえば、100個のノードを追加するたびに)再作成できます。索引のパフォーマンスを最適化するには、位相要素を数多く編集したときに、これらの索引を定期的に再作成する必要があります。
トポロジを更新せずに、最終更新以降に実行したキャッシュ内の編集操作を廃棄する場合、TopoMap
クラスのclearCache
メソッドをコールします。コミットしていない更新がある場合は、clearCache
メソッドは失敗します。コミットされていない更新が存在しない場合は、このメソッドによってキャッシュ内のデータが消去され、キャッシュが読取り専用に設定されます。
TopoMap
クラスのupdateTopology
メソッドをコールして、トポロジを更新します。
トポロジの編集操作が終了するまで、必要に応じて手順3および4(オブジェクトの編集、キャッシュの検証、Rツリー索引の再作成およびトポロジの更新)を繰り返します。
TopoMap
クラスのcommitDB
メソッドをコールして、トポロジの変更をコミットします。(commitDB
メソッドによって、変更のコミット前に、updateTopology
メソッドが自動的にコールされます。)コミット操作後、キャッシュは読取り専用(更新不可)になります。ただし、同じTopoMapオブジェクトを使用して追加の編集操作を実行する場合、そのオブジェクトを再びロードして使用できます(必要に応じてキャッシュをクリアしてから、手順2から5を繰り返します)。
追加の編集操作を実行するには、TopoMap
クラスのclearCache
メソッドをコールしてTopoMapオブジェクトのキャッシュをクリアして、手順2に戻ります。
TopoMap
クラスのrollbackDB
メソッドをコールすると、コミットされていないすべてのトポロジの変更をいつでも廃棄できます。ロールバック操作後、キャッシュがクリアされます。
TopoMapオブジェクトをNULLに設定してTopoMapオブジェクトを削除します。これにより、そのオブジェクトに対してガベージ・コレクションが実行可能となり、そのオブジェクトが使用していたすべてのリソースが解放されます。(TopoMapオブジェクトを削除しなかった場合、アプリケーションの終了時にそのオブジェクトに対するガベージ・コレクションが自動的に実行されます。)
アプリケーションが異常終了した場合、データベースにコミットされていないすべての変更は廃棄されます。
非常に多くのトポロジの編集操作を実行する予定の場合、それらの操作を複数の編集セッションに分割できます。各セッションで、前述の手順1から7を実行します。
この項では、次の状況について説明します。
入力パラメータのエラー
すべての例外
PL/SQLサブプログラムSDO_TOPO_MAPまたはJavaクラスTopoMap
のパブリック・メソッドをコールすると、入力パラメータの値が検証され、TopoMapオブジェクトが使用または作成されて編集または読取り専用操作が実行されます。入力エラーがあった場合、oracle.spatial.topo.TopoDataException
例外がスローされます。基礎となるTopoMapオブジェクトで操作が実行される際に、別のエラーが発生する場合があります。
SQLまたはPL/SQLからメソッドをコールすると、次のエラー・メッセージが表示されます。
ORA-29532: Java call terminated by uncaught Java exception: <specific error message text>
次のPL/SQLの例では、TopoDataException
例外を処理する方法を示します。
DECLARE topo_data_error EXCEPTION; PRAGMA EXCEPTION_INIT(topo_data_error, -29532); BEGIN sdo_topo_map.create_topo_map(null, null, 100, 100, 100); EXCEPTION WHEN topo_data_error THEN DBMS_OUTPUT.PUT_LINE(SQLERRM); END;/
前述の例の出力を次に示します。
ORA-29532: Java call terminated by uncaught Java exception:oracle.spatial.topo.TopoDataException: invalid TopoMap name
PL/SQLサブプログラムSDO_TOPO_MAPまたはそれらに関連付けられたJavaクラスTopoMap
内のメソッド(SDO_TOPO_MAP.ADD_EDGE(addEdge
)、SDO_TOPO_MAP.ADD_ISOLATED_NODE(addIsolatedNode
)、SDO_TOPO_MAP.ADD_LOOP(addLoop
)、SDO_TOPO_MAP.ADD_NODE(addNode
)、SDO_TOPO_MAP.ADD_POINT_GEOMETRY(addPointGeometry
)、SDO_TOPO_MAP.ADD_POLYGON_GEOMETRY(addPolygonGeometry
)、SDO_TOPO_MAP.CHANGE_EDGE_COORDS(changeEdgeCoords
)、SDO_TOPO_MAP.MOVE_ISOLATED_NODE(moveIsolatedNode
)、SDO_TOPO_MAP.MOVE_NODE(moveNode
)、SDO_TOPO_MAP.MOVE_EDGE (moveEdge
)、SDO_TOPO_MAP.REMOVE_EDGE (removeEdge
)、SDO_TOPO_MAP.REMOVE_NODE (removeNode
)およびSDO_TOPO_MAP.UPDATE_TOPO_MAP(updateTopology
))のコール時に例外が発生すると、次の操作が自動的に実行されます。
トランザクションがロールバックされます。
TopoMapオブジェクトのキャッシュがクリアされます。
TopoMapオブジェクトが読取り専用になります。
この項では、ノードの追加、移動および削除の影響、およびPL/SQL APIを使用してこれらの操作を実行する方法について説明します。
連結ノードを追加すると、現在のエッジ上の点にノードが追加されます。また、この操作によって元のエッジが2つのエッジに分割されます。Spatialによって元のエッジの定義が自動的に調整され、新しいエッジが作成されます(新しいエッジに、トポロジ内のエッジで一意のID値が割り当てられます)。
連結ノードを追加するには、SDO_TOPO_MAP.ADD_NODEファンクションを使用します。孤立ノードを追加するには、SDO_TOPO_MAP.ADD_ISOLATED_NODEファンクションを使用します。
図2-3に、エッジE1へのノード(N3)の追加を示します。
図2-3に示す操作の結果は、次のとおりです。
エッジE1が、元のエッジの開始点とノード(N3)の追加点の間に再定義されます。
エッジE2が作成されます。開始点はノードN3の点で、終了点は元のエッジの終了点です。
元のエッジに線形フィーチャが定義されていた場合、線形フィーチャは結果として生成された両方のエッジに自動的に再定義され、エッジは分割され、トポロジの履歴情報表(1.5.5項を参照)に記録が追加されます。たとえば、図2-3の元のエッジE1に大通りという名前の通りが定義されていた場合、ノードN3の追加後、大通りがエッジE1とE2の両方に定義されます。
図2-4に、より複雑なノードの追加例を示します。この例では、追加されたノードが元のエッジの新しい形状点であるかどうか(つまり、SDO_TOPO_MAP.ADD_NODEファンクションのis_new_shape_point
パラメータの値)に応じて結果が異なります。
次に、図2-4について説明します。
1つ目の図では、元のエッジ(E1)がノードN1から開始してN2で終了し、中間に2つの形状点があります。
2つ目の図では、新しいノード(N3)が追加されていますが、このノードは元のエッジの形状点ではなく、新しい形状点です(つまり、is_new_shape_point=>'TRUE'
です)。新しいノードは、point
パラメータで指定した場所に追加され、coord_index
パラメータで指定した頂点より後(この場合、coord_index=>1
となるため最初の頂点の後)に追加されます。新しいノードは、エッジE1の終了ノード、および新しいエッジE2の開始ノードとなり、エッジE2はノードN2で終了します。
3つ目の図では、新しいノード(N3)が追加されていますが、このノードは元のエッジの形状点であるため、新しい形状点ではありません(つまり、is_new_shape_point=>'FALSE'
です)。追加されたノードが新しい形状点ではないため、ノードはcoord_index
パラメータ(この場合はcoord_index=>2
)で指定された頂点に追加されます。2つ目の図で示すように、新しいノードは、エッジE1の終了ノード、および新しいエッジE2の開始ノードとなり、エッジE2はノードN2で終了します。
連結ノードを新しい位置に移動すると、ノードに接するすべてのエッジの点が、ノードとともに移動します。ノードの移動によって影響を受けるすべてのエッジの頂点を指定する必要があります。移動したノードに接する各点(開始点または終了点)は、ノードの新しい位置と同じ座標を持つ必要があり、影響を受ける各エッジのもう一方の点(移動したノードではない点)は、変わらないままである必要があります。
連結ノードを移動するには、SDO_TOPO_MAP.MOVE_NODEプロシージャを使用します。孤立ノードを移動するには、SDO_TOPO_MAP.MOVE_ISOLATED_NODEプロシージャを使用します。
図2-5に、ノードN1を移動する前の元のトポロジを示します。
図2-6に、ノードN1を移動した後の元のトポロジの2つの状態を示します。一方では、リシェイプが実行されていません。つまり、移動の影響を受けるすべてのエッジが直線として指定されています。もう一方では、リシェイプが行われています。この場合、影響を受ける1つ以上のエッジが、複数の頂点のある線セグメントとして指定されています。
次に、図2-6に示す両方の状態について説明します。
トポロジは変更されません。つまり、ノード、エッジおよびフェイスの数およびそれらの関係(近接性、接続性など)は変更されません。
ノード、エッジおよびフェイスに定義されたすべてのフィーチャは、そのまま保持されます。
連結ノードの移動操作の結果、孤立ノードおよび孤立エッジは同じフェイス内に残るか、別のフェイスに移動します。SDO_TOPO_MAP.MOVE_NODEプロシージャには、moved_iso_nodes
およびmoved_iso_edges
の2つの出力パラメータがあります。これらのパラメータには、操作の結果として別のフェイスに移動した孤立ノードおよび孤立エッジのID番号が格納されます。
移動の結果として次のことが発生する場合は、ノードを移動できません。
ノードに接するエッジがその他のエッジと交差する。たとえば、図2-6に示す元のトポロジが、ノードN1のすぐ右上を通る別のエッジE20を含むとします。ノードN1の移動によってエッジE3、E4、E6、E8またはE9がエッジE20と交差する場合、その移動操作は実行されません。
現在隣接していないフェイスにノードが移動される。たとえば、図2-6に示す元のトポロジの外側にノードN1を移動する場合、その移動操作は実行されません。
孤立フェイスの反対側にノードが移動される。この移動では、フェイスの周りのエッジの関係または順序、および各エッジの左右のフェイスのうち、1つ以上のものが変更されるため、この移動は許可されません。図2-7に、許可されないノードの移動(孤立フェイスF1の反対側へのノードN1の反転)を示します。
この項では、許可または禁止されたノードの移動操作の他の例を示します。すべての例で、図2-8に示すトポロジを参照します。
次に、図2-8に示すトポロジについて説明します。
点P1、P2、P3およびP4へのノードN1の移動が試行されます。(これらの点は単なる位置であり、既存のノードではありません。)
移動操作の前後のいずれにも、エッジに形状点はありません。
新しい頂点がエッジE1、E2、E3およびE4に指定されますが、エッジの開始点および終了点のID値は同じままです。
図2-8に示すトポロジを使用した、ノードの移動操作の試行とその結果を次に示します。
ノードN1の点P1への移動: ノードN1に接する4つのエッジのうち1つ以上がエッジE5と交差するため、許可されません。(移動を実行すると、エッジE3がエッジE5と必ず交差します。)
ノードN1の点P2への移動: 許可されます。
ノードN1の点P3への移動: 許可されます。ただし、この操作によって孤立ノードN2がフェイスF2からフェイスF1に変更されるため、アプリケーションでノードN1の移動がロールバックされるか、または拒否される場合があります。同様に、ノードの移動によって孤立エッジまたは孤立フェイスが1つのフェイスから別のフェイスに変更される場合、アプリケーションでノードの移動操作がロールバックされるか、または拒否される場合があります。
ノードN1の点P4への移動: ノードは元の(現在の)位置と隣接するフェイス内の点に移動する必要があるため、許可されません。
個々のノード(孤立ノードまたは連結ノード)を削除することができます(この項を参照)。また、トポロジ内のすべての不要ノードも削除することができます(2.2.4項を参照)。
連結ノードを削除すると、そのノードが削除され、ノードに接していたエッジが1つのエッジにマージされます。(Spatialは、複雑な規則(このマニュアルでは説明していません)を適用して、結果として生成されるエッジのID値および方向を決定します。)
連結ノードまたは孤立ノードを削除するには、SDO_TOPO_MAP.REMOVE_NODEプロシージャを使用します。
図2-9に、エッジE1およびE2に接するノード(N1)の削除を示します。
図2-9に示す操作の結果は、次のとおりです。
エッジE1が、元のエッジE1およびE2を表していた線セグメントで構成されるように再定義されます。
エッジE2が削除されます。
両方の元のエッジに線形フィーチャが定義されていた場合、線形フィーチャは結果として生成されたエッジに自動的に再定義され、トポロジの履歴情報表(1.5.5項を参照)に記録が追加されます。たとえば、図2-9の元のエッジE1およびE2に大通りという名前の通りが定義されていた場合、ノードN1の削除後に大通りがエッジE1に定義されます。
次の1つ以上の条件に該当する場合、ノードは削除できません。
不要ノードとは、2つの個別のエッジのみに接続され、どの点フィーチャにも割り当てられておらず、異なる線形フィーチャ間の境界としても機能しないノードです。不要ノードは、トポロジを作成するためにSDO_TOPO_MAP.ADD_POLYGON_GEOMETRYファンクションを繰り返し使用した場合や、編集操作中にエッジが削除されて不要なノードが残された場合に発生します。そのため、このような場合には、SDO_TOPO_MAP.REMOVE_OBSOLETE_NODESプロシージャを使用して不要ノードを削除することをお薦めします。
Spatialは、<topology-name>_NODE$表と<topology-name>_EDGE$表、および必要に応じて<topology-name>_FACE$表の該当するエントリを自動的に更新します。
図2-10に、単純なトポロジ内の不要ノードの削除を示します。このトポロジでは、ノードN1に美術館という名前の点フィーチャが定義され、ノードN3には市庁舎という名前の点フィーチャが定義されています。エッジE1、E2およびE3には大通りという名前の線形フィーチャが定義され、エッジE4にはファースト・アベニューという名前の線形フィーチャが定義されています。
図2-10では、N2のみが不要ノードのすべての条件を満たしているため、このノードのみが削除されます。次に、他のノードについて説明します。
N1は1つのエッジ(E1)のみに接続されています。また、このノードには点フィーチャ(美術館)が定義されています。
N3には点フィーチャ(市庁舎)が定義されています。
N4は、2つの異なる線形フィーチャ(大通りとファースト・アベニュー)間の境界です。
N5は、1つのエッジ(E4)にのみ接続されています。
ノードN6は、孤立ノード(どのエッジにも接続されていないノード)です。
また、図2-10に示す操作の結果として、ノードN2を削除したためにエッジE2が削除されています。
この項では、エッジの追加、移動、削除および更新の影響と、PL/SQL APIを使用してこれらの操作を実行する方法について説明します。
連結エッジを追加すると、フェイスにエッジが追加されます。また、元のフェイスが2つのフェイスに分割されます。Spatialによって元のフェイスの定義が自動的に調整され、新しいフェイスが作成されます(新しいエッジに、トポロジ内のフェイスで一意のID値が割り当てられます)。
エッジを追加するには、SDO_TOPO_MAP.ADD_EDGEプロシージャを使用します。既存のノードを、追加したエッジの開始ノードおよび終了ノードに指定する必要があります。
図2-11に、フェイスF3のノードN3とN5の間へのエッジ(E7)の追加を示します。
図2-11に示す操作の結果として、フェイスF3が再定義され、F1およびF3の2つのフェイスになります。(Spatialは、複雑な規則(このマニュアルでは説明していません)を適用して、結果として生成されるフェイスのID値を決定します。)
元のフェイスに定義されていたポリゴン・フィーチャは、結果として生成された両方のフェイスに自動的に再定義されます。たとえば、図2-11の元のフェイスF3にウォールデン州立公園という名前の公園が定義されていた場合、エッジE7の追加後にウォールデン州立公園がフェイスF1とF3の両方に定義されます。
連結エッジを移動すると、エッジの開始点または終了点の一方は同じ位置に保持され、これらの2つの点のもう一方が、既存の別のノードの位置に移動されます。ソース・ノード(移動するノードの移動前の位置)、ターゲット・ノード(移動するノードの移動後の位置)および移動後のエッジの頂点を指定する必要があります。
エッジを移動するには、SDO_TOPO_MAP.MOVE_EDGEプロシージャを使用します。
図2-12に、元はノードN3とN5の間に存在したエッジE7の、ノードN2とN5の間への移動を示します。
図2-12に示す操作の結果として、フェイスF1およびF3が再定義され、それらのエッジの座標がエッジE7の新しい座標を含むように反映されます。
連結エッジの移動操作の結果、孤立ノードおよび孤立エッジは同じフェイス内に残るか、別のフェイスに移動します。SDO_TOPO_MAP.MOVE_EDGEプロシージャには、moved_iso_nodes
およびmoved_iso_edges
の2つの出力パラメータがあります。これらのパラメータには、操作の結果として別のフェイスに移動した孤立ノードおよび孤立エッジのID番号が格納されます。
移動の結果として次のことが発生する場合、エッジを移動できません。
連結エッジを削除すると、そのエッジが削除され、エッジに隣接していたフェイスがマージされます。(Spatialは、複雑な規則(このマニュアルでは説明していません)を適用して、結果として生成されるフェイスのID値を決定します。)
エッジを削除するには、SDO_TOPO_MAP.REMOVE_EDGEプロシージャを使用します。
図2-13に、フェイスF1およびF3と隣接するエッジ(E7)の削除を示します。
図2-13に示す操作の結果は、次のとおりです。
フェイスF1が、元のフェイスF1およびF3の領域で構成されるように再定義されます。
フェイスF3が削除されます。
削除されたエッジの開始ノードおよび終了ノード(ノードN3およびN5)は削除されません。
元のフェイスに定義されていたポリゴン・フィーチャは、結果として生成されたフェイスに自動的に再定義されます。たとえば、図2-13の元のフェイスF1およびF3にアダムス公園という名前の公園が定義されていた場合、エッジE7の削除後にアダムス公園がフェイスF1に定義されます。
次の1つ以上の条件に該当する場合、連結エッジは削除できません。
孤立エッジを更新すると、エッジの1つ以上の座標が変更されますが、開始点および終了点は変更されません。
エッジを更新するには、SDO_TOPO_MAP.CHANGE_EDGE_COORDSプロシージャを使用します。
連結エッジの更新操作の結果、孤立ノードおよび孤立エッジは同じフェイス内に残るか、別のフェイスに移動します。SDO_TOPO_MAP.CHANGE_EDGE_COORDSプロシージャには、moved_iso_nodes
およびmoved_iso_edges
の2つの出力パラメータがあります。これらのパラメータには、操作の結果として別のフェイスに移動した孤立ノードおよび孤立エッジのID番号が格納されます。
操作の結果としてエッジがその他のエッジと交差する場合、エッジは更新できません。エッジの更新の詳細は、SDO_TOPO_MAP.CHANGE_EDGE_COORDSプロシージャの「使用上の注意」を参照してください。