2.1 トポロジ・データを編集する方法
-
PL/SQL APIを使用する場合、キャッシュを明示的に作成および使用するか、またはSpatialにキャッシュを自動的に作成および使用させることができます。
-
Java APIを使用する場合、キャッシュを明示的に作成および使用する必要があります。
Spatialにキャッシュを自動的に作成および管理させる方が、自分でキャッシュを作成および使用する場合より実行するステップが少ないため簡単です。ただし、Spatialにキャッシュを作成および管理させるとデータベース・アクティビティおよびディスク・アクセスが増加するため、多くの位相要素を編集する必要がある場合は非効率的です。
- TopoMapオブジェクト
- トポロジ・パラメータの編集方法の指定
- GET_xxxトポロジ・ファンクションの使用
- キャッシュを明示的に使用した編集処理(PL/SQL API)
- Java APIを使用した編集処理
- トポロジの編集のエラー処理
親トピック: トポロジの編集
2.1.1 TopoMapオブジェクト
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つのトポロジを編集できます。
親トピック: トポロジ・データを編集する方法
2.1.2 トポロジ・パラメータの編集方法の指定
トポロジを編集する多くの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);
親トピック: トポロジ・データを編集する方法
2.1.3 GET_xxxトポロジ・ファンクションの使用
トポロジの情報を取得する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オブジェクト(「SDO_EDGE_ARRAY型およびSDO_NUMBER_ARRAY型」を参照)が戻されます。
SELECT SDO_TOPO_MAP.GET_NODE_ADDITIONS FROM DUAL;
親トピック: トポロジ・データを編集する方法
2.1.4 キャッシュを明示的に使用した編集処理(PL/SQL API)
図2-1に、PL/SQL APIを使用し、TopoMapオブジェクトおよびそれに関連付けられたキャッシュを明示的に使用して位相要素を編集する処理の推奨手順を示します。
図2-1 TopoMapオブジェクトのキャッシュを使用したトポロジの編集(PL/SQL API)

図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.1.5 Java APIを使用した編集処理
図2-2に、クライアント側のJava APIを使用して位相要素を編集する処理の推奨手順を示します。Java APIの概要は、「トポロジ・データ・モデルのJavaインタフェース」および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を実行します。
親トピック: トポロジ・データを編集する方法
2.1.6 トポロジの編集のエラー処理
この項では、次の状況について説明します。
親トピック: トポロジ・データを編集する方法
2.1.6.1 入力パラメータのエラー
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
親トピック: トポロジの編集のエラー処理
2.1.6.2 すべての例外
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オブジェクトが読取り専用になります。
親トピック: トポロジの編集のエラー処理