ヘッダーをスキップ
Oracle® Spatialトポロジおよびネットワーク・データ・モデル開発者ガイド
11gリリース2 (11.2)
B72088-04
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

5 ネットワーク・データ・モデルの概要

この章では、Oracle Spatialネットワーク・データ・モデルに関連する概念および操作について説明します。ユーザーは、『Oracle Spatial開発者ガイド』に記載されているOracle Spatialの主な概念、データ型および操作を理解しておく必要があります。

この章では、Oracle Spatialに関連するいくつかのネットワーク関連の用語について説明しますが、ユーザーがネットワーク・データ・モデリングの基本的な概念を十分に理解していると想定しています。

この章には、次の項が含まれます。

5.1 ネットワーク・モデリングの概要

多くのアプリケーションで、機能またはオブジェクトは、ネットワークのノードおよびリンクとしてモデル化されます。ネットワーク・モデルには、ノード間およびリンク間の接続性の関係、リンクの方向、ノードおよびリンクのコストなどの論理情報が含まれます。論理ネットワーク情報を使用して、ネットワークを分析し、質問(多くはパスの計算および追跡に関連する質問)に対する回答を得ることができます。たとえば、生化学パスウェイの場合、2つの化合物間で可能なすべての反応パスウェイを検出できます。または、道路ネットワークの場合、次の情報を検出できます。

  • 2つの都市間の最短(距離)パスまたは最速(移動時間)パス

  • 特定の空港に最も近いホテルおよびそのホテルへのアクセス方法

論理ネットワーク情報の他に、ノードの位置やリンクのジオメトリなどの空間情報をネットワークに関連付けることができます。この情報を使用すると、論理情報をモデル化できます(たとえば、ルートの物理的な長さを空間表現から直接計算できるため、このルートのコストなどの論理情報をモデル化できます)。

Spatialネットワーク・データ・モデル・グラフは、大規模で複雑なネットワークに対して使用できます。たとえば、図5-1では、ネットワーク・データ・モデルを使用して定義されたニューヨーク市のノードおよびリンクが、Network Editorデモ・ツール(5.14項を参照)を使用して表示されています。

図5-1 ニューヨーク市のノードとリンク

図5-1の説明が続きます。
図5-1「ニューヨーク市のノードとリンク」の説明

一般的なデータ・モデルおよびネットワーク分析機能を使用すると、従来の地理情報システム(GIS)の他に、多くの種類のネットワーク・アプリケーションをモデル化および分析できます。たとえば、生化学の分野では、アプリケーションで、生物の反応パスウェイ・ネットワークをモデル化する必要がある場合があります。製薬産業では、新薬発見プロセスをモデル化するアプリケーションで、蛋白質間の相互作用をモデル化する必要がある場合があります。

Spatialのネットワーク・モデリング機能には、スキーマ・オブジェクトおよびApplication Program Interface(API)が含まれます。スキーマ・オブジェクトには、メタデータおよびネットワーク表が含まれます。APIには、データベースでネットワークを作成、管理、編集および分析するためのサーバー側PL/SQL API(SDO_NETおよびSDO_NET_MEMパッケージ)、およびネットワークの編集と分析のための中間層(クライアント側)Java APIが含まれます。

5.2 ネットワーク・データ・モデルを使用するための主な手順

この項では、Oracle Spatialでネットワーク・データ・モデルを使用するための主な手順の概要を示します。また、重要な概念、構造および操作を示します(詳細は他の項を参照してください)。

ネットワークを作成するには2つの基本的な方法があります。

  • CREATE_<network-type>_NETWORKという形式の名前を持つプロシージャを使用して、大部分の操作をSpatialによって実行します。(5.2.1項を参照。)

  • 自分自身で操作を実行します。必要なネットワーク表を作成し、ネットワーク・メタデータを更新します。(5.2.2項を参照。)

どちらの方法を使用した場合も、ネットワーク・データをネットワーク表に挿入する必要があります。その後、ネットワーク・データ・モデルのPL/SQL Application Program Interface(API)およびJava APIを使用してネットワークを更新し、その他の操作を実行できます。(PL/SQL APIおよびJava APIについては、5.11項を参照してください。)

5.2.1 Spatialによる操作の実行

必要な操作の大部分をSpatialによって実行してネットワークを作成するには、次の手順を実行します。

  1. CREATE_<network-type>_NETWORKという形式の名前を持つプロシージャを使用してネットワークを作成します。<network-type>は、作成する必要があるネットワークのタイプです。

    これらの各プロシージャは、必要なネットワーク・データ・モデル表(5.9項を参照)を作成し、適切なネットワーク・メタデータ情報が含まれる行をxxx_SDO_NETWORK_METADATAビュー(5.10.1項を参照)に挿入します。

    各プロシージャには、2つの形式があります(一方の形式は、表および特定の列にデフォルトの名前を使用して、すべてのネットワーク・データ・モデル表を作成し、もう一方の形式を使用すると、表および特定の列に名前を指定できます)。ネットワーク・データ・モデル表のデフォルトの名前は、<network-name>_NODE$、<network-name>_LINK$、<network-name>_PATH$および<network-name>_PLINK$です。ネットワーク・データ・モデル表のコスト列のデフォルトの名前はCOSTで、ジオメトリ列のデフォルトの名前はGEOMETRYです。

  2. ノード表とリンク表、および必要に応じてパス表とパスリンク表にデータを挿入します。(ノード表、リンク表、パス表およびパスリンク表については、5.9項を参照してください。)

  3. SDO_NET.VALIDATE_NETWORKファンクションを使用して、ネットワークを検証します。

  4. 空間(SDOまたはLRS)ネットワークの場合、適切な情報をUSER_SDO_GEOM_METADATAビューに挿入し、ジオメトリ列に空間索引を作成します。

    ビューをノード表、リンク表またはパス表として使用する場合は、ノード表、リンク表またはパス表に関する情報をUSER_SDO_GEOM_METADATAビューに挿入する際に、TABLE_NAME列の値にビュー名を指定する必要があります。

5.2.2 自分自身での操作の実行

必要な操作を自分で実行してネットワークを作成するには、次の手順を実行します。

  1. SDO_NET.CREATE_NODE_TABLEプロシージャを使用して、ノード表を作成します。(ノード表については、5.9.1項を参照してください。)

  2. ノード表にデータを挿入します。

  3. SDO_NET.CREATE_LINK_TABLEプロシージャを使用して、リンク表を作成します。(リンク表については、5.9.2項を参照してください。)

  4. リンク表にデータを挿入します。

  5. オプションで、SDO_NET.CREATE_PATH_TABLEプロシージャを使用して、パス表を作成します。(パス表については、5.9.3項を参照してください。)

  6. パス表を作成した場合は、SDO_NET.CREATE_PATH_LINK_TABLEプロシージャを使用して、パスリンク表を作成します。(パスリンク表については、5.9.4項を参照してください。)

  7. パス表を作成した場合に、パスを作成する必要がある場合は、パス表にデータを挿入します。

  8. パス表にデータを挿入した場合、パスリンク表に適切な行を挿入します。

  9. ネットワークに関する情報が含まれる行をUSER_SDO_NETWORK_METADATAビューに挿入します。(USER_SDO_NETWORK_METADATAビューについては、5.10.1項を参照してください。)

    ビューをノード表、リンク表、パス表またはパスリンク表として使用する場合は、ネットワークに関する情報をUSER_SDO_NETWORK_METADATAビューに挿入する際に、関連する列にビュー名を指定する必要があります。

  10. 空間(SDOまたはLRS)ネットワークの場合、適切な情報をUSER_SDO_GEOM_METADATAビューに挿入し、ジオメトリ列に空間索引を作成します。

    ビューをノード表、リンク表またはパス表として使用する場合は、ノード表、リンク表またはパス表に関する情報をUSER_SDO_GEOM_METADATAビューに挿入する際に、TABLE_NAME列の値にビュー名を指定する必要があります。

  11. SDO_NET.VALIDATE_NETWORKファンクションを使用して、ネットワークを検証します。

これらの手順では、順序の一部を変更できます。たとえば、まずノード表とリンク表の両方を作成し、次にそれぞれの表にデータを挿入できます。また、ノード表およびリンク表を作成する前に、USER_SDO_NETWORK_METADATAビューに行を挿入できます。

5.3 ネットワーク・データ・モデルの概念

ネットワークは、接続性を使用してオブジェクト間の関係を表す数学的なグラフです。接続性は、空間の近接性に基づく場合と、基づかない場合があります。たとえば、2つの町が湖の対岸に位置するとき、1つの町からもう1つの町まで車で移動する場合には、空間の近接性に基づく最短パス(湖の中心を通る直線)は適切ではありません。かわりに、最短の運転距離を検出するには、道路と交差点、および個別のリンクのコストに関する接続性情報が必要です。

ネットワークは、一連のノードおよびリンクで構成されます。各リンク(エッジまたはセグメントともいう)は、2つのノードを指定します。

ネットワークは、有向(デフォルトでは、リンクの方向は開始ノードと終了ノードによって決まる)または無向(リンクのどちらの方向にも進むことができる)にすることができます。

ネットワーク・データ・モデルに関連するいくつかの重要な用語を次に示します。

  • ノード(頂点とも呼ばれます)は、リンクを相互に結合できる点です。孤立ノードとは、どのリンクにも含まれていないノードのことです。(連結ノードは、そのノードを含むすべてのリンクが削除されると、孤立ノードになります。)

  • リンクは、2つのノード間の関係を表します。有向ネットワーク内のリンクは、無向(開始ノードから終了ノード、終了ノードから開始ノードのどちらの向きにも進むことが可能)または有向(開始ノードから終了ノードの向きにのみ進むことが可能)に設定できます。無向ネットワーク内のリンクは、すべて無向です。

  • パスは、ノードおよびリンクを交互につなげたもので、ノードで開始および終了します。通常、同じノードおよびリンクが複数回現れることはありません。(1つのパス内でノードおよびリンクを繰返し使用することもできますが、ほとんどのネットワーク・アプリケーションでは、通常、同じノードおよびリンクが繰返し使用されることはありません。)

  • サブパスは、パスに沿った部分的なパスであり、ネットワーク分析操作の結果として作成されたり、ユーザーによって明示的に作成されます。サブパスについては、5.3.1項を参照してください。

  • 論理ネットワークには接続性情報が含まれますが、ジオメトリ情報は含まれません。これは、ネットワーク分析に使用されるモデルです。論理ネットワークは、アプリケーションに応じて、有向グラフまたは無向グラフとして処理できます。

  • 空間ネットワークには、接続性情報とジオメトリ情報の両方が含まれます。空間ネットワークでは、ノードおよびリンクは、LRS情報が含まれないSDO_GEOMETRYジオメトリ・オブジェクト(SDOネットワーク)、LRS情報が含まれるSDO_GEOMETRYジオメトリ・オブジェクト(LRSネットワーク)、またはSDO_TOPO_GEOMETRYオブジェクト(トポロジ・ジオメトリ・ネットワーク)になります。

    LRSネットワークでは、各ノードにジオメトリID値およびメジャー値が含まれ、各リンクにジオメトリID値および開始メジャー値と終了メジャー値が含まれます。いずれの場合にも、ジオメトリID値は、LRS情報が含まれるSDO_GEOMETRYオブジェクトを参照します。空間ネットワークは、アプリケーションに応じて、有向または無向にすることができます。

  • フィーチャは、ノードまたはリンクに関連付けられた、ネットワーク・アプリケーションの対象オブジェクトです。たとえば、輸送ネットワークでは、(ノードにマップされた)出口と交差点、および(リンクにマップされた)高速道路と通りがフィーチャになります。

  • コストは、最低コスト・パスを計算するための、リンクまたはノードに関連付け可能な負でない数値の属性です。最低コスト・パスとは、開始ノードから終了ノードまでの合計コストが最低になるパスです。ネットワーク・メタデータで、リンクの運転時間や運転距離など、単一のコスト因子を指定し、コストを調べるネットワーク分析ファンクションで使用できます。

  • 継続時間は、リンクまたはノードに関連付ける負でない数値の属性で、リンクまたはノードの継続時間の値を指定できます。継続時間の値は、時間(分)や他のユーザー定義項目を示すことができます。ネットワーク・メタデータで、リンクの運転時間など、単一の継続時間因子を指定できます。ただし、コストのかわりに継続時間を使用して経過時間を示す場合、指定した継続時間は、コストを調査するネットワーク分析ファンクションの検討対象になりません。

  • 状態は、ACTIVEまたはINACTIVE(またはSDO_NET_MEMサブプログラムでは、それぞれTRUEまたはFALSE)のいずれかの文字列属性で、これは、リンクまたはノードをネットワーク分析機能で考慮するかどうかを指定するために、リンクまたはノードに関連付けられています。たとえば、ノードの状態がINACTIVEの場合、そのノードが起点または終点のリンクは、2ノード間の最短パスの計算時に無視されます。リンクやノードを作成した時点では、状態はデフォルトでACTIVEですが、INACTIVEに設定できます。

  • タイプは、リンクまたはノードに関連付けることのできる文字列属性で、リンクまたはノードのタイプに対するユーザー定義値を指定します。

  • 一時的なリンク、ノードおよびパスは、ネットワーク・メモリー・オブジェクト内にのみ存在し、ネットワーク・メモリー・オブジェクトをデータベースに書き込むときもデータベースには書き込まれません。たとえば、ネットワークの分析時や編集セッション時には、一時ノードを作成して住所を表し、最短パスの計算で使用することがありますが、編集操作の結果を保存するときは、これらの一時ノードは保存されません。

  • 到達可能ノードは、任意のノードから到達可能なすべてのノードです。到達ノードは、任意のノードに到達可能なすべてのノードです。

  • ノードの度数は、そのノードへのリンク(ノードに対するインシデント)の数です。イン度数はインバウンド・リンクの数で、アウト度数はアウトバウンド・リンクの数です。

  • 接続されているコンポーネントとは、直接または間接的に接続されたネットワーク・ノードのグループのことです。ノードAがノードBに到達可能な場合、これらのノードは同じ接続されているコンポーネントに属している必要があります。2つのノードが接続されていない場合、これらのノード間で使用可能なパスがないということがわかります。この情報は、不要なパスの計算を避けるためのフィルタとして使用されます。

  • 接続されたグラフのスパニング・ツリーは、グラフのすべてのノードを接続するツリー(サイクルが含まれないグラフ)です。(スパニング・ツリーでは、リンクの方向は無視されます。)最低コスト・スパニング・ツリーは、すべてのノードを接続し、合計コストが最低になるスパニング・ツリーです。

  • パーティション化されたネットワークとは、複数のパーティションを含むネットワークのことです。大規模なネットワークをパーティション化すると、必要なパーティションのみをオンデマンドでメモリーにロードできるため、全体的なパフォーマンスが向上します。

    ネットワーク・パーティションとは、サブネットワークのことです。各パーティションには、ネットワーク全体のノードとリンクのサブセットが含まれます。ネットワーク・パーティションは、ロード・オンデマンド分析を行うための基本的な処理単位です。ネットワーク・パーティションを作成するには、ネットワーク内のすべてのノードを1つのパーティションIDのみに割り当てます。ネットワーク・パーティションの情報は、パーティション表に格納されます。

  • ロード・オンデマンド(ロード・オンデマンド分析)は、大規模なネットワークを管理可能なパーティションに分割し、分析中に必要なパーティションのみをロードすることによって、考慮事項となっているメモリー制限を排除し、全体的なパフォーマンスを向上させる方法です。

  • パーティションBLOBは、ネットワーク・パーティションをバイナリで表現したものです。これを使用すると、パーティションのロード時間を短縮できます。パーティションBLOBは、パーティションBLOB表に格納されます。

  • ロード・オンデマンドのパーティション・キャッシュは、ネットワーク分析中にメモリーにロードされるネットワーク・パーティションに対するメモリ内プレースホルダです。パーティション・キャッシュは、構成することができます。

  • ユーザー定義データは、ユーザーがネットワーク表現に関連付ける(接続性とは関係のない)情報です。ユーザー定義データは、ノード、リンク、パスおよびサブパスの各レベルで定義することができ、ノード表、リンク表、パス表およびサブパス表の列に格納されます。

5.3.1 サブパス

サブパスは、パスに沿った部分的なパスであり、ネットワーク分析操作の結果として作成されたり、ユーザーによって明示的に作成されます。サブパスの開始点および終了点は、図5-2に示すように、リンクの索引と、パスにおける1つ前のノードからの距離の割合として定義されます。

図5-2 パスおよびサブパス

図5-2の説明が続きます。
図5-2「パスおよびサブパス」の説明

サブパスは、次のパラメータを使用して、既存のパス(参照パス)を参照します。

  • 参照パスID: 参照パスのパスID。

  • 開始リンクの索引: 参照パス上の開始リンクの索引。(リンク索引0は、パス上の最初のノードと2番目のノード間のリンクを示します。)図5-2ではリンク索引0が開始リンクの索引です。

  • 開始の割合: サブパスの開始ノードに対する、開始リンクに沿った距離の割合。図5-2では、サブパスは、リンク索引0の開始から終了までの距離の65%の位置で開始しています。

  • 終了リンクの索引: 参照パス上の終了リンクの索引。図5-2ではリンク索引6が終了リンクの索引です。

  • 終了の割合: サブパスの終了ノードに対する、終了リンクに沿った距離の割合。図5-2では、サブパスは、リンク索引6の開始から終了までの距離の50%の位置で終了しています。

5.4 ネットワーク・アプリケーション

ネットワークは、アプリケーションで、異なるオブジェクトが相互に接続されている方法を確認するために使用されます。接続性は、通常、近接性およびパスの関係で表現されます。2つのノードが1つのリンクで接続されている場合、これらのノードは近接しています。多くの場合、任意の2つのノード間には複数のパスが存在し、コストが最低になるパスを検出する必要がある場合があります。

この項では、いくつかの種類のネットワーク・アプリケーションでの一般的な例について説明します。

5.4.1 道路ネットワークの例

通常の道路ネットワークでは、道路の交差点がノードになり、2つの交差点間の道路セグメントがリンクになります。道路の空間表現は、ネットワークのノードおよびリンクとは本質的に無関係です。たとえば、(道路の急カーブを反映する)道路の空間表現の形状点は、この形状点が交差点に関連付けられていない場合、ネットワークのノードにはなりません。また、単一の空間オブジェクトが、ネットワークの複数のリンクを構成する場合があります(横断する3つの道路によって交差点が形成された直線セグメントなど)。道路ネットワークに関する重要な操作は、移動時間または移動距離が最短になる、開始点から終了点までのパスを検索することです。パスの計算には、特定のランドマークの通過や特定の交差点の回避など、追加の制約が課せられる場合があります。

5.4.2 鉄道(地下鉄)ネットワークの例

大都市の地下鉄ネットワークは、停車駅および線路の正確な空間表現が重要でないと想定すると、最適なモデル化が行われた論理ネットワークであるといえます。このネットワークでは、地下鉄のすべての停車駅がネットワークのノードを構成し、列車が2つの停車駅間を直接移動する場合、これらの2つの停車駅間の接続がリンクになります。鉄道ネットワークに関する重要な操作には、指定された駅から到達可能なすべての駅の検索、指定された2つの駅間の停車駅の数の検索、および2つの駅間の移動時間の検索が含まれます。

5.4.3 ライフライン・ネットワークの例

送電線ネットワークやケーブル・ネットワークなどのライフライン・ネットワークは、多くの場合、コストが最低になるように構成する必要があります。ライフライン・ネットワークに関する重要な操作は、最低コスト・スパニング・ツリー・アルゴリズムを使用してノード間の接続を決定し、必要な品質のサービスを最低コストで提供することです。もう1つの重要な操作は、到達可能性の分析です。たとえば、水道ネットワークの給水拠点が停止した場合、影響を受けるエリアがわかります。

5.4.4 生化学ネットワークの例

生化学プロセスは、生体内の反応および調節を表す生化学ネットワークとしてモデル化できます。たとえば、代謝パスウェイは酵素反応に関連するネットワークで、調節パスウェイは蛋白質間の相互作用を表します。この例では、パスウェイがネットワークで、遺伝子、蛋白質および化合物がノードです。また、ノード間の反応がリンクになります。生化学ネットワークに関する重要な操作には、パスおよびノードの度数の計算が含まれます。

5.5 ネットワーク階層

一部のネットワーク・アプリケーションでは、異なる抽象化レベルでの表現が必要です。たとえば、2つの主なプロセスがリンクで接続された最も高い抽象化レベルのノードとして表され、それぞれの主なプロセスがノードおよびリンクで表現された1段階低いレベルの複数の下位プロセスを持つ場合があります。

ネットワーク階層を使用すると、各ノードに階層レベルを割り当てることによって、ネットワークを複数の抽象化レベルで表現できます。(リンクには階層レベルは割り当てられません。リンクは、同じ階層レベルまたは異なる階層レベルのノード間に設定できます。)階層内で最も低い(最も詳細な)レベルはレベル1で、これより高いレベルは順にレベル2、レベル3のように番号が付けられます。

ネットワーク階層で隣接するレベルのノードには、親子関係があります。上位レベルの各ノードは、下位レベルの1つ以上のノードに対する親ノードになります。下位レベルの各ノードは、上位レベルの1つのノードの子ノードになります。同じ親ノードを持つノードは、兄弟ノードになります。

リンクにも、親子関係がある場合があります。ただし、リンクには階層レベルが割り当てられないため、リンクの親子関係とネットワーク階層レベルには関連性がない場合もあります。同じ親リンクを持つリンクは、兄弟リンクになります。

図5-3に、2つのレベルが存在する単純な階層ネットワークを示します。

図5-3 ネットワークの階層

図5-3の説明が続きます。
図5-3「ネットワークの階層」の説明

次に、図5-3について説明します。

  • 上位レベル(レベル2)には、2つのノードが含まれます。各ノードは、下位レベルの複数のノードに対する親ノードです。上位レベルのノード間のリンクは、下位レベルのノード間の2つのリンクに対する親リンクです。

  • 下位レベル(レベル1)は、上位レベルの各ノードを構成するノードを示します。また、上位レベルの各親ノードの子ノードであるノード間のリンク、および異なる親ノードを持つノード間のリンクを示します。

  • 異なる親ノードを持つ下位レベルのノード間のリンクは、太い接続線で示されています。これらのリンクは、階層の上位レベルのノード間の単一のリンクの子リンクです。(ただし、下位レベルでのこれらの2つのリンクを、上位レベルのノード間の親リンクの子リンクとして定義しない場合もあります。)

  • それぞれの親ノードと親リンク、およびその子ノードと子リンクとの間の親子関係は、両端に矢印がある破線で示されています。

図5-3には示しませんが、異なる階層レベル間にリンクを設定できます。たとえば、上位レベルのノードと下位レベルの任意のノードとの間にリンクを定義できます。この場合、リンク間には親子関係がありません。

5.6 ネットワーク制約

ネットワーク制約は、ネットワーク分析の計算に対して定義される制限事項です。たとえば、道路ネットワークでは、一方通行や「左折禁止」標識などによる右/左折禁止リストがネットワーク制約になります。この場合、それぞれの右/左折禁止は、リンクの組合せ(開始リンクと、その開始リンクから右/左折できない終了リンクの組合せ)で表現されます。また、運転ルートに有料道路や高速道路を含めないという制限もネットワーク制約になります。

ネットワーク制約を作成するには、制約を実装するJavaクラスを作成し、SDO_NET.REGISTER_CONSTRAINTプロシージャを使用して制約を登録する必要があります。ネットワーク分析の操作にネットワーク制約を適用するには、該当するSDO_NET_MEMサブプログラムのconstraintパラメータでその制約を指定します。

ネットワーク制約を実装するJavaクラスの例が、ネットワーク・データ・モデルのデモ・ファイル(5.14項を参照)で提供されています。たとえば、ProhibitedTurns.javaファイルは、一連の右/左折禁止を定義するネットワーク制約を作成してから、2ノード間の最短パスを戻します(最初に制約を適用しない場合の最短パス、続いて制約を適用した場合の最短パスが戻ります)。

5.7 ロード・オンデマンドを使用したネットワーク分析

ロード・オンデマンドとは、ネットワーク分析時に、調査がネットワーク・パーティションに到達するまでは、そのパーティションがメモリーにロードされないことです。ロード・オンデマンドを使用すると、Oracle Spatialでは、ほとんどのパーティション化とロードの操作が自動的に実行され、これにより、通常は大規模なネットワークでのメモリーの使用効率を高めることができます。

ロード・オンデマンド分析には、次に説明する主要手順(ネットワークの作成、ネットワークのパーティション、パーティション・キャッシュの構成およびネットワーク分析)が含まれます。

  1. 5.2項で説明する方法のうち1つを使用してネットワークを作成します。

  2. SDO_NET.SPATIAL_PARTITIONプロシージャを使用してネットワークをパーティション化します(5.7.1項を参照)。

  3. オプションで、パーティションBLOBを生成します(5.7.2項を参照)。

  4. パーティション・キャッシュを含むロード・オンデマンド環境を構成します(5.7.3項を参照)。

  5. ネットワークを分析します(5.7.4項を参照)。


注意:

また、ロード・オンデマンド分析は、ネットワーク全体を1つのパーティションとして扱うことによって、パーティション化されていないネットワークでも使用できます。小規模なネットワークでは、ネットワークをパーディション化してもメリットが得られない場合があるため、そのようなケースについてはパーティション化を省略してロード・オンデマンドAPIを使用することができます。

ロード・オンデマンドのネットワーク分析の実行とパーティション・キャッシュの構成の例については、5.13.5項を参照してください。

パーティション化とロード・オンデマンド分析のその他の例については、Oracle Database Examplesメディアに含まれています(『Oracle Database Examplesインストレーション・ガイド』を参照)。ネットワーク・データ・モデルの例とデモ・ファイルの詳細は、5.14項を参照してください。

5.7.1 ネットワークのパーティション化

ネットワークをパーティション化するには、SDO_NET.SPATIAL_PARTITIONプロシージャを使用して、各パーティション内のノードの最大数を指定します。パーティション結果は、自動的に生成されるパーティション表に格納され、パーティション・メタデータ情報がネットワーク・メタデータに挿入されます。(このプロシージャを使用するかわりに、パーティション表を作成および移入することによってネットワークをパーティション化することもできます。)他のSDO_NETサブプログラムを使用してパーティション・メタデータを問い合せることもできます。

パーティション化の方法としては、パーティション間のリンク数を最小限に抑える方法をお薦めします。この方法により、ロードする必要のあるパーティションの数および同じパーティションをリロードする必要がある推定回数を減らします。また、パーティションのサイズが小さすぎると、分析中のパーティションのロードおよびアンロードが多くなります。

メモリーを1GBと想定した場合に推奨されるパーティション当たりのノードの最大数は、5,000から10,000の間です。この数を調整して使用中のアプリケーションに最適な数であることを確認するには、使用可能なメモリー、分析のタイプおよびネットワークのサイズを考慮します。また、パーティション・キャッシュのサイズの構成も考慮する必要があります。

5.7.2 パーティションBLOBの生成

ネットワークのロードのパフォーマンスを向上させるために、オプションで、ネットワーク・パーティションBLOB表にBLOBとしてパーティションを格納できます。パーティションのロード時間の短縮というメリットを得るには、この情報をネットワーク・メタデータ・ビューに格納する必要があります。ネットワークまたはパーティションの情報が更新されると、パーティションBLOBも再生成する必要があることに注意してください。

パーティションBLOBは、ノード数、リンク数、各ノードのプロパティ、各リンクのプロパティなどのネットワーク・パーティション情報を含むデータのバイナリ・ストリームです。パーティションBLOBが存在する場合、Spatialでは、時間のかかるデータベース問合せを実行せずに、このBLOBを使用してロード操作中に情報を読み取ります。

パーティションBLOBを生成するには、SDO_NET.GENERATE_PARTITION_BLOBSプロシージャを使用します。パーティションBLOBとそのメタデータは、パーティションBLOB表(5.9.7項を参照)に格納されます。

5.7.3 パーティション・キャッシュの構成

ネットワーク分析を実行する前に、XML構成ファイルを変更してデフォルトの構成をオーバーライドすることにより、パフォーマンスが最適化されるようにネットワーク・パーティション・キャッシュを構成できます。次の内容を指定できます。

  • キャッシュ・サイズ: パーティション・キャッシュ内のノードの最大数。

  • パーティション・ソース: ネットワーク表またはパーティションBLOB。

  • 常駐パーティション: キャッシュからフラッシュされることなく、一度ロードされるとメモリー内に保持されるパーティションのID。

  • キャッシュのフラッシュ方針: CachingHandlerの実装のクラス名。

    デフォルトのキャッシュ方針はLeastRecentlyUsedです。この方針では、キャッシュが一杯になると、メモリーから最も古いパーティションがフラッシュされます。他のキャッシュ方針を指定するには、CachingHandlerインタフェースを実装します。

デフォルトのロード・オンデマンド構成ファイルのコピーは、5.14項で説明する補足ドキュメントに含まれています。

5.7.4 ネットワークの分析

ネットワークの作成およびパーティション化を行い、オプションでパーティション・キャッシュを構成した後は、分析問合せを発行できます。分析結果は、JavaまたはXML APIのいずれを使用したかによって、Java表現またはXMLの応答で戻されます。詳細は、ロード・オンデマンド(LOD)のJavadocおよびXMLスキーマ(後者については5.14項を参照)を参照してください。

ロード・オンデマンドのJava APIを使用して分析結果をデータベースに書き込むこともできます。

5.7.5 リンク・レベルを使用した優先順位のモデリング

ロード・オンデマンド方式を使用すると、大規模なネットワークを分析する場合のメモリー制限の影響は小さくなりますが、分析操作の速度が非常に遅いままであることがあります。たとえば、ネットワーク全体を斜めに横切る2つのノードの最短パスの分析では、ネットワーク内のほとんどすべてのリンクを走査することになる可能性があります。そのため、ネットワークに200万個を超えるノードがある場合などは、非常に長い時間がかかります。

ネットワークの分析にかかる時間をさらに短縮するには、異なるリンク・レベルで分析を実行します。リンク・レベルとは、リンクの優先順位のレベルを示す、リンクに割り当てられた正の整数のことです。リンク・レベルが高いほど、優先順位が高くなります。たとえば、道路ネットワークの場合は、2つのリンク・レベル(一般道路に対してはレベル1、高速道路に対してはレベル2)で構成することができます。ネットワーク分析中は、高速道路が一般道路より優先され、最低リンク・レベルが1になります。(リンク・レベルが割り当てられていないリンクには、デフォルトのリンク・レベル1が使用されます。)

リンク・レベルには暗黙的な継承プロパティが含まれています。これは、リンク・レベルの高いネットワークが、リンク・レベルの低いネットワークのサブネットワークとなる必要があるということです。つまり、リンク・レベル2はリンク・レベル1のサブネットワークで、リンク・レベル3はリンク・レベル2のサブネットワークなどのように設定されます。

リンク・レベルはネットワークまたはパーティションのロード時に指定できます。これにより、そのレベルと、そのレベルより高いレベルのリンクがロードされます。一般道路に対してレベル1、および高速道路に対してレベル2が割り当てられている道路ネットワークの例では、ロード操作でリンク・レベル1を指定するとレベルが1および2のリンク(つまり一般道路と高速道路)がロードされますが、ロード操作でリンク・レベル2を指定すると、高速道路のリンクのみがロードされます。高速道路のリンクのみを使用して分析を実行する場合は、ロード操作に対してリンク・レベル2を指定してパフォーマンスを最適化できます。

5.7.6 計算済の分析結果

接続されているコンポーネントの分析などの一部の分析操作には、時間がかかる場合があります。実行時のパフォーマンスを向上させるには、SDO_NET.FIND_CONNECTED_COMPONENTSプロシージャをコールし、このプロシージャにより、ネットワーク内の接続されているコンポーネントを計算して、接続されているコンポーネント表(5.9.8項を参照)にその結果を格納します。

実行時には、最短パスの分析または到達可能性の分析をコールする前に、接続されているコンポーネント表を問い合せて、対象ノードが同じ接続されているコンポーネントに属しているかどうかを確認できます。計算済のコンポーネント情報が存在しない場合は、最短パスおよび到達可能性の分析で、2つのノードが実際には接続されていないことを検出するまでに長い時間がかかる場合があります。

5.8 インメモリー方式を使用したネットワークの編集と分析


注意:

次のリリースのSpatialでは、インメモリー方式は非推奨となり、将来の開発では、5.7項に記載のロード・オンデマンド方式が強化されます。利用できる場合は、ロード・オンデマンド方式を使用するをお薦めします。

この項では、仮想メモリーのキャッシュであるネットワーク・メモリー・オブジェクトを使用して、ネットワークの編集と分析操作を実行する方法ついて説明します。ネットワークのネットワークまたは階層レベルをネットワーク・メモリー・オブジェクトにロードしたり、メモリー・オブジェクトのネットワーク・オブジェクト上で操作を実行して、次に変更内容を破棄するか、またはデータベースにネットワークの変更内容を書き込むことができます。

指定のネットワークに対し、一度に複数のネットワーク・メモリー・オブジェクトが存在できますが、更新できるのは1つのみで、その他は読取り専用でなくてはなりません。情報を取得するか、またはネットワーク分析操作を実行するためだけにネットワーク・メモリー・オブジェクトを使用する場合のパフォーマンスを向上させるには、ネットワーク・メモリー・オブジェクトを読取り専用(つまり、SDO_NET_MEM.NETWORK_MANAGER.READ_NETWORKプロシージャでallow_updates=>'FALSE'を指定)にします。

ネットワーク・メモリー・オブジェクトの処理は、PL/SQL API(特にSDO_NET_MEMパッケージ)とJava APIのどちらでも実行できます。この2つのAPIについては、5.11項で説明します。

ネットワーク・データ・モデルのPL/SQL APIでは、SDO_NETパッケージのサブプログラムでデータベース内のネットワークを操作し、SDO_NET_MEMパッケージのサブプログラムでキャッシュ内のネットワーク・メモリー・オブジェクトを操作します。一部のネットワーク編集操作(ノード、リンクまたはパスの追加など)は、SDO_NETとSDO_NET_MEMのどちらのプロシージャでも実行できますが、編集操作を大量に行う場合はキャッシュ(SDO_NET_MEMプロシージャ)を使用した方がパフォーマンスが向上します。ただし、ほとんどのネットワーク操作については、SDO_NETまたはSDO_NET_MEMパッケージのどちらかのサブプログラムのみで実行可能なため、このような場合にネットワーク・メモリー・オブジェクトを使用するかどうかは、実行する操作によって決まります。

例5-1では、ネットワーク・メモリー・オブジェクトを使用して既存のネットワークに新しいノードと新しいリンクを追加し、最短パス分析を実行し、分析結果を出力し、変更内容と分析結果をデータベースに保存しています。この手順では、5.13.4項例5-5に示す文によって、XYZ_NETWORKという名前の論理ネットワークが作成済で、データが移入済であることを前提としています。

例5-1 ネットワーク・メモリー・オブジェクトを使用した編集と分析(PL/SQL)

DECLARE
  path_id     NUMBER;
  res_numeric NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN 
-- Create a network memory object in the user session for the 
-- logical network named XYZ_NETWORK. This creates a network 
-- object and reads all metadata, nodes, links, and paths in 
-- the network, and it allows for updates to be performed.
sdo_net_mem.network_manager.read_network(net_mem=>'XYZ_NETWORK', 
  allow_updates=>'TRUE');
 
-- Add a node with ID=901, and set its name to N901 and cost to 5.
sdo_net_mem.network.add_node(net_mem=>'XYZ_NETWORK', node_id=>901,
  node_name=>'N901', external_network_id=>0, external_node_id=>0);
sdo_net_mem.node.set_cost(net_mem=>'XYZ_NETWORK', node_id=>901, cost=>5);
 
-- Add a link with ID=9901, name=N901N1, cost=20 from node N901 to node N1.
sdo_net_mem.network.add_link(net_mem=>'XYZ_NETWORK', link_id=>9901, 
  link_name=>'N901N1', start_node_id=>901, end_node_id=>101, cost=>20);
 
-- Perform a shortest path analysis from node N1 to node N5.
path_id := sdo_net_mem.network_manager.shortest_path('XYZ_NETWORK', 101, 105);
DBMS_OUTPUT.PUT_LINE('The ID of the shortest path from N1 to N5 is: ' || path_id);
 
-- List the properties of the path: cost, nodes, and links.
res_numeric := sdo_net_mem.path.get_cost('XYZ_NETWORK', path_id);
DBMS_OUTPUT.PUT_LINE('The cost of this path is: ' || res_numeric);
res_array:= sdo_net_mem.path.get_node_ids('XYZ_NETWORK', path_id);
DBMS_OUTPUT.PUT('This path has the following nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
res_array:= sdo_net_mem.path.get_link_ids('XYZ_NETWORK', path_id);
DBMS_OUTPUT.PUT('This path has the following links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- Add the path to the network memory object.
sdo_net_mem.network.add_path(net_mem=>'XYZ_NETWORK', path_id=>path_id);
 
-- Write changes to the database and commit changes.
sdo_net_mem.network_manager.write_network(net_mem=>'XYZ_NETWORK');
 
-- Drop the network memory object.
sdo_net_mem.network_manager.drop_network(net_mem=>'XYZ_NETWORK');
 
END;
/
The ID of the shortest path from N1 to N5 is: 1
The cost of this path is: 50
This path has the following nodes: 101 103 104 105
This path has the following links: 1102 1104 1105

5.9 ネットワーク・データ・モデル表

空間ネットワークの接続性情報は、ノード表およびリンク表の2つの表に格納されます。さらに、パス情報を、パス表およびパスリンク表に格納できます。これらの表は、CREATE_<network-type>_NETWORKプロシージャを使用してネットワークを作成するときに、自動的に作成することができ、また、SDO_NET.CREATE_NODE_TABLESDO_NET.CREATE_LINK_TABLESDO_NET.CREATE_PATH_TABLEおよびSDO_NET.CREATE_PATH_LINK_TABLEの各プロシージャを使用して作成することもできます。

これらの表には、事前定義の名前を持つ列が含まれます。事前定義の列名は変更できません。ただし、ADD COLUMN句を指定してALTER TABLE文を実行することによって、表に列を追加できます。たとえば、各リンク表およびパス表は1つのCOST列を持つように作成されますが、追加の列を作成し、それらの列をその他の比較可能な属性に関連付けることができます。したがって、各リンクに運転時間、景色のよさ、および危険度を割り当てるには、運転時間にCOST列を使用し、SCENIC_APPEAL列およびDANGER列をリンク表に追加して、アプリケーションによって解釈される値を3つの列すべてに移入します。

次の注意事項は、Oracle Spatialのメタデータ・ビューに格納されるスキーマ名、表名および列名に適用されます。たとえば、これらの注意事項は、ネットワーク・メタデータ・ビュー(5.10項を参照)に格納されるノード表、リンク表、パス表およびパスリンク表の名前と、これらの表の列名にも適用されます。

  • 名前は、文字、数字およびアンダースコアのみで構成する必要があります。たとえば、名前にスペース( )、アポストロフィ(')、引用符(")またはカンマ(,)を含めることはできません。

  • 名前の中の文字はすべて、名前がメタデータ・ビューに格納される前または表がアクセスされる前に大文字に変換されます。この変換は、表名で指定されているスキーマ名にも適用されます。

5.9.1 ノード表

各ネットワークには、表5-1で説明する列が含まれるノード表があります。(含まれる列は、ネットワークのタイプ、およびネットワークが階層であるかどうかによって異なります。)

表5-1 ノード表の列

列名 データ型 説明

NODE_ID

NUMBER

ネットワーク内でこのノードを一意に識別するID番号です。

NODE_NAME

VARCHAR2(32)

ノード名です。

NODE_TYPE

VARCHAR2(24)

ノードのタイプを識別するユーザー定義の文字列です。

ACTIVE

VARCHAR2(1)

ノードがアクティブである(ネットワークで認識されている)場合はY、ノードがアクティブでない場合はNです。

PARTITION_ID

NUMBER

(使用されていません。かわりに、ノードとパーティションの関係は、5.9.6項で説明されているパーティション表に格納されます。)

<node_geometry_column>、またはGEOM_IDおよびMEASURE

SDO_GEOMETRY、SDO_TOPO_GEOMETRYまたはNUMBER

空間(SDO、非LRS)ネットワークの場合、ノードに関連付けられたSDO_GEOMETRYオブジェクトです。

空間トポロジ・ネットワークの場合、ノードに関連付けられたSDO_TOPO_GEOMETRYオブジェクトです。

空間LRSネットワークの場合、ノードに関連付けられたジオメトリ・オブジェクトのGEOM_ID列およびMEASURE列の値(いずれもNUMBER型)です。

論理ネットワークの場合、この列は使用しません。

空間SDOネットワークまたはトポロジ・ネットワークの場合、実際の列名は、デフォルト名、またはSDO_NET.CREATE_NODE_TABLEプロシージャのコール時にgeom_columnパラメータの値として指定した名前のいずれかになります。

<node_cost_column>

NUMBER

ノードに関連付けられるコスト値で、ネットワークを使用するアプリケーションによって使用されます。実際の列名は、デフォルト名、またはSDO_NET.CREATE_NODE_TABLEプロシージャのコール時にcost_columnパラメータの値として指定した名前のいずれかになります。コスト値は、料金所で支払う料金など、必要な任意の値を表すことができます。

HIERARCHY_LEVEL

NUMBER

階層ネットワークでのみ使用されます。このノードのネットワーク階層でのレベルを示す数値です。(ネットワーク階層については、5.5項を参照してください。)

PARENT_NODE_ID

NUMBER

階層ネットワークでのみ使用されます。このノードの親ノードのノードIDです。(ネットワーク階層については、5.5項を参照してください。)


5.9.2 リンク表

各ネットワークには、表5-2で説明する列が含まれるリンク表があります。

表5-2 リンク表の列

列名 データ型 説明

LINK_ID

NUMBER

ネットワーク内でこのリンクを一意に識別するID番号です。

LINK_NAME

VARCHAR2(32)

リンク名です。

START_NODE_ID

NUMBER

リンクの開始ノードのノードIDです。

END_NODE_ID

NUMBER

リンクの終了ノードのノードIDです。

LINK_TYPE

VARCHAR2(24)

リンクのタイプを識別するユーザー定義の文字列です。

ACTIVE

VARCHAR2(1)

リンクがアクティブである(ネットワークで認識されている)場合はY、リンクがアクティブでない場合はNです。

LINK_LEVEL

NUMBER

リンクの優先順位です。ネットワーク分析に使用すると、パスの計算時に優先順位の高いリンクが最初に考慮されます。

<link_geometry_column>、またはGEOM_ID、START_MEASUREおよびEND_MEASURE

SDO_GEOMETRY、SDO_TOPO_GEOMETRYまたはNUMBER

空間(SDO、非LRS)ネットワークの場合、リンクに関連付けられたSDO_GEOMETRYオブジェクトです。

空間トポロジ・ネットワークの場合、リンクに関連付けられたSDO_TOPO_GEOMETRYオブジェクトです。

空間LRSネットワークの場合、リンクに関連付けられたジオメトリ・オブジェクトのGEOM_ID列、START_MEASURE列およびEND_MEASURE列の値(すべてNUMBER型)です。

論理ネットワークの場合、この列は使用しません。

空間SDOネットワークまたはトポロジ・ネットワークの場合、実際の列名は、デフォルト名、またはSDO_NET.CREATE_LINK_TABLEプロシージャのコール時にgeom_columnパラメータの値として指定した名前のいずれかになります。

<link_cost_column>

NUMBER

リンクに関連付けられるコスト値で、ネットワークを使用するアプリケーションによって使用されます。実際の列名は、デフォルト名、またはSDO_NET.CREATE_LINK_TABLEプロシージャのコール時にcost_columnパラメータの値として指定した名前のいずれかになります。コスト値は、リンクの推定運転時間など、必要な任意の値を表すことができます。

PARENT_LINK_ID

NUMBER

階層ネットワークでのみ使用されます。このリンクの親リンクのリンクIDです。(ネットワーク階層の親子関係については、5.5項を参照してください。)

BIDIRECTED

VARCHAR2(1)

有向ネットワークの場合のみ使用されます。リンクが無向(開始ノードから終了ノード、終了ノードから開始ノードのどちらの方向にも進むことが可能)の場合はY、有向(開始ノードから終了ノードの方向にのみ進むことが可能)の場合はNです。


5.9.3 パス表

各ネットワークにパス表を作成できます。パスは、リンクを順につなげたもので、通常、ネットワーク分析の結果として作成されます。パス表は、この分析の結果を格納する方法を提供します。パス表ごとに、対応するパスリンク表(5.9.4項を参照)を作成する必要があります。各パス表には、表5-3で説明する列が含まれます。

表5-3 パス表の列

列名 データ型 説明

PATH_ID

NUMBER

ネットワーク内でこのパスを一意に識別するID番号です。

PATH_NAME

VARCHAR2(32)

パス名です。

PATH_TYPE

VARCHAR2(24)

パスのタイプを識別するユーザー定義の文字列です。

START_NODE_ID

NUMBER

パスの最初のリンクを開始するノードのノードIDです。

END_NODE_ID

NUMBER

パスの最後のリンクを終了するノードのノードIDです。

COST

NUMBER

パスに関連付けられるコスト値で、ネットワークを使用するアプリケーションによって使用されます。コスト値は、パスの推定運転時間など、必要な任意の値を表すことができます。

SIMPLE

VARCHAR2(1)

単純なパスの場合はY、複雑なパスの場合はNです。単純なパスでは、各リンクを1回使用することによって開始ノードから終了ノードまで横断できる、リンクの順序付けされたリストが形成されます。複雑なパスでは、開始ノードから終了ノードまで移動するために、複数のオプションがあります。

<path_geometry_column>

SDO_GEOMETRY

論理ネットワークを除くすべてのネットワーク・タイプの場合、パスに関連付けられたジオメトリ・オブジェクトです。実際の列名は、デフォルト名、またはSDO_NET.CREATE_PATH_TABLEプロシージャのコール時にgeom_columnパラメータの値として指定した名前のいずれかになります。

論理ネットワークの場合、この列は使用しません。


5.9.4 パスリンク表

各パス表(5.9.3項を参照)ごとに、パスリンク表を作成する必要があります。パスリンク表の各行は、ネットワークのパス内でリンクを一意に識別します。つまり、PATH_ID、LINK_IDおよびSEQ_NOの値の組合せが、ネットワーク内で一意である必要があります。パスリンク表での行の順序は、重要ではありません。各パスリンク表には、表5-4で説明する列が含まれます。

表5-4 パスリンク表の列

列名 データ型 説明

PATH_ID

NUMBER

ネットワークのパスのID番号です。

LINK_ID

NUMBER

ネットワークのリンクのID番号です。

SEQ_NO

NUMBER

パスでのリンクの一意の順序番号です。(順序番号は、1から始まります。)順序番号を使用すると、同じノードおよびリンクをパスに繰り返し含めることができます。


5.9.5 サブパス表

各パスには、1つ以上の対応するサブパスを作成できます。ネットワーク内のすべてのサブパスに関する情報は、サブパス表に格納されます。サブパスは、パスに沿った部分的なパスです(5.3項を参照)。サブパス表には、表5-5で説明する列が含まれます。

表5-5 サブパス表の列

列名 データ型 説明

SUBPATH_ID

NUMBER

このサブパスを参照パス内で一意に識別するID番号です。

SUBPATH_NAME

VARCHAR2(32)

サブパス名です。

SUBPATH_TYPE

VARCHAR2(24)

サブパスのタイプを識別するユーザー定義の文字列です。

REFERENCE_PATH_ID

NUMBER

このサブパスを含むパスのパスID番号です。

START_LINK_INDEX

NUMBER

サブパスの開始を定義するために使用するリンクのリンクIDです。たとえば、5.3項図5-2では、START_LINK_INDEXは0で、START_PERCENTAGEは0.65です。

END_LINK_INDEX

NUMBER

サブパスの終了を定義するために使用するリンクのリンクIDです。たとえば、5.3項図5-2では、END_LINK_INDEXは6で、END_PERCENTAGEは0.5です。

START_PERCENTAGE

NUMBER

パスのSTART_LINK_INDEXとその次のリンクの間の距離の割合で、サブパスの開始点を表します。正の数値または負の数値となります。たとえば、5.3項図5-2では、START_LINK_INDEXは0で、START_PERCENTAGEは0.65です。(この場合の割合の値は0から1.0の範囲で表されるので、0.65は65パーセントです。)

END_PERCENTAGE

NUMBER

パスのEND_LINK_INDEXとその次のリンクの間の距離の割合で、サブパスの終了点を表します。正の数値または負の数値となります。たとえば、5.3項図5-2では、END_LINK_INDEXは6で、END_PERCENTAGEは0.5です。(この場合の割合の値は0から1.0の範囲で表されるので、0.5は50パーセントです。)

COST

NUMBER

サブパスに関連付けられるコスト値で、ネットワークを使用するアプリケーションによって使用されます。コスト値は、パスの推定運転時間など、必要な任意の値を表すことができます。

GEOM

SDO_GEOMETRY

論理ネットワークを除くすべてのネットワーク・タイプの場合、サブパスに関連付けられたジオメトリ・オブジェクトです。実際の列名は、デフォルト名、またはSDO_NET.CREATE_SUBPATH_TABLEプロシージャのコール時にgeom_columnパラメータの値として指定した名前のいずれかになります。

論理ネットワークの場合、この列は使用しません。


5.9.6 パーティション表

パーティション化された各ネットワークには、パーティション表があります。パーティション化されたネットワークの詳細は、5.7項を参照してください。各パーティション表には、表5-6で説明する列が含まれます。

表5-6 パーティション表の列

列名 データ型 説明

NODE_ID

NUMBER

ノードのID番号です。

PARTITION_ID

NUMBER

パーティションのID番号です。ネットワーク内で一意である必要があります。

LINK_LEVEL

NUMBER

リンク・レベルです(リンク・レベルは、リンクの優先順位です。ネットワーク分析に使用すると、パスの計算時に優先順位の高いリンクが最初に考慮されます)。


5.9.7 パーティションBLOB表

パーティション化された各ネットワークには、パーティションBLOB表があります。この表には、ネットワークのリンク・レベルとパーティションIDの組合せごとのバイナリ・ラージ・オブジェクト(BLOB)表現が格納されます。パーティションのBLOB表現を使用すると、ネットワークのロード・オンデマンド分析操作でパフォーマンスが向上します。パーティションBLOB表を作成するには、SDO_NET.GENERATE_PARTITION_BLOBSプロシージャを使用します。このプロシージャでは、パーティションBLOB表の名前をパラメータの1つとして指定します。パーティション化されたネットワークの詳細は、5.7項を参照してください。


注意:

パーティションBLOB表を直接変更することはできません。この表は、SDO_NET.GENERATE_PARTITION_BLOBSプロシージャおよびSDO_NET.GENERATE_PARTITION_BLOBプロシージャへのコールの結果として自動的に更新されます。

各パーティション表には、表5-7で説明する列が含まれます。

表5-7 パーティションBLOB表の列

列名 データ型 説明

LINK_LEVEL

VARCHAR2(32)

リンク・レベルです(リンク・レベルは、リンクの優先順位です。ネットワーク分析に使用すると、パスの計算時に優先順位の高いリンクが最初に考慮されます)。

PARTITION_ID

NUMBER

パーティションのID番号です。

BLOB

BLOB

指定したパーティション内の指定したリンク・レベルを表すバイナリ・ラージ・オブジェクト(BLOB)です。

NUM_INODES

NUMBER

BLOBの内部ノード数(BLOB内の合計ノード数)です。

NUM_ENODES

NUMBER

外部ノードの数です。外部ノードとは、BLOB外にあるノードで、このノードが一端を構成するリンクのもう一端のノードがBLOB内にあるものを指します。

NUM_ILINKS

NUMBER

BLOBの内部リンク(完全にBLOB内にあるリンク)の数です。

NUM_ELINKS

NUMBER

外部リンクの数です。外部リンクとは、1つのノードが内部(BLOB内)で、1つのノードが外部(BLOB外)となっているリンクです。

NUM_INLINKS

NUMBER

外部からのリンクの数です。外部からのリンクとは、開始ノードがBLOB外にあり、終了ノードがBLOB内にある外部リンクです。

NUM_OUTLINKS

NUMBER

外部へのリンクの数です。外部へのリンクとは、開始ノードがBLOB内にあり、終了ノードがBLOB外にある外部リンクです。

USER_DATA_INCLUDED

VARCHAR2(1)

BLOBにユーザー・データを含めることができる場合はY、BLOBにユーザー・データを含めることができない場合はNです。


5.9.8 接続されているコンポーネント表

各ネットワークには、接続されているコンポーネント表を作成できます。この表には各ノードのコンポーネントIDが格納されます。同じ接続されているコンポーネントのノードは、同じコンポーネントIDを持ちます。この情報が表に格納されていると、ネットワーク分析の多くの操作でパフォーマンスが向上します。接続されているコンポーネント表を作成し、後から表の内容を更新するには、SDO_NET.FIND_CONNECTED_COMPONENTSプロシージャを使用します。このプロシージャでは、接続されているコンポーネント表の名前をパラメータの1つとして指定します。接続されているコンポーネントに関する計算済情報の使用の詳細は、5.7.6項を参照してください。

各接続されているコンポーネント表には、表5-8で説明する列が含まれます。

表5-8 接続されているコンポーネント表の列

列名 データ型 説明

LINK_LEVEL

NUMBER

コンポーネントの割当てのリンク・レベルです。(リンク・レベルは、リンクの優先順位です。ネットワーク分析に使用すると、パスの計算時に優先順位の高いリンクが最初に考慮されます。)

NODE_ID

NUMBER

到達可能なその他すべてのコンポーネントの算出元となるノードのID番号です。

COMPONENT_ID

NUMBER

指定したノードから到達可能なコンポーネントのID番号です。


5.10 ネットワーク・データ・モデルのメタデータ・ビュー

スキーマ(ユーザー)ごとに、xxx_SDO_NETWORK_METADATAという一連のネットワーク・メタデータ・ビューがあります。xxxは、USERまたはALLです。これらのビューは、Spatialによって作成されます。

5.10.1 xxx_SDO_NETWORK_METADATAビュー

次のビューには、ネットワークに関する情報が含まれます。

  • USER_SDO_NETWORK_METADATAには、ユーザーが所有するすべてのネットワークに関する情報が含まれます。

  • ALL_SDO_NETWORK_METADATAには、ユーザーがSELECT権限を持つすべてのネットワークに関する情報が含まれます。

CREATE_<network-type>_NETWORKプロシージャの1つを使用してネットワークを作成すると、これらのビューの情報が、新しいネットワークを反映するように自動的に更新されます。このプロシージャを使用してネットワークを作成しない場合、ネットワークに関する情報をUSER_SDO_NETWORK_METADATAビューに挿入する必要があります。

USER_SDO_NETWORK_METADATAビューとALL_SDO_NETWORK_METADATAビューのどちらにも表5-9に示す列が含まれますが、USER_SDO_NETWORK_METADATAビューにはOWNER列は含まれません。(列は、ビューの定義どおりの順序で示します。)

表5-9 xxx_SDO_NETWORK_METADATAビューの列

列名 データ型 説明

OWNER

VARCHAR2(32)

ネットワークの所有者です(ALL_SDO_NETWORK_METADATAビューのみ)。

NETWORK

VARCHAR2(24)

ネットワーク名です。

NETWORK_ID

NUMBER

ネットワークのID番号です。Spatialによって割り当てられます。

NETWORK_CATEGORY

VARCHAR2(12)

ネットワークのノードおよびリンクが空間ジオメトリに関連付けられている場合はSPATIAL、ネットワークのノードおよびリンクが空間ジオメトリに関連付けられていない場合はLOGICALです。値がLOGICALの場合、ネットワーク・データ・モデルのPL/SQL APIおよびJava APIで、ノード、リンクおよびパスの空間属性は無視されます。

GEOMETRY_TYPE

VARCHAR2(24)

NETWORK_CATEGORYSPATIALの場合は、ノードおよびリンクのジオメトリ・タイプを示す値です。非LRS SDO_GEOMETRYオブジェクトの場合はSDO_GEOMETRY、LRS SDO_GEOMETRYオブジェクトの場合はLRS_GEOMETRY、SDO_TOPO_GEOMETRYオブジェクトの場合はTOPO_GEOMETRYです。

NETWORK_TYPE

VARCHAR2(24)

ネットワークのタイプを識別するユーザー定義の文字列です。

NO_OF_HIERARCHY_LEVELS

NUMBER

ネットワーク階層のレベルの数です。階層がない場合は1が含まれます。(ネットワーク階層については、5.5項を参照してください。)

NO_OF_PARTITIONS

NUMBER

(現在は使用されていません)

LRS_TABLE_NAME

VARCHAR2(32)

GEOMETRY_TYPESDO_GEOMETRYの場合、ノードに関連付けられたジオメトリが含まれる表の名前です。

LRS_GEOM_COLUMN

VARCHAR2(32)

LRS_TABLE_NAMEに表名が指定されている場合、その表のジオメトリ列です。

NODE_TABLE_NAME

VARCHAR2(32)

GEOMETRY_TYPESDO_GEOMETRYの場合、ノードに関連付けられたジオメトリが含まれる表の名前です。(ノード表については、5.9.1項を参照してください。)

NODE_GEOM_COLUMN

VARCHAR2(32)

NODE_TABLE_NAMEに表名が指定されている場合、その表のジオメトリ列です。

NODE_COST_COLUMN

VARCHAR2(1024)

NODE_TABLE_NAMEに表名が指定されている場合、その表のコスト列です。またはコスト値を計算するPL/SQLファンクションです。

NODE_PARTITION_COLUMN

VARCHAR2(32)

(現在は使用されていません)

NODE_DURATION_COLUMN

VARCHAR2(32)

NODE_TABLE_NAMEに表名が指定されている場合、その表の継続時間列(オプション)です。この列には、ユーザー定義項目の数値(ノードに関連付けられた時間(分)など)を含めることができます。

LINK_TABLE_NAME

VARCHAR2(32)

GEOMETRY_TYPESDO_GEOMETRYの場合、リンクに関連付けられたジオメトリが含まれる表の名前です。(リンク表については、5.9.2項を参照してください。)

LINK_GEOM_COLUMN

VARCHAR2(32)

LINK_TABLE_NAMEに表名が指定されている場合、その表のジオメトリ列です。

LINK_DIRECTION

VARCHAR2(12)

ネットワークのすべてのリンクのタイプを示す値です。UNDIRECTEDまたはDIRECTEDになります。

LINK_COST_COLUMN

VARCHAR2(1024)

LINK_TABLE_NAMEに表名が指定されている場合、各リンクのコスト値が含まれるオプションの数値列です。またはコスト値を計算するPL/SQLファンクションです。

LINK_PARTITION_COLUMN

VARCHAR2(32)

(現在は使用されていません)

LINK_DURATION_COLUMN

VARCHAR2(32)

LINK_TABLE_NAMEに表名が指定されている場合、その表の継続時間列(オプション)です。この列には、ユーザー定義項目の数値(リンクに関連付けられた時間(分)など)を含めることができます。

PATH_TABLE_NAME

VARCHAR2(32)

パスに関する情報が含まれるオプションの表の名前です。(パス表については、5.9.3項を参照してください。)

PATH_GEOM_COLUMN

VARCHAR2(32)

PATH_TABLE_NAMEが空間ネットワークに関連付けられている場合、その表のジオメトリ列です。

PATH_LINK_TABLE_NAME

VARCHAR2(32)

各パスのリンクに関する情報が含まれるオプションの表の名前です。(パスリンク表については、5.9.4項を参照してください。)

SUBPATH_TABLE_NAME

VARCHAR2(32)

サブパスに関する情報が含まれるオプションの表の名前です。(サブパス表については、5.9.5項を参照してください。)

SUBPATH_GEOM_COLUMN

VARCHAR2(32)

SUBPATH_TABLE_NAMEが空間ネットワークに関連付けられている場合、その表のジオメトリ列です。

PARTITION_TABLE_NAME

VARCHAR2(32)

パーティション化されたネットワークの場合: パーティション表の名前です。(パーティション表については、5.9.6項を参照してください。)

PARTITION_BLOB_TABLE_NAME

VARCHAR2(32)

パーティションBLOBが生成されているパーティション化されたネットワークの場合: パーティションBLOB表の名前です。(パーティションBLOB表については、5.9.7項を参照してください。)

COMPONENT_TABLE_NAME

VARCHAR2(32)

計算済の接続されているコンポーネント(5.7.6項を参照)に関する情報を含む表の名前です。(接続されているコンポーネント表については、5.9.8項を参照してください。)

NODE_LEVEL_TABLE_NAME

VARCHAR2(32)

階層ネットワークのノード・レベルに関する情報を含む表の名前です。この表は、SDO_NET.GENERATE_NODE_LEVELSプロシージャでnode_level_table_nameパラメータとして指定します。

TOPOLOGY

VARCHAR2(32)

(SDO_NET.CREATE_TOPO_NETWORKプロシージャで作成した)SDO_TOPO_GEOMETRYオブジェクトが含まれる空間ネットワークの場合、トポロジの名前です。

USER_DEFINED_DATA

VARCHAR2(1)

ネットワークにユーザー定義データが含まれる場合はY、ネットワークにユーザー定義のデータが含まれない場合はNです。

EXTERNAL_REFERENCES

VARCHAR2(1)

(現在は使用されていません)


5.10.2 xxx_SDO_NETWORK_CONSTRAINTSビュー

次のビューには、ネットワーク制約(5.6項を参照)に関する情報が含まれます。

  • USER_SDO_NETWORK_CONSTRAINTSには、ユーザーが所有するすべてのネットワーク制約に関する情報が含まれます。

  • ALL_SDO_NETWORK_CONSTRAINTSには、ユーザーがSELECT権限を持つすべてのネットワーク制約に関する情報が含まれます。

これらのビューは、SDO_NET.REGISTER_CONSTRAINTプロシージャおよびSDO_NET.DEREGISTER_CONSTRAINTプロシージャによって自動的に保持されます。これらのビューの内容を直接変更することはできません。

USER_SDO_NETWORK_CONSTRAINTSビューとALL_SDO_NETWORK_CONSTRAINTSビューのどちらにも表5-10に示す列が含まれますが、USER_SDO_NETWORK_CONSTRAINTSビューにはOWNER列は含まれません。(列は、ビューの定義どおりの順序で示します。)

表5-10 xxx_SDO_NETWORK_CONSTRAINTSビューの列

列名 データ型 説明

OWNER

VARCHAR2(32)

ネットワーク制約の所有者です(ALL_SDO_NETWORK_CONSTRAINTSビューのみ)。

CONSTRAINT

VARCHAR2(32)

ネットワーク制約の名前です。

DESCRIPTION

VARCHAR2(200)

ネットワーク制約に関する説明(目的、使用上の注意など)です。

CLASS_NAME

VARCHAR2(4000)

ネットワーク制約を実装するJavaクラスの名前です。

CLASS

バイナリ・ファイルのLOB

ネットワーク制約を実装するJavaクラスです。


5.10.3 xxx_SDO_NETWORK_USER_DATAビュー

次のビューには、ネットワークのユーザー定義データに関する情報が含まれます。これは、ユーザーがネットワーク表現と関連付ける(接続性とは関係のない)情報です。

  • USER_SDO_NETWORK_USER_DATAには、ユーザーが所有するすべてのネットワークのユーザー定義データに関する情報が含まれます。

  • ALL_SDO_NETWORK_USER_DATAには、ユーザーがSELECT権限を持つすべてのネットワークのユーザー定義データに関する情報が含まれます。

USER_SDO_NETWORK_USER_DATAビューとALL_SDO_NETWORK_USER_DATAビューのどちらにも表5-10に示す列が含まれますが、USER_SDO_NETWORK_USER_DATAビューにはOWNER列は含まれません。(列は、ビューの定義どおりの順序で示します。)

表5-11 xxx_SDO_NETWORK_USER_DATAビューの列

列名 データ型 説明

OWNER

VARCHAR2(32)

ネットワーク制約の所有者です(ALL_SDO_NETWORK_CONSTRAINTSビューのみ)。

NETWORK

VARCHAR2(32)

ネットワーク名です。

TABLE_TYPE

VARCHAR2(12)

ユーザー定義データを含む表のタイプ: NODELINKPATHまたはSUBPATHです。

DATA_NAME

VARCHAR2(32)

ユーザー定義データを含む列の名前です。

DATA_TYPE

VARCHAR2(12)

ユーザー定義データのデータ型: VARCHAR2INTEGERNUMBERDATETIMESTAMPまたはSDO_GEOMETRYです。

DATA_LENGTH

NUMBER(38)

DATA_TYPEがVARCHAR2である場合、ユーザー定義データの長さです。

CATEGORY_ID

NUMBER

ユーザー・データ・カテゴリID (負でない数値、デフォルト値は0)です。カテゴリIDを使用すると、アプリケーションごとにユーザー・データをグループ化できます。カテゴリ0は、すべてのアプリケーションに有効な汎用ユーザー・データに使用するために予約されています。ユーザー・データを目的ごとに異なるカテゴリにグループ化できますので、ネットワーク分析中は、関連するユーザー・データ・カテゴリのみがメモリーにロードされ、実行時のメモリー使用量が削減されます。

たとえば、道路ネットワークの場合、カテゴリ0のユーザー・データには、リンクの制限速度およびファンクション・クラスと、ノードの(x, y)座標を含めることができ、トラック輸送関連のユーザー・データをカテゴリ1に、またトラフィック関連のユーザー・データをカテゴリ2に含めることができます。


ユーザー定義データを使用するには、適切なxxx_SDO_NETWORK_METADATAビュー(5.10.1項を参照)のUSER_DEFINED_DATA列値をYに設定する必要があります。

ユーザー定義データの使用例については、5.13.6項を参照してください。

5.11 ネットワーク・データ・モデルのApplication Program Interface(API)

Oracle Spatialのネットワーク・データ・モデルには、2つのクライアントApplication Program Interface(API)として、SDO_NETおよびSDO_NET_MEMパッケージによって提供されるPL/SQLインタフェースと、Javaインタフェースが含まれます。両方のインタフェースを使用して、ネットワーク・データの作成と更新、およびネットワークの分析を実行できます。ネットワーク表の移入および索引の作成にはPL/SQLのみまたはSQLのみを使用し、アプリケーション開発にはPL/SQLまたはJavaのいずれかを使用することをお薦めします。

PL/SQL APIとJava APIには、次のパフォーマンス上の注意事項があります。

  • 空間ネットワークの空間に関係しない内容について分析または編集を行う場合は、これらの処理を開始する前にUSER_SDO_NETWORK_METADATAビュー(5.10.1項を参照)のNETWORK_CATEGORY列の値をLOGICALに設定し、処理が完了してから値をSPATIALに戻すことで、パフォーマンスを向上できます。

    たとえば、2ノード間の最短パスの計算で検討されるのはコスト値であるため、この方法は最短パスを探す場合に利用できます。ただし、リンクに対して空間ジオメトリ・オブジェクトまたは終了メジャー値を設定する場合は、この方法を利用できません。

  • ネットワーク・オブジェクトを変更しない場合(ネットワークの分析操作または情報取得のみを実行する場合)は、ネットワーク・メモリー・オブジェクトを読取り専用で(更新不可を指定して)作成することで、パフォーマンスを向上できます。

5.11.1 ネットワーク・データ・モデルのPL/SQLインタフェース

SDO_NETパッケージは、データベース・サーバー上でネットワークの作成、アクセスおよび管理を行うためのサブプログラムを提供します。Java APIで利用可能な機能を実装するSDO_NET_MEMパッケージは、ネットワーク・メモリー・オブジェクトと呼ばれるキャッシュ・オブジェクトを使用して、ネットワーク・オブジェクトの編集とネットワークの分析を実行するためのサブプログラムを提供します。SDO_NETのファンクションとプロシージャの使用例は、5.13項例5-4に示しています。5.8項では、ネットワーク・メモリー・オブジェクトの使用方法について説明し、SDO_NET_MEMのファンクションとプロシージャを使用する例5-1を示しています。

SDO_NETサブプログラムは、次の論理カテゴリにグループ化できます。

SDO_NETの各ファンクションおよびプロシージャのリファレンス情報については、第6章を参照してください。

SDO_NET_MEMサブプログラムは、oracle.spatial.networkインタフェースまたはクラス内の関連付けられたオブジェクト関連クラスに従ってグループ化されます。各プログラムのSDO_NET_MEMの後ろに接頭辞を指定する必要があり、この接頭辞は、関連付けられたクラス(たとえば、SDO_NET_MEM.NETWORK_MANAGER.CREATE_LOGICAL_NETWORK、SDO_NET_MEM.NETWORK.ADD_NODEおよびSDO_NET_MEM.NODE.GET_COST)によって異なります。


注意:

このマニュアルは、SDO_NET_MEMパッケージについて触れていますが、1つを除くすべてのサブプログラムが、実際には各種オブジェクト・タイプのメソッドとして実装されています。そのため、サブプログラムのリストをDESCRIBE SDO_NET_MEM文で表示することはできません。かわりに、第7章表7-1に示されているDESCRIBE文を使用して、各グループのサブプログラムを表示できますが、これらはオブジェクト・タイプのメンバー・ファンクションとメンバー・プロシージャであるため、DESCRIBE文の結果には、グループ別のサブプログラムをアルファベット順に表示できません。

SDO_NET_MEMサブプログラムは、次のようにグループ化されています。

  • SDO_NET_MEM.NETWORK_MANAGERサブプログラムは、oracle.spatial.network.NetworkManager Javaクラスに関連します。このサブプログラムでは、ネットワーク・メモリー・オブジェクトの作成と削除、およびネットワークの分析を実行できます。

  • SDO_NET_MEM.NETWORKサブプログラムは、oracle.spatial.network.Network Javaインタフェースに関連します。このサブプログラムでは、ノード、リンクおよびパスを追加および削除できます。

  • SDO_NET_MEM.NODEサブプログラムは、oracle.spatial.network.Node Javaインタフェースに関連します。このサブプログラムでは、ノードの属性を取得および設定できます。

  • SDO_NET_MEM.LINKサブプログラムは、oracle.spatial.network.Link Javaインタフェースに関連します。このサブプログラムでは、リンクの属性を取得および設定できます。

  • SDO_NET_MEM.PATHサブプログラムは、oracle.spatial.network.Path Javaインタフェースに関連します。このサブプログラムでは、パスの属性を取得および設定できます。

SDO_NET_MEMのサブプログラムとJava APIのメソッドは、必ずしも正確に対応しているわけではありません。場合によっては、1つのPL/SQLサブプログラムによって、複数のメソッドの操作とオプションがまとめられていることもあります。また、対応するPL/SQLがないJavaメソッドもあります。このため、サブプログラムの「使用上の注意」では、双方に論理的な関係があることを示す場合、そのファンクションまたはプロシージャに類似した特定のJavaメソッドがあることのみを示しています。特定のJavaメソッドおよびその関連項目の詳細は、Javadoc生成のAPIドキュメント(概略は5.11.2項)を参照してください。

SDO_NET_MEMの各ファンクションおよびプロシージャのリファレンス情報については、第7章を参照してください。

5.11.2 ネットワーク・データ・モデルのJavaインタフェース

ネットワーク・データ・モデルのJavaインタフェースには、インメモリーのインタフェースおよびロード・オンデマンドのインタフェースが含まれています。これらのインタフェースに関する完全なリファレンス情報については、『Oracle Spatial Java API Reference』を参照してください。インメモリーのJavaインタフェースのクラスは、oracle.spatial.networkパッケージに含まれています。ロード・オンデマンドのJavaインタフェースのクラスは、oracle.spatial.network.lodパッケージとそのサブパッケージに含まれています。

SpatialのJavaクラス・ライブラリは、<ORACLE_HOME>/md/jlib/ディレクトリの下の.jarファイルにあります。

5.11.2.1 ネットワーク・メタデータとデータの管理

Java APIを使用して、次のようなネットワーク・メタデータとデータの管理操作を実行できます。

  • ノードおよびリンクのデータの挿入、削除および変更

  • データベースからのネットワークのロード

  • データベースへのネットワークの格納

  • データベースへのネットワーク・メタデータの格納

  • ネットワーク・メタデータの属性の変更

5.11.2.2 インメモリー方式を使用したネットワーク分析

oracle.spatial.network.NetworkManagerクラスを使用し、インメモリー方式を使用して、次のようなネットワーク分析操作を実行できます。

  • 最短パス: グラフ理論の一般的な推移閉包問題です。任意の開始ノードおよび終了ノードについて、最短パスを検索します。

  • 最低コスト・スパニング・ツリー: 任意の無向グラフについて、すべてのノードを接続する最低コスト・ツリーを検索します。

  • 到達可能性: 任意のノードについて、このノードに到達可能なすべてのノードを検索するか、またはこのノードから到達可能なすべてのノードを検索します。

  • コスト内分析: 任意のターゲット・ノードおよびコストについて、任意のコスト内でターゲット・ノードから到達可能なすべてのノードを検索します。

  • 最近隣分析: 任意のターゲット・ノードおよび近くにある複数のノードについて、近くにあるノードおよびそのノードから任意のターゲット・ノードに移動するためのコストを検索します。

  • 2つのノード間のすべてのパス: 任意の2つのノードについて、これらのノード間で使用可能なすべてのパスを検索します。

  • TSP(巡回セールスマン問題)の分析: 指定された一連のノードについて、すべてのノードを通過する最も効率的なパス(最小コストまたは最短距離のパス)を検索し、開始ノードと終了ノードは、オプションで同じノードに指定できます。

5.11.2.3 ロード・オンデマンド方式を使用したネットワーク分析

oracle.spatial.network.lod.NetworkAnalystクラスを使用し、ロード・オンデマンド方式を使用して次のようなネットワーク分析操作を実行できます。

  • 最短パス: グラフ理論の一般的な推移閉包問題です。任意の開始ノードおよび終了ノードについて、最短パスを検索します。

  • 到達可能性: 任意のノードについて、このノードに到達可能なすべてのノードを検索するか、またはこのノードから到達可能なすべてのノードを検索します。

  • コスト内分析: 任意のターゲット・ノードおよびコストについて、任意のコスト内でターゲット・ノードから到達可能なすべてのノードを検索します。

  • 最近隣分析: 任意のターゲット・ノードおよび近くにある複数のノードについて、近くにあるノードおよびそのノードから任意のターゲット・ノードに移動するためのコストを検索します。

  • 動的データ入力: ネットワーク更新情報を使用してNetworkUpdateオブジェクトを作成して使用します。

  • ユーザー定義のリンクおよびノードのコスト計算表: リンクまたはノードのコストを計算する方法を定義します。

5.12 複数のスキーマが関係している場合のネットワーク・アクセス

ネットワーク所有者以外のデータベース・ユーザーがメモリーにネットワークを読み込む場合は、次のいずれかを実行する必要があります。

  • 所有者以外のユーザーごとに、USER_SDO_NETWORK_METADATAビューのネットワーク表をネットワーク所有者のスキーマで修飾します(5.12.1項を参照)。

  • 所有者以外のユーザーごとに、ネットワーク・データ・モデル表に対するビューを作成し、USER_SDO_NETWORK_METADATAビューを更新します(5.12.2項を参照)。

2つ目の方法では、ビューの作成という追加の手順が必要ですが、このビューによって、ネットワークにおけるアクセス可能な部分を柔軟に制御できるようになります。各ビューでは、ネットワークのすべての部分にアクセスできるようにすることも、WHERE句を使用してアクセスを一部分のみに制限することもできます(たとえば、WHERE STATE_CODE='NY'では、ビュー・ユーザーをNew Yorkの行に制限します)。

例として、次のシナリオについて考えてみます。

  • User1がNetwork1を作成します(したがって、所有者になります)。

  • User2がSDO_NET_MEM.NETWORK_MANAGER.READ_NETWORKプロシージャをコールしてNetwork1を読み込もうとしますが、エラーが発生します。このエラーは、User2がNetwork1のネットワーク・データ・モデル表に対する適切な権限を所有していても発生します。

この問題に対処するには、5.12.1項「複数のスキーマが関係している場合のネットワーク・メタデータでの所有者の指定によるアクセス」または5.12.2項「複数のスキーマが関係している場合のビューを使用したアクセス」のいずれかの方法を使用する必要があります。

5.12.1 複数のスキーマが関係している場合のネットワーク・メタデータでの所有者の指定によるアクセス

(適切な権限のある)所有者以外のユーザーがネットワークにアクセスできるように、ネットワーク・メタデータでネットワーク所有者を指定します。ネットワークへのアクセスを許可する所有者以外のユーザーごとに、次の手順を実行します。

  1. ユーザーに、必要なネットワーク・データ・モデル表へのSELECTアクセス権が付与されていることを確認します。このアクセス権がユーザーに付与されていない場合は、ネットワーク所有者として接続し、アクセス権を付与します。たとえば、User1として接続し、次の文を実行します。

    GRANT select ON network1_node$ TO user2;
    GRANT select ON network1_link$ TO user2;
    GRANT select ON network1_path$ TO user2;
    GRANT select ON network1_plink$ TO user2;
    
  2. 所有者以外のユーザーとして接続します。たとえば、User2として接続します。

  3. USER_SDO_NETWORK_METADATAビュー(5.10.1項を参照)におけるネットワークについて、ネットワーク所有者のスキーマ名を使用してネットワーク・データ・モデル表を修飾します。たとえば、ネットワークがこのビューにまだ定義されていない場合は、User2としての接続中に次を実行します。

    INSERT INTO user_sdo_network_metadata 
      (network, network_category, geometry_type, 
       node_table_name,node_geom_column,
       link_table_name, link_geom_column, link_direction,
       path_table_name, path_geom_column,
       path_link_table_name)
    VALUES
      ('NETWORK1','SPATIAL', 'SDO_GEOMETRY',
       'USER1.NETWORK1_NODE$', 'GEOMETRY',
       'USER1.NETWORK1_LINK$', 'GEOMETRY', 'DIRECTED',
       'USER1.NETWORK1_PATH$', 'GEOMETRY',
       'USER1.NETWORK1_PLINK$');
    

    ネットワークがこのビューにすでに定義されている場合は、定義を更新して、各表名をスキーマ名で修飾します。次に例を示します。

    UPDATE USER_SDO_NETWORK_METADATA
      SET node_table_name = 'USER1.NETWORK1_NODE$',
          link_table_name = 'USER1.NETWORK1_LINK$',
          path_table_name = 'USER1.NETWORK1_PATH$',
          path_link_table_name = 'USER1.NETWORK1_PLINK$'
      WHERE network = 'NETWORK1';
    

このシナリオでは、これでUser2がNETWORK1をメモリーに読み込めるようになります。

5.12.2 複数のスキーマが関係している場合のビューを使用したアクセス

(適切な権限のある)所有者以外のユーザーがネットワークまたはネットワークの特定の部分にアクセスできるように、ビューを作成します。ネットワークへのアクセスを許可する所有者以外のユーザーごとに、次の手順を実行します。

  1. ユーザーに、必要なネットワーク・データ・モデル表へのSELECTアクセス権が付与されていることを確認します。このアクセス権がユーザーに付与されていない場合は、ネットワーク所有者として接続し、アクセス権を付与します。たとえば、User1として接続し、次の文を実行します。

    GRANT select ON network1_node$ TO user2;
    GRANT select ON network1_link$ TO user2;
    GRANT select ON network1_path$ TO user2;
    GRANT select ON network1_plink$ TO user2;
    
  2. 所有者以外のユーザーとして接続します。たとえば、User2として接続します。

  3. 必要な各ネットワーク・データ・モデル・ノードに対するビューを作成し、各ビューでは対応する表の列をすべて選択するようにします。表名をネットワーク所有者のスキーマ名で修飾します。たとえば、User2としての接続中に次のようにします。

    CREATE VIEW network1_node$ AS select * from user1.network1_node$;
    CREATE VIEW network1_link$ AS select * from user1.network1_link$;
    CREATE VIEW network1_path$ AS select * from user1.network1_path$;
    CREATE VIEW network1_plink$ AS select * from user1.network1_plink$;
    

    注意:

    この例では、基礎となる表のすべてのデータを含むビューを示していますが、各ビューの定義でWHERE句(WHERE STATE_CODE='NY'など)を使用することで、ネットワークの使用可能な部分を制限できます。

  4. 新しく作成したビューを指定する行をUSER_SDO_NETWORK_METADATAビュー(5.10.1項を参照)に追加します。たとえば、User2としての接続中に次のようにします。

    INSERT INTO user_sdo_network_metadata 
      (network, network_category, geometry_type, 
       node_table_name,node_geom_column,
       link_table_name, link_geom_column, link_direction,
       path_table_name, path_geom_column,
       path_link_table_name)
    VALUES
      ('NETWORK1','SPATIAL', 'SDO_GEOMETRY',
       'NETWORK1_NODE$', 'GEOMETRY',
       'NETWORK1_LINK$', 'GEOMETRY', 'DIRECTED',
       'NETWORK1_PATH$', 'GEOMETRY',
       'NETWORK1_PLINK$');
    

このシナリオでは、これでUser2が作成されたビューを介してNETWORK1の使用可能な部分をメモリーに読み込めるようになります。

5.13 ネットワークの例

この項では、複数のネットワーク・データ・モデルの例を示します。ほとんどは簡単な例です。すべての例でPL/SQL APIを使用し、一部の例では他のAPIも使用しています。この項の内容は次のとおりです。

この項の例では、この章で説明した概念を示しています。また、第6章に示すPL/SQLのファンクションおよびプロシージャを使用しています。

5.13.1 単純な空間(SDO)ネットワークの例(PL/SQL)

この項では、3つのノードおよび各ノード間のリンクが含まれる非常に単純な空間(SDO、非LRS)ネットワークの例を示します。図5-4に、このネットワークを示します。

図5-4 単純な空間(SDO)ネットワーク

図5-4の説明が続きます。
図5-4「単純な空間(SDO)ネットワーク」の説明

図5-4に示すとおり、ノードN1は点1,1、ノードN2は点15,1、ノードN3は点9,4に存在します。リンクL1はノードN1とノードN2を結ぶ直線、リンクL2はノードN2とノードN3を結ぶ直線、リンクL3はノードN3とノードN1を結ぶ直線です。リンクにはその他のノードまたは形状点は含まれません。

例5-2では、次の処理を行います。

  • SDO_NET.CREATE_SDO_NETWORKプロシージャのコール時に、SDO_NET1有向ネットワークを作成し、SDO_NET1_NODE$、SDO_NET1_LINK$、SDO_NET1_PATH$およびSDO_NET1_PLINK$の各表を作成して、xxx_SDO_NETWORK_METADATAビューを更新します。すべてのジオメトリ列は、GEOMETRYという名前になります。ノード表とリンク表の両方に、COSTという名前のコスト列が含まれます。

  • ノード表、リンク表、パス表およびパスリンク表を移入します。これによって、ノード表に3つの行、リンク表に3つの行、パス表に2つの行、パスリンク表に4つの行が挿入されます。

  • Oracle Spatialメタデータを更新し、ノード表およびリンク表のGEOMETRY列に空間索引を作成します。(このアクションは、ネットワーク管理には直接関係ありませんが、アプリケーションでこれらのジオメトリ列の空間索引を利用する場合に必要です。)

例5-2には、SDO_NETのファンクションおよびプロシージャの使用が多くは示されていません。これらについては、5.13.3項例5-4を参照してください。

例5-2 単純な空間(SDO)ネットワークの例(PL/SQL)

-- Create the SDO_NET1 directed network. Also creates the SDO_NET1_NODE$, 
-- SDO_NET1_LINK$, SDO_NET1_PATH$, SDO_NET1_PLINK$ tables, and updates 
-- USER_SDO_NETWORK_METADATA. All geometry columns are named GEOMETRY. 
-- Both the node and link tables contain a cost column named COST. 
EXECUTE SDO_NET.CREATE_SDO_NETWORK('SDO_NET1', 1, TRUE, TRUE);
 
-- Populate the SDO_NET1_NODE$ table.
-- N1
INSERT INTO sdo_net1_node$ (node_id, node_name, active, geometry, cost)
  VALUES(1, 'N1', 'Y',
    SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(1,1,NULL), NULL, NULL),
    5);
-- N2
INSERT INTO sdo_net1_node$ (node_id, node_name, active, geometry, cost)
  VALUES(2, 'N2', 'Y',
    SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(15,1,NULL), NULL, NULL),
    8);
-- N3
INSERT INTO sdo_net1_node$ (node_id, node_name, active, geometry, cost)
  VALUES(3, 'N3', 'Y',
    SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(9,4,NULL), NULL, NULL),
    4);
 
-- Populate the SDO_NET1_LINK$ table.
-- L1
INSERT INTO sdo_net1_link$ (link_id, link_name, start_node_id, end_node_id,
     active, geometry, cost, bidirected)
  VALUES(1, 'L1', 1, 2, 'Y',
    SDO_GEOMETRY(2002, NULL, NULL, 
      SDO_ELEM_INFO_ARRAY(1,2,1), 
        SDO_ORDINATE_ARRAY(1,1, 15,1)),
    14, 'Y');
-- L2
INSERT INTO sdo_net1_link$ (link_id, link_name, start_node_id, end_node_id,
     active, geometry, cost, bidirected)
   VALUES(2, 'L2', 2, 3, 'Y',
    SDO_GEOMETRY(2002, NULL, NULL, 
      SDO_ELEM_INFO_ARRAY(1,2,1), 
        SDO_ORDINATE_ARRAY(15,1, 9,4)),
    10, 'Y');
-- L3
INSERT INTO sdo_net1_link$ (link_id, link_name, start_node_id, end_node_id,
     active, geometry, cost, bidirected)
  VALUES(3, 'L3', 3, 1, 'Y',
    SDO_GEOMETRY(2002, NULL, NULL, 
      SDO_ELEM_INFO_ARRAY(1,2,1), 
        SDO_ORDINATE_ARRAY(9,4, 1,1)),
    10, 'Y');
 
-- Do not populate the SDO_NET1_PATH$ and SDO_NET1_PLINK$ tables now.
-- Do this only when you need to create any paths.
 
---------------------------------------------------------------------------
-- REMAINING STEPS NEEDED TO USE SPATIAL INDEXES --
---------------------------------------------------------------------------
-- Update the USER_SDO_GEOM_METADATA view. This is required before the
-- spatial index can be created. Do this only once for each layer
-- (that is, table-column combination).

INSERT INTO user_sdo_geom_metadata
    (TABLE_NAME,
     COLUMN_NAME,
     DIMINFO,
     SRID)
  VALUES (
    'SDO_NET1_NODE$',
    'GEOMETRY',
    SDO_DIM_ARRAY(   -- 20X20 grid
      SDO_DIM_ELEMENT('X', 0, 20, 0.005),
      SDO_DIM_ELEMENT('Y', 0, 20, 0.005)
       ),
    NULL   -- SRID (spatial reference system, also called coordinate system)
  );
INSERT INTO user_sdo_geom_metadata
    (TABLE_NAME,
     COLUMN_NAME,
     DIMINFO,
     SRID)
  VALUES (
    'SDO_NET1_LINK$',
    'GEOMETRY',
    SDO_DIM_ARRAY(   -- 20X20 grid
      SDO_DIM_ELEMENT('X', 0, 20, 0.005),
      SDO_DIM_ELEMENT('Y', 0, 20, 0.005)
       ),
    NULL   -- SRID (spatial reference system, also called coordinate system)
  );
 
-- Create the spatial indexes
CREATE INDEX sdo_net1_nodes_idx ON sdo_net1_node$(geometry)
  INDEXTYPE IS MDSYS.SPATIAL_INDEX;
CREATE INDEX sdo_net1_links_idx ON sdo_net1_link$(geometry)
  INDEXTYPE IS MDSYS.SPATIAL_INDEX;

5.13.2 単純な論理ネットワークの例(PL/SQL)

この項では、3つのノードおよびノード間のリンクが含まれる非常に単純な論理ネットワークの例を示します。図5-5に、このネットワークを示します。

図5-5 単純な論理ネットワーク

図5-5の説明が続きます。
図5-5「単純な論理ネットワーク」の説明

図5-5に示すとおり、リンクL1はノードN1とノードN2を結ぶ直線、リンクL2はノードN2とノードN3を結ぶ直線、リンクL3はノードN3とノードN1を結ぶ直線です。リンクにはその他のノードは含まれません。

例5-3では、SDO_NET.CREATE_LOGICAL_NETWORKプロシージャをコールし、これによって、LOG_NET1有向ネットワークの作成、LOG_NET1_NODE$、LOG_NET1_LINK$、LOG_NET1_PATH$およびLOG_NET1_PLINK$の各表の作成、およびxxx_SDO_NETWORK_METADATAビューの更新が行われます。ノード表とリンク表の両方に、COSTという名前のコスト列が含まれます。(これは論理ネットワークであるため、ジオメトリ列は含まれません。)この例では、ノード表およびリンク表の移入も行われます。

例5-3には、SDO_NETのファンクションおよびプロシージャの使用が多くは示されていません。これらについては、5.13.4項の論理階層ネットワークの例(例5-5)を参照してください。

例5-3 単純な論理ネットワークの例(PL/SQL)

-- Creates the LOG_NET1 directed logical network. Also creates the
-- LOG_NET1_NODE$, LOG_NET1_LINK$, LOG_NET1_PATH$,
-- and LOG_NET1_PLINK$ tables, and updates USER_SDO_NETWORK_METADATA.
-- Both the node and link tables contain a cost column named COST. 
EXECUTE SDO_NET.CREATE_LOGICAL_NETWORK('LOG_NET1', 1, TRUE, TRUE);
 
-- Populate the LOG_NET1_NODE$ table.
-- N1
INSERT INTO log_net1_node$ (node_id, node_name, active, cost)
  VALUES (1, 'N1', 'Y', 2);
-- N2
INSERT INTO log_net1_node$ (node_id, node_name, active, cost)
  VALUES (2, 'N2', 'Y', 3);
-- N3
INSERT INTO log_net1_node$ (node_id, node_name, active, cost)
  VALUES (3, 'N3', 'Y', 2);
 
-- Populate the LOG_NET1_LINK$ table.
-- L1
INSERT INTO log_net1_link$ (link_id, link_name, start_node_id, end_node_id,
     active, link_level, cost)
  VALUES (1, 'L1', 1, 2, 'Y', 1, 10);
-- L2
INSERT INTO log_net1_link$ (link_id, link_name, start_node_id, end_node_id,
     active, link_level, cost)
  VALUES (2, 'L2', 2, 3, 'Y', 1, 7);
-- L3
INSERT INTO log_net1_link$ (link_id, link_name, start_node_id, end_node_id,
     active, link_level, cost)
  VALUES (3, 'L3', 3, 1, 'Y', 1, 8);
 
-- Do not populate the LOG_NET1_PATH$ and LOG_NET1_PLINK$ tables now.
-- Do this only when you need to create any paths.

5.13.3 空間(LRS)ネットワークの例(PL/SQL)

この項では、図5-6に示す道路(ルート)を使用する空間(LRS)ネットワークの例を示します。それぞれの道路は、1つ以上の道路セグメント・ジオメトリ(図を参照)から抜き出された、(リンクに関連付けられた)個々の線セグメントで作成されています。

図5-6 空間(LRS)ネットワークの道路および道路セグメントの例

図5-6の説明が続きます。
図5-6「空間(LRS)ネットワークの道路および道路セグメントの例」の説明

次に、図5-6について説明します。

  • Route1は、点2,2から開始し、点5,14で終了します。このルートには、N1N2N3N4N5N6およびN7の各ノードが含まれます。このルートには、R1L1R1L2R1L3R1L4R1L5およびR1L6の各リンクが含まれます。

  • Route2は、点8,4から開始し、点8,13で終了します。これには、N3N6およびN8の各ノードが含まれます。これには、R2L1およびR2L2の各リンクが含まれます。

  • Route3は、点12,10から開始し、点5,14で終了します。これには、N5N8およびN7の各ノードが含まれます。これには、R3L1およびR3L2の各リンクが含まれます。

  • 図の右側には、4つの道路セグメント・ジオメトリが個別に示されています。(各セグメント上の点には、対応するノード名がラベル付けされ、各セグメント・ジオメトリが、左側の図のどの部分に相当するかわかりやすくなっています。)

例5-4では、次の処理を行います。

  • 道路セグメント・ジオメトリを格納する表を作成します。

  • 4つの道路セグメント・ジオメトリを表に挿入します。

  • USER_SDO_GEOM_METADATAビューに空間メタデータを挿入します。

  • ROAD_SEGMENTS表のジオメトリ列に空間索引を作成します。

  • ノード表を作成および移入します。

  • リンク表を作成および移入します。

  • 将来使用する場合に備えて、パス表およびパスリンク表を作成および移入します。(アプリケーションでパスを使用できるようにするには、これらの2つの表を移入する必要があります。)

  • USER_SDO_NETWORK_METADATAビューにネットワーク・メタデータを挿入します。

  • SDO_NETとSDO_NET_MEMの様々なファンクションおよびプロシージャを使用します。

例5-4 空間(LRS)ネットワークの例(PL/SQL)

---------------------------------------------------------------------------
-- CREATE AND POPULATE TABLE --
---------------------------------------------------------------------------
-- Create a table for road segments. Use LRS.
CREATE TABLE road_segments (
  segment_id  NUMBER PRIMARY KEY,
  segment_name  VARCHAR2(32),
  segment_geom  SDO_GEOMETRY, 
  geom_id NUMBER);
 
-- Populate the table with road segments.
INSERT INTO road_segments VALUES(
  1,
  'Segment1',
  SDO_GEOMETRY(
    3302,  -- line string, 3 dimensions (X,Y,M), 3rd is measure dimension
    NULL,
    NULL,
    SDO_ELEM_INFO_ARRAY(1,2,1), -- one line string, straight segments
    SDO_ORDINATE_ARRAY(
      2,2,0,   -- Starting point - Node1; 0 is measure from start.
      2,4,2,   -- Node2; 2 is measure from start. 
      8,4,8,   -- Node3; 8 is measure from start. 
      12,4,12) -- Node4; 12 is measure from start. 
  ), 1001
);
 
INSERT INTO road_segments VALUES(
  2,
  'Segment2',
  SDO_GEOMETRY(
    3302,  -- line string, 3 dimensions (X,Y,M), 3rd is measure dimension
    NULL,
    NULL,
    SDO_ELEM_INFO_ARRAY(1,2,1), -- one line string, straight segments
    SDO_ORDINATE_ARRAY(
      8,4,0,   -- Node3; 0 is measure from start. 
      8,10,6,  -- Node6; 6 is measure from start. 
      8,13,9)  -- Ending point - Node8; 9 is measure from start.
  ), 1002
);
 
INSERT INTO road_segments VALUES(
  3,
  'Segment3',
  SDO_GEOMETRY(
    3302,  -- line string, 3 dimensions (X,Y,M), 3rd is measure dimension
    NULL,
    NULL,
    SDO_ELEM_INFO_ARRAY(1,2,1), -- one line string, straight segments
    SDO_ORDINATE_ARRAY(
      12,4,0,     -- Node4; 0 is measure from start.
      12,10,6,    -- Node5; 6 is measure from start. 
      8,13,11,    -- Node8; 11 is measure from start. 
      5,14,14.16) -- Ending point - Node7; 14.16 is measure from start.
  ), 1003
);
 
INSERT INTO road_segments VALUES(
  4,
  'Segment4',
  SDO_GEOMETRY(
    3302,  -- line string, 3 dimensions (X,Y,M), 3rd is measure dimension
    NULL,
    NULL,
    SDO_ELEM_INFO_ARRAY(1,2,1), -- one line string, straight segments
    SDO_ORDINATE_ARRAY(
      12,10,0, -- Node5; 0 is measure from start.
      8,10,4,  -- Node6; 4 is measure from start.  
      5,14,9)  -- Ending point - Node7; 9 is measure from start.
  ), 1004
);
 
---------------------------------------------------------------------------
-- UPDATE THE SPATIAL METADATA --
---------------------------------------------------------------------------
-- Update the USER_SDO_GEOM_METADATA view. This is required before the
-- spatial index can be created. Do this only once for each layer
-- (that is, table-column combination; here: road_segment and segment_geom).
INSERT INTO user_sdo_geom_metadata
    (TABLE_NAME,
     COLUMN_NAME,
     DIMINFO,
     SRID)
  VALUES (
  'ROAD_SEGMENTS',
  'SEGMENT_GEOM',
  SDO_DIM_ARRAY(   -- 20X20 grid
    SDO_DIM_ELEMENT('X', 0, 20, 0.005),
    SDO_DIM_ELEMENT('Y', 0, 20, 0.005),
    SDO_DIM_ELEMENT('M', 0, 20, 0.005) -- Measure dimension
     ),
  NULL   -- SRID (spatial reference system, also called coordinate system)
);
 
-------------------------------------------------------------------
-- CREATE THE SPATIAL INDEX --
-------------------------------------------------------------------
CREATE INDEX road_segments_idx ON road_segments(segment_geom)
  INDEXTYPE IS MDSYS.SPATIAL_INDEX;
  
--------------------------------
-- USE SDO_NET SUBPROGRAMS
--------------------------------
 
-- This procedure does not use the CREATE_LRS_NETWORK procedure. Instead,
-- the user creates the network tables and populates the network metadata view.
-- Basic steps:
-- 1. Create and populate the node table.
-- 2. Create and populate the link table.
-- 3. Create the path table and paths and links table (for possible 
--    future use, before which they will need to be populated).
-- 4. Populate the network metadata (USER_SDO_NETWORK_METADATA).
--    Note: Can be done before or after Steps 1-3.
-- 5. Use various SDO_NET functions and procedures.
-- 6. Use SDO_NET_MEM functions and procedures for analysis and editing.
 
-- 1. Create and populate the node table.
EXECUTE SDO_NET.CREATE_NODE_TABLE('ROADS_NODES', 'LRS_GEOMETRY', 'NODE_GEOMETRY', 'COST', 1);
 
-- Populate the node table.
 
-- N1
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure) 
  VALUES (1, 'N1', 'Y', 1001, 0);
 
-- N2
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (2, 'N2', 'Y', 1001, 2);
 
-- N3
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (3, 'N3', 'Y', 1001, 8);
 
-- N4
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (4, 'N4', 'Y', 1001, 12);
 
-- N5
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (5, 'N5', 'Y', 1004, 0);
 
-- N6
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (6, 'N6', 'Y', 1002, 6);
 
-- N7
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (7, 'N7', 'Y', 1004, 9);
 
-- N8
INSERT INTO roads_nodes (node_id, node_name, active, geom_id, measure)
  VALUES (8, 'N8', 'Y', 1002, 9);
 
-- 2. Create and populate the link table.
EXECUTE SDO_NET.CREATE_LINK_TABLE('ROADS_LINKS', 'LRS_GEOMETRY', 'LINK_GEOMETRY', 'COST', 1);
 
-- Populate the link table.
 
-- Route1, Link1
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active, 
   cost, geom_id, start_measure, end_measure)
VALUES (101, 'R1L1', 1, 2, 'Y', 3, 1001, 0, 2);
 
-- Route1, Link2
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active, 
   cost, geom_id, start_measure, end_measure)
VALUES (102, 'R1L2', 2, 3, 'Y', 15, 1001, 2, 8);
 
 -- Route1, Link3
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (103, 'R1L3', 3, 4, 'Y', 10, 1001, 8, 12);
 
-- Route1, Link4
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (104, 'R1L4', 4, 5, 'Y', 15, 1003, 0, 6);
 
-- Route1, Link5
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (105, 'R1L5', 5, 6, 'Y', 10, 1004, 0, 4);
 
-- Route1, Link6
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (106, 'R1L6', 6, 7, 'Y', 7, 1004, 4, 9);
 
-- Route2, Link1 (cost = 30, a slow drive)
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (201, 'R2L1', 3, 6, 'Y', 30, 1002, 0, 6);
 
-- Route2, Link2
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (202, 'R2L2', 6, 8, 'Y', 5, 1002, 6, 9);
 
-- Route3, Link1
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (301, 'R3L1', 5, 8, 'Y', 5, 1003, 6, 11);
 
-- Route3, Link2
INSERT INTO roads_links (link_id, link_name, start_node_id, end_node_id, active,
   cost, geom_id, start_measure, end_measure)
VALUES (302, 'R3L2', 8, 7, 'Y', 5, 1003, 11, 14.16);
 
-- 3. Create the path table (to store created paths) and the path-link 
--    table (to store links for each path) for possible future use,
--    before which they will need to be populated.
EXECUTE SDO_NET.CREATE_PATH_TABLE('ROADS_PATHS', 'PATH_GEOMETRY');
EXECUTE SDO_NET.CREATE_PATH_LINK_TABLE('ROADS_PATHS_LINKS');
 
-- 4. Populate the network metadata (USER_SDO_NETWORK_METADATA).
 
INSERT INTO user_sdo_network_metadata 
    (NETWORK,
     NETWORK_CATEGORY,
     GEOMETRY_TYPE,
     NETWORK_TYPE,
     NO_OF_HIERARCHY_LEVELS,
     NO_OF_PARTITIONS,
     LRS_TABLE_NAME,
     LRS_GEOM_COLUMN,
     NODE_TABLE_NAME,
     NODE_GEOM_COLUMN,
     NODE_COST_COLUMN,
     LINK_TABLE_NAME,
     LINK_GEOM_COLUMN,
     LINK_DIRECTION,
     LINK_COST_COLUMN,
     PATH_TABLE_NAME,
     PATH_GEOM_COLUMN,
     PATH_LINK_TABLE_NAME)
  VALUES (
    'ROADS_NETWORK',  -- Network name
    'SPATIAL',  -- Network category
    'LRS_GEOMETRY',  -- Geometry type
    'Roadways',  -- Network type (user-defined)
    1,  -- No. of levels in hierarchy
    1,  -- No. of partitions
    'ROAD_SEGMENTS',   -- LRS table name
    'SEGMENT_GEOM' ,  -- LRS geometry column
    'ROADS_NODES',  -- Node table name
    'NODE_GEOMETRY',  -- Node geometry column
    'COST',  -- Node cost column
    'ROADS_LINKS',  -- Link table name
    'LINK_GEOMETRY',  -- Link geometry column
    'DIRECTED',  -- Link direction
    'COST',  -- Link cost column
    'ROADS_PATHS',  -- Path table name
    'PATH_GEOMETRY',  -- Path geometry column
    'ROADS_PATHS_LINKS'  -- Paths and links table
    );
 
-- 5. Use various SDO_NET functions and procedures.
 
-- Validate the network.
SELECT SDO_NET.VALIDATE_NETWORK('ROADS_NETWORK') FROM DUAL;
 
-- Validate parts or aspects of the network.
SELECT SDO_NET.VALIDATE_LINK_SCHEMA('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.VALIDATE_LRS_SCHEMA('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.VALIDATE_NODE_SCHEMA('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.VALIDATE_PATH_SCHEMA('ROADS_NETWORK') FROM DUAL;
 
-- Retrieve various information (GET_xxx and some other functions).
SELECT SDO_NET.GET_CHILD_LINKS('ROADS_NETWORK', 101) FROM DUAL;
SELECT SDO_NET.GET_CHILD_NODES('ROADS_NETWORK', 1) FROM DUAL;
SELECT SDO_NET.GET_GEOMETRY_TYPE('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_IN_LINKS('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_INVALID_LINKS('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_INVALID_NODES('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_INVALID_PATHS('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_ISOLATED_NODES('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LINK_COST_COLUMN('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LINK_DIRECTION('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LINK_GEOM_COLUMN('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LINK_GEOMETRY('ROADS_NETWORK', 103) FROM DUAL;
SELECT SDO_NET.GET_LINK_TABLE_NAME('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LRS_GEOM_COLUMN('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LRS_LINK_GEOMETRY('ROADS_NETWORK', 103) FROM DUAL;
SELECT SDO_NET.GET_LRS_NODE_GEOMETRY('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_LRS_TABLE_NAME('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NETWORK_CATEGORY('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NETWORK_ID('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NETWORK_NAME(3) FROM DUAL;
SELECT SDO_NET.GET_NETWORK_TYPE('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NO_OF_HIERARCHY_LEVELS('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NO_OF_LINKS('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NO_OF_NODES('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NODE_DEGREE('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_NODE_GEOM_COLUMN('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NODE_GEOMETRY('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_NODE_IN_DEGREE('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_NODE_OUT_DEGREE('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_NODE_TABLE_NAME('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NODE_COST_COLUMN('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NODE_HIERARCHY_LEVEL('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_OUT_LINKS('ROADS_NETWORK', 3) FROM DUAL;
SELECT SDO_NET.GET_PATH_GEOM_COLUMN('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_PATH_TABLE_NAME('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_COMPLEX('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_HIERARCHICAL('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_LOGICAL('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_SIMPLE('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_SPATIAL('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.LRS_GEOMETRY_NETWORK('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.NETWORK_EXISTS('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.SDO_GEOMETRY_NETWORK('ROADS_NETWORK') FROM DUAL;
SELECT SDO_NET.TOPO_GEOMETRY_NETWORK('ROADS_NETWORK') FROM DUAL;
 
-- Copy a network.
EXECUTE SDO_NET.COPY_NETWORK('ROADS_NETWORK', 'ROADS_NETWORK2');
 
-- Create a trigger.
EXECUTE SDO_NET.CREATE_DELETE_TRIGGER('ROADS_NETWORK');
 
-- 6. Use SDO_NET_MEM functions and procedures for analysis and editing.
 
-- Network analysis and other operations (SDO_NET_MEM.NETWORK_MANAGER)
 
DECLARE
  net_mem    VARCHAR2(100);
  res_string VARCHAR2(1000);
 
  cost        NUMBER;
  res_numeric NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
  indx1        NUMBER;
  var1_numeric NUMBER;
  var1_array   SDO_NUMBER_ARRAY;
 
BEGIN
 
net_mem := 'ROADS_NETWORK';
  
-- Read in the network.
SDO_NET_MEM.NETWORK_MANAGER.READ_NETWORK(net_mem, 'TRUE');
 
-- Validate the network.
res_string := SDO_NET_MEM.NETWORK_MANAGER.VALIDATE_NETWORK_SCHEMA(net_mem);
DBMS_OUTPUT.PUT_LINE('Is network ' || net_mem || ' valid? ' || res_string);
  
res_string := SDO_NET_MEM.NETWORK_MANAGER.LIST_NETWORKS;
DBMS_OUTPUT.PUT_LINE('The current in-memory network(s) is/are: ' || res_string);
 
res_numeric := SDO_NET_MEM.NETWORK_MANAGER.FIND_CONNECTED_COMPONENTS(net_mem);
DBMS_OUTPUT.PUT_LINE('The number of connected components is: ' || res_numeric);
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.MCST_LINK(net_mem);
DBMS_OUTPUT.PUT('Network ' || net_mem || ' has the following MCST links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.FIND_REACHABLE_NODES(net_mem,1);
DBMS_OUTPUT.PUT_LINE('Reachable nodes from 1: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.NEAREST_NEIGHBORS(net_mem,6,3);
DBMS_OUTPUT.PUT_LINE('Path IDs to the nearest 3 neighbors of node 6 are: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ', which contains links: ');
  var1_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, res_numeric);
    FOR indx1 IN var1_array.FIRST..var1_array.LAST
    LOOP
      var1_numeric := var1_array(indx1);
      DBMS_OUTPUT.PUT(var1_numeric || ' ');
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); 
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.NEAREST_NEIGHBORS(net_mem,6,3);
DBMS_OUTPUT.PUT_LINE('Path IDs to the nearest 3 neighbors of node 6 are: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ', whose end node is: ');
  var1_numeric := SDO_NET_MEM.PATH.GET_END_NODE_ID(net_mem, res_numeric);
  DBMS_OUTPUT.PUT(var1_numeric);
  DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); 
  
res_string := SDO_NET_MEM.NETWORK_MANAGER.IS_REACHABLE(net_mem,1,5);
DBMS_OUTPUT.PUT_LINE('Can node 1 reach node 5? ' || res_string);
  
res_array := SDO_NET_MEM.NETWORK_MANAGER.ALL_PATHS(net_mem,1,5,10,200,5);
DBMS_OUTPUT.PUT_LINE('For each path from node 1 to node 5: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric ||
                       ' has the following properties: ');
  cost := SDO_NET_MEM.PATH.GET_COST(net_mem, res_numeric);
  DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric || ' cost: ' || cost);
  res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, res_array(indx));  
  DBMS_OUTPUT.PUT_LINE('Is path ' || res_numeric || ' closed? ' || res_string);       
END LOOP;
   
DBMS_OUTPUT.PUT_LINE(' ');
res_numeric := SDO_NET_MEM.NETWORK_MANAGER.SHORTEST_PATH(net_mem,1,5);
DBMS_OUTPUT.PUT_LINE('The shortest path from node 1 to node 5 is path ID: ' || res_numeric);
 
DBMS_OUTPUT.PUT_LINE('The following are characteristics of this shortest path: ');
cost := SDO_NET_MEM.PATH.GET_COST(net_mem, res_numeric);
DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric || ' has cost: ' || cost);
res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, res_numeric);  
DBMS_OUTPUT.PUT_LINE('Is path ' || res_numeric || ' closed? ' || res_string);  
 
DBMS_OUTPUT.PUT_LINE(' ');
res_numeric := SDO_NET_MEM.NETWORK_MANAGER.SHORTEST_PATH_DIJKSTRA(net_mem,1,5);
DBMS_OUTPUT.PUT_LINE('The shortest Dijkstra path from node 1 to node 5 is ' || res_numeric);
 
DBMS_OUTPUT.PUT_LINE('The following are characteristics of this shortest path: ');
cost := SDO_NET_MEM.PATH.GET_COST(net_mem, res_numeric);
DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric || ' cost: ' || cost);
res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, res_numeric);  
DBMS_OUTPUT.PUT_LINE('Is path ' || res_numeric || ' closed? ' || res_string);  
    
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, res_numeric);   
DBMS_OUTPUT.PUT('Path ' || res_numeric || ' has links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
  
res_array := SDO_NET_MEM.PATH.GET_NODE_IDS(net_mem, res_numeric);   
DBMS_OUTPUT.PUT('Path ' || res_numeric || ' has nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.WITHIN_COST(net_mem,2,20);
DBMS_OUTPUT.PUT('Path IDs to nodes within cost of 40 from node 2: ');
DBMS_OUTPUT.PUT_LINE(' ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ', whose end node is: ');
  var1_numeric := SDO_NET_MEM.PATH.GET_END_NODE_ID(net_mem, res_numeric);
  DBMS_OUTPUT.PUT(var1_numeric);
  DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); 
 
END;  
/
 
-- Link editing (SDO_NET_MEM.LINK)
 
DECLARE
  net_mem     VARCHAR2(32);
  res_string  VARCHAR2(100);
  res_numeric NUMBER;
  res_geom    SDO_GEOMETRY;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN
 
net_mem := 'ROADS_NETWORK';
  
-- GET_COST
res_numeric := SDO_NET_MEM.LINK.GET_COST(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The cost of link 104 is: ' || res_numeric);
 
-- GET_END_MEASURE
res_numeric := SDO_NET_MEM.LINK.GET_END_MEASURE(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The end measure of link 104 is: ' || res_numeric);
 
-- GET_END_NODE_ID
res_numeric := SDO_NET_MEM.LINK.GET_END_NODE_ID(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The end node of link 104 is: ' || res_numeric);
 
-- GET_GEOM_ID
res_numeric := SDO_NET_MEM.LINK.GET_GEOM_ID(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The geometry ID of link 104 is: ' || res_numeric);
 
-- GET_GEOMETRY
res_geom := SDO_NET_MEM.LINK.GET_GEOMETRY(net_mem, 104);
 
-- GET_NAME
res_string := SDO_NET_MEM.LINK.GET_NAME(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The name of link 104 is: ' || res_string);
 
-- GET_START_MEASURE
res_numeric := SDO_NET_MEM.LINK.GET_START_MEASURE(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The start measure of link 104 is: ' || res_numeric);
 
-- GET_START_NODE_ID
res_numeric := SDO_NET_MEM.LINK.GET_START_NODE_ID(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The start node of link 104 is: ' || res_numeric);
 
-- GET_STATE
res_string := SDO_NET_MEM.LINK.GET_STATE(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('The state of link 104 is: ' || res_string);
 
-- IS_ACTIVE
res_string := SDO_NET_MEM.LINK.IS_ACTIVE(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('Is link 104 active?: ' || res_string);
 
-- IS_LOGICAL
res_string := SDO_NET_MEM.LINK.IS_LOGICAL(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('Is link 104 a logical link?: ' || res_string);
 
-- IS_TEMPORARY
res_string := SDO_NET_MEM.LINK.IS_TEMPORARY(net_mem, 104);
DBMS_OUTPUT.PUT_LINE('Is link 104 temporary?: ' || res_string);
 
-- SET_COST
-- Set the cost of link 302 to 6.
SDO_NET_MEM.LINK.SET_COST(net_mem, 302, 6);
 
-- SET_MEASURE
-- Set the measure value of link 302 as from 111 to 114.16.
SDO_NET_MEM.LINK.SET_MEASURE(net_mem, 302, 111, 114.16);
 
-- SET_NAME
-- Set the name of link 302 to 'My favorite link'.
SDO_NET_MEM.LINK.SET_NAME(net_mem, 302, 'My favorite link');
 
-- SET_STATE
-- Set the state of link 302 to 'FALSE'.
SDO_NET_MEM.LINK.SET_STATE(net_mem, 302, 'FALSE');
-- GET_STATE
res_string := SDO_NET_MEM.LINK.GET_STATE(net_mem, 302);
DBMS_OUTPUT.PUT_LINE('The state of link 302 is: ' || res_string);
 
-- SET_TYPE
-- Set the type of link 302 to 'Normal street'.
SDO_NET_MEM.LINK.SET_TYPE(net_mem, 302, 'Normal street');
-- GET_TYPE
res_string := SDO_NET_MEM.LINK.GET_TYPE(net_mem, 302);
DBMS_OUTPUT.PUT_LINE('The type of link 302 is: ' || res_string);
 
END;  
/
 
-- Node editing (SDO_NET_MEM.NODE)
 
DECLARE
  net_mem     VARCHAR2(32);
  res_string  VARCHAR2(100);
  res_numeric NUMBER;
  res_geom    SDO_GEOMETRY;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN
 
net_mem := 'ROADS_NETWORK';
  
-- GET_COMPONENT_NO
res_numeric := SDO_NET_MEM.NODE.GET_COMPONENT_NO(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('The component number of node 3 is: ' || res_numeric);
 
-- GET_COST
res_numeric := SDO_NET_MEM.NODE.GET_COST(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('The cost of node 3 is: ' || res_numeric);
 
-- GET_GEOM_ID
res_numeric := SDO_NET_MEM.NODE.GET_GEOM_ID(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('The geometry ID of node 3 is: ' || res_numeric);
 
-- GET_GEOMETRY
res_geom := SDO_NET_MEM.NODE.GET_GEOMETRY(net_mem, 3);
 
-- GET_IN_LINK_IDS
res_array := SDO_NET_MEM.NODE.GET_IN_LINK_IDS(net_mem, 3);
DBMS_OUTPUT.PUT('Node 3 has the following inbound links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_INCIDENT_LINK_IDS
res_array := SDO_NET_MEM.NODE.GET_INCIDENT_LINK_IDS(net_mem, 3);
DBMS_OUTPUT.PUT('Node 3 has the following incident links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_MEASURE
res_numeric := SDO_NET_MEM.NODE.GET_MEASURE(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('The measure value of node 3 is: ' || res_numeric);
 
-- GET_NAME
res_string := SDO_NET_MEM.NODE.GET_NAME(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('The name of node 3 is: ' || res_string);
 
-- GET_OUT_LINK_IDS
res_array := SDO_NET_MEM.NODE.GET_OUT_LINK_IDS(net_mem, 3);
DBMS_OUTPUT.PUT('Node 3 has the following outbound links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_STATE
res_string := SDO_NET_MEM.NODE.GET_STATE(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('The state of node 3 is: ' || res_string);
 
-- IS_ACTIVE
res_string := SDO_NET_MEM.NODE.IS_ACTIVE(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('Is node 3 active?: ' || res_string);
 
-- IS_LOGICAL
res_string := SDO_NET_MEM.NODE.IS_LOGICAL(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('Is node 3 a logical node?: ' || res_string);
 
-- IS_TEMPORARY
res_string := SDO_NET_MEM.NODE.IS_TEMPORARY(net_mem, 3);
DBMS_OUTPUT.PUT_LINE('Is node 3 temporary?: ' || res_string);
 
-- LINK_EXISTS
res_string := SDO_NET_MEM.NODE.LINK_EXISTS(net_mem, 3, 4);
DBMS_OUTPUT.PUT_LINE('Does a link exist between nodes 3 and 4?: ' || res_string);
 
-- MAKE_TEMPORARY
-- Make node 7 temporary.
SDO_NET_MEM.NODE.MAKE_TEMPORARY(net_mem, 7);
 
-- SET_COMPONENT_NO
-- Set the component number of node 7 to 987.
SDO_NET_MEM.NODE.SET_COMPONENT_NO(net_mem, 7, 987);
 
-- SET_COST
-- Set the cost of node 7 to 40.
SDO_NET_MEM.NODE.SET_COST(net_mem, 7, 40);
 
-- SET_GEOM_ID
-- Set the geometry ID of node 7 to 99.
SDO_NET_MEM.NODE.SET_GEOM_ID(net_mem, 7, 99);
 
-- SET_MEASURE
-- Set the measure value of node 7 to 30.
SDO_NET_MEM.NODE.SET_MEASURE(net_mem, 7, 30);
 
-- SET_NAME
-- Set the name of node 7 to 'My favorite node'.
SDO_NET_MEM.NODE.SET_NAME(net_mem, 7, 'My favorite node');
-- GET_NAME
res_string := SDO_NET_MEM.NODE.GET_NAME(net_mem, 7);
DBMS_OUTPUT.PUT_LINE('The name of node 7 is: ' || res_string);
 
-- SET_STATE
-- Set the state of node 7 to 'FALSE'.
SDO_NET_MEM.NODE.SET_STATE(net_mem, 7, 'FALSE');
-- GET_STATE
res_string := SDO_NET_MEM.NODE.GET_STATE(net_mem, 7);
DBMS_OUTPUT.PUT_LINE('The state of node 7 is: ' || res_string);
 
-- SET_TYPE
-- Set the type of node 7 to 'Historic site'.
SDO_NET_MEM.NODE.SET_TYPE(net_mem, 7, 'Historic site');
-- GET_TYPE
res_string := SDO_NET_MEM.NODE.GET_TYPE(net_mem, 7);
DBMS_OUTPUT.PUT_LINE('The type of node 7 is: ' || res_string);
 
END;  
/
 
-- Path editing (SDO_NET_MEM.PATH)
 
DECLARE
  net_mem     VARCHAR2(32);
  res_string  VARCHAR2(100);
  res_numeric NUMBER;
  res_geom    SDO_GEOMETRY;
  path_id     NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN
 
net_mem := 'ROADS_NETWORK';
  
-- Create a path for use with subsequent statements. Here, it is
-- the shortest path between nodes 1 (N1) and 5 (N5).
path_id := SDO_NET_MEM.NETWORK_MANAGER.SHORTEST_PATH(net_mem,1,5);
DBMS_OUTPUT.PUT_LINE('The shortest path between nodes 1 and 5 is: ' || path_id);
 
-- GET_LINK_IDS
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Path ' || path_id || ' has the following links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_COST
res_numeric := SDO_NET_MEM.PATH.GET_COST(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The cost of path ' || path_id || ' is: ' || res_numeric);
 
-- GET_END_NODE_ID
res_numeric := SDO_NET_MEM.PATH.GET_END_NODE_ID(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The end node ID of path ' || path_id || ' is: ' || res_numeric);
 
-- GET_GEOMETRY
res_geom := SDO_NET_MEM.PATH.GET_GEOMETRY(net_mem, path_id);
-- doesn't work DBMS_OUTPUT.PUT_LINE('The geometry of path ' || path_id || ' is: ' || res_geom);
 
-- GET_LINK_IDS
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Path ' || path_id || ' has the following links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_NAME
res_string := SDO_NET_MEM.PATH.GET_NAME(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The name of path ' || path_id || ' is: ' || res_string);
 
-- GET_NO_OF_LINKS
res_numeric := SDO_NET_MEM.PATH.GET_NO_OF_LINKS(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The number of links in path ' || path_id || ' is: ' || res_numeric);
 
-- GET_NODE_IDS
res_array := SDO_NET_MEM.PATH.GET_NODE_IDS(net_mem, path_id);
DBMS_OUTPUT.PUT('Path ' || path_id || ' has the following nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_START_NODE_ID
res_numeric := SDO_NET_MEM.PATH.GET_START_NODE_ID(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The start node ID of path ' || path_id || ' is: ' || res_numeric);
 
-- IS_ACTIVE
res_string := SDO_NET_MEM.PATH.IS_ACTIVE(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' active?: ' || res_string);
 
-- IS_CLOSED
res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' closed?: ' || res_string);
 
-- IS_CONNECTED
res_string := SDO_NET_MEM.PATH.IS_CONNECTED(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' connected?: ' || res_string);
 
-- IS_LOGICAL
res_string := SDO_NET_MEM.PATH.IS_LOGICAL(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' a logical path?: ' || res_string);
 
-- IS_SIMPLE
res_string := SDO_NET_MEM.PATH.IS_SIMPLE(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' a simple path?: ' || res_string);
 
-- IS_TEMPORARY
res_string := SDO_NET_MEM.PATH.IS_TEMPORARY(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' temporary?: ' || res_string);
 
-- SET_NAME
-- Set the name of path to 'My favorite path'.
SDO_NET_MEM.PATH.SET_NAME(net_mem, path_id, 'My favorite path');
-- GET_NAME
res_string := SDO_NET_MEM.PATH.GET_NAME(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The name of path ' || path_id || ' is: ' || res_string);
 
-- SET_TYPE
-- Set the type of the path to 'Scenic'.
SDO_NET_MEM.PATH.SET_TYPE(net_mem, path_id, 'Scenic');
-- GET_TYPE
res_string := SDO_NET_MEM.PATH.GET_TYPE(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The type of path ' || path_id || ' is: ' || res_string);
 
-- SET_PATH_ID
-- Set (change) the path ID of the path to 6789.
SDO_NET_MEM.PATH.SET_PATH_ID(net_mem, path_id, 6789);
 
END;  
/

5.13.4 論理階層ネットワークの例(PL/SQL)

この項では、図5-7に示すノードおよびリンクが含まれる論理ネットワークの例を示します。論理ネットワークであるため、空間ジオメトリは関連付けられません。(図5-7は、基本的に5.5項図5-3と同じですが、ノードおよびリンクがラベル付けされています。)

図5-7 論理ネットワークのノードおよびリンクの例

図5-7の説明が続きます。
図5-7「論理ネットワークのノードおよびリンクの例」の説明

次に、図5-7について説明します。

  • ネットワークは階層ネットワークで、2つのレベルがあります。上位レベル(レベル2)は、2つのノード(HN1HN2)で構成されており、残りのノードおよびリンクは、階層の下位レベル(レベル1)に含まれます。

  • レベル1の各ノードは、レベル2のいずれかのノードの子ノードです。ノードHN1は、子ノードN1N2N3N4N5およびN6を持ちます。ノードHN2は、子ノードN7N8N9N10N11N12N13およびN14を持ちます。

  • 1つのリンク(HN1HN2)がノードHN1およびHN2をリンクし、2つのリンク(N5N8およびN6N7)は、親リンクHN1HN2の子リンクとなります。ただし、リンクは特定のネットワーク階層レベルには関連付けられていません。

例5-5では、次の処理を行います。

  • ノード表を作成および移入します。

  • リンク表を作成および移入します。

  • 将来使用する場合に備えて、パス表およびパスリンク表を作成および移入します。(アプリケーションでパスを使用できるようにするには、これらの2つの表を移入する必要があります。)

  • USER_SDO_NETWORK_METADATAビューにネットワーク・メタデータを挿入します。

  • SDO_NETの様々なファンクションおよびプロシージャを使用します。

  • SDO_NET_MEMのファンクションおよびプロシージャを使用して、分析と編集を行います。

例5-5 論理ネットワークの例(PL/SQL)

-- Basic steps:
-- 1. Create and populate the node table.
-- 2. Create and populate the link table.
-- 3. Create the path table and paths and links table (for possible 
--    future use, before which they will need to be populated).
-- 4. Populate the network metadata (USER_SDO_NETWORK_METADATA).
--    Note: Can be done before or after Steps 1-3.
-- 5. Use various SDO_NET functions and procedures.
-- 6. Use SDO_NET_MEM functions and procedures for analysis and editing.
 
-- 1. Create and populate the node table.
EXECUTE SDO_NET.CREATE_NODE_TABLE('XYZ_NODES', NULL, NULL, NULL, 2);
 
-- Populate the node table, starting with the highest level in the hierarchy.
 
-- HN1 (Hierarchy level=2, highest in this network)
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level)
  VALUES (1, 'HN1', 'Y', 2);
 
-- HN2 (Hierarchy level=2, highest in this network)
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level)
  VALUES (2, 'HN2', 'Y', 2);
 
-- N1 (Hierarchy level 1, parent node ID = 1 for N1 through N6)
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (101, 'N1', 'Y', 1, 1);
 
-- N2 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (102, 'N2', 'Y', 1, 1);
 
-- N3 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (103, 'N3', 'Y', 1, 1);
 
-- N4 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (104, 'N4', 'Y', 1, 1);
 
-- N5 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (105, 'N5', 'Y', 1, 1);
 
-- N6 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (106, 'N6', 'Y', 1, 1);
 
-- N7 (Hierarchy level 1, parent node ID = 2 for N7 through N14)
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (107, 'N7', 'Y', 1, 2);
 
-- N8 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (108, 'N8', 'Y', 1, 2);
 
-- N9 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (109, 'N9', 'Y', 1, 2);
 
-- N10 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (110, 'N10', 'Y', 1, 2);
 
-- N11 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (111, 'N11', 'Y', 1, 2);
 
-- N12 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (112, 'N12', 'Y', 1, 2);
 
-- N13 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (113, 'N13', 'Y', 1, 2);
 
-- N14 
INSERT INTO xyz_nodes (node_id, node_name, active, hierarchy_level, 
     parent_node_id)
  VALUES (114, 'N14', 'Y', 1, 2);
 
-- 2. Create and populate the link table.
EXECUTE SDO_NET.CREATE_LINK_TABLE('XYZ_LINKS', NULL, NULL, 'COST', 2);
 
-- Populate the link table.
 
-- HN1HN2 (single link in highest hierarchy level: link level = 2)
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level)
  VALUES (1001, 'HN1HN2', 1, 2, 'Y', 2);
 
-- For remaining links, link level = 1 and cost (10, 20, or 30) varies among links.
-- N1N2
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1101, 'N1N2', 101, 102, 'Y', 1, 10);
 
-- N1N3
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1102, 'N1N3', 101, 103, 'Y', 1, 20);
 
-- N2N3
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1103, 'N2N3', 102, 103, 'Y', 1, 30);
 
-- N3N4
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1104, 'N3N4', 103, 104, 'Y', 1, 10);
 
-- N4N5
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1105, 'N4N5', 104, 105, 'Y', 1, 20);
 
-- N4N6
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1106, 'N4N6', 104, 106, 'Y', 1, 30);
 
-- N5N6
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1107, 'N5N6', 105, 106, 'Y', 1, 10);
 
-- N5N8 (child of the higher-level link: parent ID = 1001)
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost, parent_link_id)
  VALUES (1108, 'N5N8', 105, 108, 'Y', 1, 20, 1001);
 
-- N6N7 (child of the higher-level link: parent ID = 1001)
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost, parent_link_id)
  VALUES (1109, 'N6N7', 106, 107, 'Y', 1, 30, 1001);
 
-- N7N8
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1110, 'N7N8', 107, 108, 'Y', 1, 10);
 
-- N7N9
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1111, 'N7N9', 107, 109, 'Y', 1, 20);
 
-- N8N9
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1112, 'N8N9', 108, 109, 'Y', 1, 30);
 
-- N9N10
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1113, 'N9N10', 109, 110, 'Y', 1, 30);
 
-- N9N13
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1114, 'N9N13', 109, 113, 'Y', 1, 10);
 
-- N10N11
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1115, 'N10N11', 110, 111, 'Y', 1, 20);
 
-- N11N12
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1116, 'N11N12', 111, 112, 'Y', 1, 30);
 
-- N12N13
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1117, 'N12N13', 112, 113, 'Y', 1, 10);
 
-- N12N14
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1118, 'N12N14', 112, 114, 'Y', 1, 20);
 
-- N13N14
INSERT INTO xyz_links (link_id, link_name, start_node_id, end_node_id, active, 
     link_level, cost)
  VALUES (1119, 'N13N14', 113, 114, 'Y', 1, 30);
 
-- 3. Create the path table (to store created paths) and the path-link 
--    table (to store links for each path) for possible future use,
--    before which they will need to be populated.
EXECUTE SDO_NET.CREATE_PATH_TABLE('XYZ_PATHS', NULL);
EXECUTE SDO_NET.CREATE_PATH_LINK_TABLE('XYZ_PATHS_LINKS');
 
-- 4. Populate the network metadata (USER_SDO_NETWORK_METADATA).
 
INSERT INTO user_sdo_network_metadata 
    (NETWORK,
     NETWORK_CATEGORY,
     NO_OF_HIERARCHY_LEVELS,
     NO_OF_PARTITIONS,
     NODE_TABLE_NAME,
     LINK_TABLE_NAME,
     LINK_DIRECTION,
     LINK_COST_COLUMN,
     PATH_TABLE_NAME,
     PATH_LINK_TABLE_NAME)
  VALUES (
    'XYZ_NETWORK',  -- Network name
    'LOGICAL',   -- Network category
    2,  -- No. of levels in hierarchy
    1,  -- No. of partitions
    'XYZ_NODES',  -- Node table name
    'XYZ_LINKS',  -- Link table name
    'BIDIRECTED',  -- Link direction
    'COST',  -- Link cost column
    'XYZ_PATHS',  -- Path table name
    'XYZ_PATHS_LINKS'  -- Path-link table name
  );
 
-- 5. Use various SDO_NET functions and procedures.
 
-- Validate the network.
SELECT SDO_NET.VALIDATE_NETWORK('XYZ_NETWORK') FROM DUAL;
 
-- Validate parts or aspects of the network.
SELECT SDO_NET.VALIDATE_LINK_SCHEMA('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.VALIDATE_LRS_SCHEMA('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.VALIDATE_NODE_SCHEMA('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.VALIDATE_PATH_SCHEMA('XYZ_NETWORK') FROM DUAL;
 
-- Retrieve various information (GET_xxx and some other functions).
SELECT SDO_NET.GET_CHILD_LINKS('XYZ_NETWORK', 1001) FROM DUAL;
SELECT SDO_NET.GET_CHILD_NODES('XYZ_NETWORK', 1) FROM DUAL;
SELECT SDO_NET.GET_CHILD_NODES('XYZ_NETWORK', 2) FROM DUAL;
SELECT SDO_NET.GET_IN_LINKS('XYZ_NETWORK', 104) FROM DUAL;
SELECT SDO_NET.GET_LINK_COST_COLUMN('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LINK_DIRECTION('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_LINK_TABLE_NAME('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NETWORK_TYPE('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NO_OF_HIERARCHY_LEVELS('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NO_OF_LINKS('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NO_OF_NODES('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.GET_NODE_DEGREE('XYZ_NETWORK', 104) FROM DUAL;
SELECT SDO_NET.GET_NODE_IN_DEGREE('XYZ_NETWORK', 104) FROM DUAL;
SELECT SDO_NET.GET_NODE_OUT_DEGREE('XYZ_NETWORK', 104) FROM DUAL;
SELECT SDO_NET.GET_OUT_LINKS('XYZ_NETWORK', 104) FROM DUAL;
SELECT SDO_NET.GET_PATH_TABLE_NAME('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_HIERARCHICAL('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_LOGICAL('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.IS_SPATIAL('XYZ_NETWORK') FROM DUAL;
SELECT SDO_NET.NETWORK_EXISTS('XYZ_NETWORK') FROM DUAL;
 
-- Copy a network.
EXECUTE SDO_NET.COPY_NETWORK('XYZ_NETWORK', 'XYZ_NETWORK2');
 
-- Create a trigger.
EXECUTE SDO_NET.CREATE_DELETE_TRIGGER('XYZ_NETWORK');
 
-- 6. Use SDO_NET_MEM functions and procedures for analysis and editing.
 
-- Network analysis and other operations (SDO_NET_MEM.NETWORK_MANAGER)
 
DECLARE
  net_mem    VARCHAR2(100);
  res_string VARCHAR2(1000);
 
  cost        NUMBER;
  res_numeric NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
  indx1        NUMBER;
  var1_numeric NUMBER;
  var1_array   SDO_NUMBER_ARRAY;
 
BEGIN
 
net_mem := 'XYZ_NETWORK';
  
-- Read in the network.
SDO_NET_MEM.NETWORK_MANAGER.READ_NETWORK(net_mem, 'TRUE');
 
-- Validate the network.
res_string := SDO_NET_MEM.NETWORK_MANAGER.VALIDATE_NETWORK_SCHEMA(net_mem);
DBMS_OUTPUT.PUT_LINE('Is network ' || net_mem || ' valid? ' || res_string);
  
res_string := SDO_NET_MEM.NETWORK_MANAGER.LIST_NETWORKS;
DBMS_OUTPUT.PUT_LINE('The current in-memory network(s) is/are: ' || res_string);
 
res_numeric := SDO_NET_MEM.NETWORK_MANAGER.FIND_CONNECTED_COMPONENTS(net_mem);
DBMS_OUTPUT.PUT_LINE('The number of connected components is: ' || res_numeric);
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.MCST_LINK(net_mem);
DBMS_OUTPUT.PUT('Network ' || net_mem || ' has the following MCST links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.FIND_REACHABLE_NODES(net_mem,101);
DBMS_OUTPUT.PUT_LINE('Reachable nodes from 101: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.FIND_REACHING_NODES(net_mem,101);
DBMS_OUTPUT.PUT_LINE('Nodes from which 101 can be reached: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
  
res_array := SDO_NET_MEM.NETWORK_MANAGER.NEAREST_NEIGHBORS(net_mem,101,3);
DBMS_OUTPUT.PUT_LINE('Path IDs to the nearest 3 neighbors of node 101 are: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ', which contains links: ');
  var1_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, res_numeric);
    FOR indx1 IN var1_array.FIRST..var1_array.LAST
    LOOP
      var1_numeric := var1_array(indx1);
      DBMS_OUTPUT.PUT(var1_numeric || ' ');
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); 
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.NEAREST_NEIGHBORS(net_mem,101,3);
DBMS_OUTPUT.PUT_LINE('Path IDs to the nearest 3 neighbors of node 101 are: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ', whose end node is: ');
  var1_numeric := SDO_NET_MEM.PATH.GET_END_NODE_ID(net_mem, res_numeric);
  DBMS_OUTPUT.PUT(var1_numeric);
  DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); 
  
res_string := SDO_NET_MEM.NETWORK_MANAGER.IS_REACHABLE(net_mem,101,105);
DBMS_OUTPUT.PUT_LINE('Can node 101 reach node 105? ' || res_string);
  
res_array := SDO_NET_MEM.NETWORK_MANAGER.ALL_PATHS(net_mem,101,105,10,200,5);
DBMS_OUTPUT.PUT_LINE('For each path from node 101 to node 105: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric ||
                       ' has the following properties: ');
  cost := SDO_NET_MEM.PATH.GET_COST(net_mem, res_numeric);
  DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric || ' cost: ' || cost);
  res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, res_array(indx));  
  DBMS_OUTPUT.PUT_LINE('Is path ' || res_numeric || ' closed? ' || res_string);       
END LOOP;
   
DBMS_OUTPUT.PUT_LINE(' ');
res_numeric := SDO_NET_MEM.NETWORK_MANAGER.SHORTEST_PATH(net_mem,101,105);
DBMS_OUTPUT.PUT_LINE('The shortest path from node 101 to node 105 is path ID: ' || res_numeric);
 
DBMS_OUTPUT.PUT_LINE('The following are characteristics of this shortest path: ');
cost := SDO_NET_MEM.PATH.GET_COST(net_mem, res_numeric);
DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric || ' has cost: ' || cost);
res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, res_numeric);  
DBMS_OUTPUT.PUT_LINE('Is path ' || res_numeric || ' closed? ' || res_string);  
 
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, res_numeric);   
DBMS_OUTPUT.PUT('Path ' || res_numeric || ' has links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
DBMS_OUTPUT.PUT_LINE(' ');
res_numeric := SDO_NET_MEM.NETWORK_MANAGER.SHORTEST_PATH_DIJKSTRA(net_mem,101,105);
DBMS_OUTPUT.PUT_LINE('The shortest Dijkstra path from node 101 to node 105 is ' || res_numeric);
 
DBMS_OUTPUT.PUT_LINE('The following are characteristics of this shortest path: ');
cost := SDO_NET_MEM.PATH.GET_COST(net_mem, res_numeric);
DBMS_OUTPUT.PUT_LINE('Path ' || res_numeric || ' cost: ' || cost);
res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, res_numeric);  
DBMS_OUTPUT.PUT_LINE('Is path ' || res_numeric || ' closed? ' || res_string);  
 
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, res_numeric);   
DBMS_OUTPUT.PUT('Path ' || res_numeric || ' has links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
  
res_array := SDO_NET_MEM.PATH.GET_NODE_IDS(net_mem, res_numeric);   
DBMS_OUTPUT.PUT('Path ' || res_numeric || ' has nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
res_array := SDO_NET_MEM.NETWORK_MANAGER.WITHIN_COST(net_mem,102,100);
DBMS_OUTPUT.PUT('Shortest path IDs to nodes within cost of 100 from node 102: ');
DBMS_OUTPUT.PUT_LINE(' ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  res_numeric := res_array(indx);
  DBMS_OUTPUT.PUT(res_numeric || ', whose end node is: ');
  var1_numeric := SDO_NET_MEM.PATH.GET_END_NODE_ID(net_mem, res_numeric);
  DBMS_OUTPUT.PUT(var1_numeric);
  DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); 
 
END;  
/
 
-- Link editing (SDO_NET_MEM.LINK)
 
DECLARE
  net_mem     VARCHAR2(32);
  res_string  VARCHAR2(100);
  res_numeric NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN
 
net_mem := 'XYZ_NETWORK';
  
-- Read in the network.
-- SDO_NET_MEM.NETWORK_MANAGER.READ_NETWORK(net_mem, 'TRUE');
 
-- GET_CHILD_LINKS
res_array := SDO_NET_MEM.LINK.GET_CHILD_LINKS(net_mem, 1001);
DBMS_OUTPUT.PUT('Link 1001 has the following child links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_COST
res_numeric := SDO_NET_MEM.LINK.GET_COST(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('The cost of link 1104 is: ' || res_numeric);
 
-- GET_END_NODE_ID
res_numeric := SDO_NET_MEM.LINK.GET_END_NODE_ID(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('The end node of link 1104 is: ' || res_numeric);
 
-- GET_LEVEL
res_numeric := SDO_NET_MEM.LINK.GET_LEVEL(net_mem, 1001);
DBMS_OUTPUT.PUT_LINE('The hierarchy level of link 1001 is: ' || res_numeric);
 
-- GET_NAME
res_string := SDO_NET_MEM.LINK.GET_NAME(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('The name of link 1104 is: ' || res_string);
 
-- GET_PARENT_LINK_ID
res_numeric := SDO_NET_MEM.LINK.GET_PARENT_LINK_ID(net_mem, 1108);
DBMS_OUTPUT.PUT_LINE('The parent link of link 1108 is: ' || res_numeric);
 
-- GET_SIBLING_LINK_IDS
res_array := SDO_NET_MEM.LINK.GET_SIBLING_LINK_IDS(net_mem, 1108);
DBMS_OUTPUT.PUT('Link 1108 has the following sibling links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');

-- GET_START_NODE_ID
res_numeric := SDO_NET_MEM.LINK.GET_START_NODE_ID(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('The start node of link 1104 is: ' || res_numeric);
 
-- GET_STATE
res_string := SDO_NET_MEM.LINK.GET_STATE(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('The state of link 1104 is: ' || res_string);
 
-- IS_ACTIVE
res_string := SDO_NET_MEM.LINK.IS_ACTIVE(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('Is link 1104 active?: ' || res_string);
 
-- IS_LOGICAL
res_string := SDO_NET_MEM.LINK.IS_LOGICAL(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('Is link 1104 a logical link?: ' || res_string);
 
-- IS_TEMPORARY
res_string := SDO_NET_MEM.LINK.IS_TEMPORARY(net_mem, 1104);
DBMS_OUTPUT.PUT_LINE('Is link 1104 temporary?: ' || res_string);
 
-- SET_COST
-- Set the cost of link 1119 to 40.
SDO_NET_MEM.LINK.SET_COST(net_mem, 1119, 40);
 
-- SET_END_NODE
-- Set the end node of link 1119 to 109 (N9).
SDO_NET_MEM.LINK.SET_END_NODE(net_mem, 1119, 109);
 
-- SET_LEVEL
-- Set the hierarchy level of link 1119 to 2.
SDO_NET_MEM.LINK.SET_LEVEL(net_mem, 1119, 2);
 
-- SET_NAME
-- Set the name of link 1119 to 'My favorite link'.
SDO_NET_MEM.LINK.SET_NAME(net_mem, 1119, 'My favorite link');
 
-- SET_PARENT_LINK
-- Make link 1001 the parent of link 1119.
SDO_NET_MEM.LINK.SET_PARENT_LINK(net_mem, 1119, 1001);
 
-- SET_START_NODE
-- Set the start node of link 1119 to 110 (N10).
SDO_NET_MEM.LINK.SET_START_NODE(net_mem, 1119, 110);
 
-- SET_STATE
-- Set the state of link 1119 to 'FALSE'.
SDO_NET_MEM.LINK.SET_STATE(net_mem, 1119, 'FALSE');
-- GET_STATE
res_string := SDO_NET_MEM.LINK.GET_STATE(net_mem, 1119);
DBMS_OUTPUT.PUT_LINE('The state of link 1119 is: ' || res_string);
 
-- SET_TYPE
-- Set the type of link 1119 to 'Associative'.
SDO_NET_MEM.LINK.SET_TYPE(net_mem, 1119, 'Associative');
-- GET_TYPE
res_string := SDO_NET_MEM.LINK.GET_TYPE(net_mem, 1119);
DBMS_OUTPUT.PUT_LINE('The type of link 1119 is: ' || res_string);
 
END;  
/
 
-- Node editing (SDO_NET_MEM.NODE)
 
DECLARE
  net_mem     VARCHAR2(32);
  res_string  VARCHAR2(100);
  res_numeric NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN
 
net_mem := 'XYZ_NETWORK';
  
-- GET_ADJACENT_NODE_IDS
res_array := SDO_NET_MEM.NODE.GET_ADJACENT_NODE_IDS(net_mem, 103);
DBMS_OUTPUT.PUT('Node 103 has the following adjacent nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');

-- GET_CHILD_NODE_IDS
res_array := SDO_NET_MEM.NODE.GET_CHILD_NODE_IDS(net_mem, 1);
DBMS_OUTPUT.PUT('Node 1 has the following child nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_COMPONENT_NO
res_numeric := SDO_NET_MEM.NODE.GET_COMPONENT_NO(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('The component number of node 103 is: ' || res_numeric);
 
-- GET_COST
res_numeric := SDO_NET_MEM.NODE.GET_COST(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('The cost of node 103 is: ' || res_numeric);
 
-- GET_HIERARCHY_LEVEL
res_numeric := SDO_NET_MEM.NODE.GET_HIERARCHY_LEVEL(net_mem, 1);
DBMS_OUTPUT.PUT_LINE('The hierarchy level of node 1 is: ' || res_numeric);
 
-- GET_IN_LINK_IDS
res_array := SDO_NET_MEM.NODE.GET_IN_LINK_IDS(net_mem, 103);
DBMS_OUTPUT.PUT('Node 103 has the following inbound links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_INCIDENT_LINK_IDS
res_array := SDO_NET_MEM.NODE.GET_INCIDENT_LINK_IDS(net_mem, 103);
DBMS_OUTPUT.PUT('Node 103 has the following incident links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_NAME
res_string := SDO_NET_MEM.NODE.GET_NAME(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('The name of node 103 is: ' || res_string);
 
-- GET_OUT_LINK_IDS
res_array := SDO_NET_MEM.NODE.GET_OUT_LINK_IDS(net_mem, 103);
DBMS_OUTPUT.PUT('Node 103 has the following outbound links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_PARENT_NODE_ID
res_numeric := SDO_NET_MEM.NODE.GET_PARENT_NODE_ID(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('The parent node of node 103 is: ' || res_numeric);
 
-- GET_SIBLING_NODE_IDS
res_array := SDO_NET_MEM.NODE.GET_SIBLING_NODE_IDS(net_mem, 103);
DBMS_OUTPUT.PUT('Node 103 has the following sibling nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');

-- GET_STATE
res_string := SDO_NET_MEM.NODE.GET_STATE(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('The state of node 103 is: ' || res_string);
 
-- IS_ACTIVE
res_string := SDO_NET_MEM.NODE.IS_ACTIVE(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('Is node 103 active?: ' || res_string);
 
-- IS_LOGICAL
res_string := SDO_NET_MEM.NODE.IS_LOGICAL(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('Is node 103 a logical node?: ' || res_string);
 
-- IS_TEMPORARY
res_string := SDO_NET_MEM.NODE.IS_TEMPORARY(net_mem, 103);
DBMS_OUTPUT.PUT_LINE('Is node 103 temporary?: ' || res_string);
 
-- LINK_EXISTS
res_string := SDO_NET_MEM.NODE.LINK_EXISTS(net_mem, 103, 104);
DBMS_OUTPUT.PUT_LINE('Does a link exist between nodes 103 and 104?: ' || res_string);
 
-- MAKE_TEMPORARY
-- Make node 114 temporary.
SDO_NET_MEM.NODE.MAKE_TEMPORARY(net_mem, 114);
 
-- SET_COMPONENT_NO
-- Set the component number of node 114 to 987.
SDO_NET_MEM.NODE.SET_COMPONENT_NO(net_mem, 114, 987);
 
-- SET_COST
-- Set the cost of node 114 to 40.
SDO_NET_MEM.NODE.SET_COST(net_mem, 114, 40);
 
-- SET_HIERARCHY_LEVEL
-- Set the hierarchy level of node 1 to 2.
SDO_NET_MEM.NODE.SET_HIERARCHY_LEVEL(net_mem, 1, 2);
 
-- SET_NAME
-- Set the name of node 114 to 'My favorite node'.
SDO_NET_MEM.NODE.SET_NAME(net_mem, 114, 'My favorite node');
-- GET_NAME
res_string := SDO_NET_MEM.NODE.GET_NAME(net_mem, 114);
DBMS_OUTPUT.PUT_LINE('The name of node 114 is: ' || res_string);
 
-- SET_PARENT_NODE
-- Make node 1 the parent of node 114.
SDO_NET_MEM.NODE.SET_PARENT_NODE(net_mem, 114, 1);
 
-- SET_STATE
-- Set the state of node 111 to 'FALSE'.
SDO_NET_MEM.NODE.SET_STATE(net_mem, 111, 'FALSE');
-- GET_STATE
res_string := SDO_NET_MEM.NODE.GET_STATE(net_mem, 111);
DBMS_OUTPUT.PUT_LINE('The state of node 111 is: ' || res_string);
 
-- SET_TYPE
-- Set the type of node 114 to 'Research'.
SDO_NET_MEM.NODE.SET_TYPE(net_mem, 114, 'Research');
-- GET_TYPE
res_string := SDO_NET_MEM.NODE.GET_TYPE(net_mem, 114);
DBMS_OUTPUT.PUT_LINE('The type of node 114 is: ' || res_string);
 
END;  
/
 
-- Path editing (SDO_NET_MEM.PATH)
 
DECLARE
  net_mem     VARCHAR2(32);
  res_string  VARCHAR2(100);
  res_numeric NUMBER;
  path_id     NUMBER;
  res_array   SDO_NUMBER_ARRAY;
  indx        NUMBER;
 
BEGIN
 
net_mem := 'XYZ_NETWORK';
  
-- Create a path for use with subsequent statements. Here, it is
-- the shortest path between nodes 101 (N1) and 105 (N5).
path_id := SDO_NET_MEM.NETWORK_MANAGER.SHORTEST_PATH(net_mem,101,105);
DBMS_OUTPUT.PUT_LINE('The shortest path between nodes 101 and 105 is: ' || path_id);
 
-- GET_LINK_IDS
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Path ' || path_id || ' has the following links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_COST
res_numeric := SDO_NET_MEM.PATH.GET_COST(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The cost of path ' || path_id || ' is: ' || res_numeric);
 
-- GET_END_NODE_ID
res_numeric := SDO_NET_MEM.PATH.GET_END_NODE_ID(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The end node ID of path ' || path_id || ' is: ' || res_numeric);
 
-- GET_LINK_IDS
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Path ' || path_id || ' has the following links: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_NO_OF_LINKS
res_numeric := SDO_NET_MEM.PATH.GET_NO_OF_LINKS(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The number of links in path ' || path_id || ' is: ' || res_numeric);
 
-- GET_NODE_IDS
res_array := SDO_NET_MEM.PATH.GET_NODE_IDS(net_mem, path_id);
DBMS_OUTPUT.PUT('Path ' || path_id || ' has the following nodes: ');
FOR indx IN res_array.FIRST..res_array.LAST
LOOP
  DBMS_OUTPUT.PUT(res_array(indx) || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
 
-- GET_START_NODE_ID
res_numeric := SDO_NET_MEM.PATH.GET_START_NODE_ID(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The start node ID of path ' || path_id || ' is: ' || res_numeric);
 
-- IS_ACTIVE
res_string := SDO_NET_MEM.PATH.IS_ACTIVE(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' active?: ' || res_string);
 
-- IS_CLOSED
res_string := SDO_NET_MEM.PATH.IS_CLOSED(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' closed?: ' || res_string);
 
-- IS_CONNECTED
res_string := SDO_NET_MEM.PATH.IS_CONNECTED(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' connected?: ' || res_string);
 
-- IS_LOGICAL
res_string := SDO_NET_MEM.PATH.IS_LOGICAL(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' a logical path?: ' || res_string);
 
-- IS_SIMPLE
res_string := SDO_NET_MEM.PATH.IS_SIMPLE(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' a simple path?: ' || res_string);
 
-- IS_TEMPORARY
res_string := SDO_NET_MEM.PATH.IS_TEMPORARY(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('Is path ' || path_id || ' temporary?: ' || res_string);
 
-- SET_NAME
-- Set the name of path to 'My favorite path'.
SDO_NET_MEM.PATH.SET_NAME(net_mem, path_id, 'My favorite path');
-- GET_NAME
res_string := SDO_NET_MEM.PATH.GET_NAME(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The name of path ' || path_id || ' is: ' || res_string);
 
-- SET_TYPE
-- Set the type of the path to 'Logical connections'.
SDO_NET_MEM.PATH.SET_TYPE(net_mem, path_id, 'Logical connections');
-- GET_TYPE
res_string := SDO_NET_MEM.PATH.GET_TYPE(net_mem, path_id);
DBMS_OUTPUT.PUT_LINE('The type of path ' || path_id || ' is: ' || res_string);
 
-- SET_PATH_ID
-- Set (change) the path ID of the path to 6789.
SDO_NET_MEM.PATH.SET_PATH_ID(net_mem, path_id, 6789);
 
-- Get maximum link, node, path, subpath IDs.
SELECT SDO_NET_MEM.NETWORK.GET_MAX_LINK_ID(net_mem) 
  INTO res_numeric FROM DUAL;
DBMS_OUTPUT.PUT_LINE('Maximum link ID = ' || res_numeric);
SELECT SDO_NET_MEM.NETWORK.GET_MAX_NODE_ID(net_mem)   
  INTO res_numeric FROM DUAL;
DBMS_OUTPUT.PUT_LINE('Maximum node ID = ' || res_numeric);
SELECT SDO_NET_MEM.NETWORK.GET_MAX_PATH_ID(net_mem)
  INTO res_numeric FROM DUAL;
DBMS_OUTPUT.PUT_LINE('Maximum path ID = ' || res_numeric);
SELECT SDO_NET_MEM.NETWORK.GET_MAX_SUBPATH_ID(net_mem)
  INTO res_numeric FROM DUAL;
DBMS_OUTPUT.PUT_LINE('Maximum subpath ID = ' || res_numeric);

END;  
/

5.13.5 パーティション化とロード・オンデマンド分析の例(PL/SQL、XMLおよびJava)

この項では、関連する操作を含むネットワークのパーティション化の例、およびロード・オンデマンドでのネットワーク分析の実行の例を示します。この例では、5.7項で説明した概念と方法を示します。

例5-6では、NYC_NETという名前の空間ネットワークをパーティション化します。(このネットワークはすでに存在し、そのメタデータ表、ノード表およびリンク表は移入済であると想定します。)

例5-6 空間ネットワークのパーティション化

exec sdo_net.spatial_partition(
  network->'NYC_NET', -- network name
  partition_table_name->'NYC_PART$', -- partition table name
  max_num_nodes->5000, -- max. number of nodes per partition
  log_loc->'MDDIR', -- partition log directory
  log_file->'nyc_part.log', --partition log file name
  open_mode->'w', -- partition log file open mode
  link_level->1); -- link level

例5-7では、ネットワークのパーティションBLOBを生成します。

例5-7 パーティションBLOBの生成

exec sdo_net.generate_partition_blobs(
  network->'NYC_NET', ,-- network name
  link_level ->1, -- link level
  partition_blob_table_name->'NYC_PBLOB$', -- partition blob table name
  includeUserdata->FALSE, -- include user data in partition blobs?
  log_loc->'MYDIR',  -- partition log directory
  log_file->'nyc_part.log', --partition log file name
  open_mode->'a'); -- partition log file open mode

例5-6および例5-7では、NYC_NETネットワークに必要なパーティション表を生成します。これらの例の実行後に、.logファイルで現行の状態またはパーティション化やBLOB生成中に発生したエラーをチェックできます。

例5-8には、パーティション・キャッシュを含む、ロード・オンデマンド環境の構成を行うXMLを示します。

例5-8 パーティション・キャッシュを含むロード・オンデマンド環境の構成

<?xml version="1.0" encoding="UTF-8" ?>
<LODConfigs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.oracle.com/spatial/network/lodLODConfigs.xsd"
     xmlns="http://www.oracle.com/spatial/network/lod">
  <!-- default configuration for networks not configured -->
  <defaultLODConfig>
    <LODConfig>
      <readPartitionFromBlob>false</readPartitionFromBlob>
      <partitionBlobTranslator>oracle.spatial.network.lod.PartitionBlobTranslator11g</partitionBlobTranslator>
      <userDataIO>oracle.spatial.network.lod.LODUserDataIOSDO</userDataIO>
      <cachingPolicy>
        <linkLevelCachingPolicy>
          <linkLevel>1</linkLevel>
          <maxNodes>500000</maxNodes>
          <residentPartitions>-1</residentPartitions>
          <flushRule>oracle.spatial.network.lod.LRUCachingHandler</flushRule>
        </linkLevelCachingPolicy>
      </cachingPolicy>
    </LODConfig>
  </defaultLODConfig>
  …
  <networkLODConfig>
    <!-- network to be configured -->
    <networkName> NYC_NET </networkName>
    <LODConfig>
       <!- read partitions from partition table or from partition blob table -->
      <readPartitionFromBlob>true</readPartitionFromBlob>
      <partitionBlobTranslator>oracle.spatial.network.lod.PartitionBlobTranslator11g</partitionBlobTranslator>
      <userDataIO>oracle.spatial.network.lod.LODUserDataIOSDO</userDataIO>
      <cachingPolicy>
        <linkLevelCachingPolicy>
          <linkLevel>1</linkLevel>
          <!-- Maximum number of nodes allowed in cache -->
          <maxNodes>500000</maxNodes>
          <!-- resident partitions -->
          <residentPartitions>-1</residentPartitions>
          <flushRule>oracle.spatial.network.lod.LRUCachingHandler</flushRule>
        </linkLevelCachingPolicy>
        <linkLevelCachingPolicy>
          <linkLevel>2</linkLevel>
          <maxNodes>500000</maxNodes>
          <residentPartitions>*</residentPartitions>
          <flushRule>oracle.spatial.network.lod.LRUCachingHandler</flushRule>
        </linkLevelCachingPolicy>
      </cachingPolicy>
    </LODConfig>
  </networkLODConfig>
</LODConfigs>

例5-9および例5-10には、それぞれロード・オンデマンド構成のリロードに使用するJava APIおよびPL/SQL APIを示します。

例5-9 ロード・オンデマンド構成のリロード(Java API)

InputStream config = ClassLoader.getSystemResourceAsStream(
                     "netlodcfg.xml");
LODNetworkManager.getConfigManager().loadConfig(config);

例5-10 ロード・オンデマンド構成のリロード(PL/SQL API)

EXECUTE SDO_NET.LOAD_CONFIG('WORK_DIR', 'netlodcfg.xml');

例5-11では、指定したネットワーク・パーティションの推定サイズ(バイト単位)を戻します。

例5-11 推定パーティション・サイズの取得

SELECT SDO_NET.GET_PARTITION_SIZE (
  NETWORK->'NYC_NET',
  PARTITION_ID->1,
  LINK_LEVEL ->1,
  INCLUDE_USER_DATA->'FALSE',
  INCLUDE_SPATIAL_DATA->'TRUE') FROM DUAL;

例5-12では、ロード・オンデマンドのJava API(oracle.spatial.network.lod)を使用して、ネットワーク上の最短パスの問合せを発行します。

例5-12 ネットワーク分析: 最短パス(LOD Java API)

Connection conn = LODNetworkManager.getConnection(dbUrl, dbUser, dbPassword);
// get LOD network IO Adapter
String networkName = "NYC_NET";
NetworkIO reader = LODNetworkManager.getCachedNetworkIO(conn, networkName, networkName, null);
// get analysis module
NetworkAnalyst analyst = LODNetworkManager.getNetworkAnalyst(reader);
// compute the shortest path
LogicalSubPath path = analyst.shortestPathDijkstra(new PointOnNet(startNodeId),
      new PointOnNet(endNodeId), null);
// print path result
PrintUtility.print(System.out, path, false, 0, 0);
. . .

例5-13では、XML API (oracle.spatial.network.xml)を使用して、ネットワーク上の最短パスの問合せを発行します。これには、要求と応答が含まれます。

例5-13 ネットワーク分析: 最短パス(XML API)

<?xml version="1.0" encoding="UTF-8"?>
<ndm:networkAnalysisRequest
    xmlns:ndm="http://xmlns.oracle.com/spatial/network"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:gml="http://www.opengis.net/gml">
  <ndm:networkName>NYC_NET</ndm:networkName>
  <ndm:shortestPath>
    <ndm:startPoint>
      <ndm:nodeID>65</ndm:nodeID>
    </ndm:startPoint>
    <ndm:endPoint>
      <ndm:nodeID>115</ndm:nodeID>
    </ndm:endPoint>
    <ndm:subPathRequestParameter>
      <ndm:isFullPath> true </ndm:isFullPath>
      <ndm:startLinkIndex> true </ndm:startLinkIndex>
      <ndm:startPercentage> true </ndm:startPercentage>
      <ndm:endLinkIndex> true </ndm:endLinkIndex>
      <ndm:endPercentage> true </ndm:endPercentage>
      <ndm:geometry>false</ndm:geometry>
    <ndm:pathRequestParameter>
      <ndm:cost> true </ndm:cost>
      <ndm:isSimple> true </ndm:isSimple>
      <ndm:startNodeID>true</ndm:startNodeID>
      <ndm:endNodeID>true</ndm:endNodeID>
      <ndm:noOfLinks>true</ndm:noOfLinks>
      <ndm:linksRequestParameter>
        <ndm:onlyLinkID>true</ndm:onlyLinkID>
      </ndm:linksRequestParameter>
      <ndm:nodesRequestParameter>
        <ndm:onlyNodeID>true</ndm:onlyNodeID>
      </ndm:nodesRequestParameter>
      <ndm:geometry>true</ndm:geometry>
    </ndm:pathRequestParameter>
    </ndm:subPathRequestParameter>
  </ndm:shortestPath>
</ndm:networkAnalysisRequest>
 
<?xml version = '1.0' encoding = 'UTF-8'?>
<ndm:networkAnalysisResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ndm="http://xmlns.oracle.com/spatial/network" xmlns:gml="http://www.opengis.net/gml">
  <ndm:networkName>NYC_NET</ndm:networkName>
  <ndm:shortestPath>
    <ndm:subPathResponse>
      <ndm:isFullPath>true</ndm:isFullPath>
      <ndm:startLinkIndex>0</ndm:startLinkIndex>
      <ndm:startPercentage>0.0</ndm:startPercentage>
      <ndm:endLinkIndex>17</ndm:endLinkIndex>
      <ndm:endPercentage>1.0</ndm:endPercentage>
      <ndm:pathResponse>
        <ndm:cost>6173.212694405703</ndm:cost>
        <ndm:isSimple>true</ndm:isSimple>
        <ndm:startNodeID>65</ndm:startNodeID>
        <ndm:endNodeID>115</ndm:endNodeID>
        <ndm:noOfLinks>18</ndm:noOfLinks>
        <ndm:linkIDs>145477046 145477044 145477042 145477039 145476926 145476930 145480892 145480891 145476873 145476871 145477023 145489019 145489020 145476851 145488986 145488987 145476913 145476905         
        </ndm:linkIDs>
        <ndm:nodeIDs>65 64 60 57 58 61 71 70 73 87 97 95 91 101 102 104 117 120 115 
        </ndm:nodeIDs>
        <ndm:geometry>
          <gml:LineString>
            <gml:coordinates>-71.707462,43.555262 -71.707521,43.555601…
            </gml:coordinates>
          </gml:LineString>
        </ndm:geometry>
      </ndm:pathResponse>
    </ndm:subPathResponse>
  </ndm:shortestPath>
</ndm:networkAnalysisResponse>

パーティション化したネットワークでのロード・オンデマンド分析のその他の使用例は、デモ・ファイル(5.14項を参照)に含まれています。

5.13.6 ユーザー定義データの例(PL/SQLおよびJava)

この項では、ネットワークのユーザー定義データの使用例を示します。ユーザー定義データとは、ユーザーがネットワーク表現と関連付ける(接続性とは関係のない)情報です。USER_SDO_NETWORK_USER_DATAメタデータ・ビューとALL_SDO_NETWORK_USER_DATAメタデータ・ビュー(5.10.3項を参照)のどちらにも、ユーザー定義データに関する情報が含まれます。

ユーザー定義データを使用するには、適切なxxx_SDO_NETWORK_METADATAビュー(5.10.1項を参照)のUSER_DEFINED_DATA列値をYに設定する必要があります。

例5-14では、リンク関連のユーザー定義データをネットワーク・メタデータに挿入します。

例5-14 ユーザー定義データのネットワーク・メタデータへの挿入

-- Insert link user data named 'interaction' of
-- type varchar2 (50) in network 'bi_test'.
--'interaction' is a column of type varchar2(50) in the link table of network 'bi_
test'.
insert into user_sdo_network_user_data 
         (network,table_type, data_name, data_type, data_length, category_id) 
          values ('bi_test', 'LINK', 'interaction', 'VARCHAR2', 50, 0) ;
-- insert link user data named 'PROB' of type Number.
--'PROB' is a column of type NUMBER in the link table of network 'bi_test'.
insert into user_sdo_network_user_data 
         (network,table_type,data_name,data_type, category_id)
          values ('bi_test','LINK','PROB','NUMBER', 0) ;

ネットワークまたはネットワーク・パーティションがロードされた後に、ユーザー定義データをJava表現で使用できます。ユーザー定義データにアクセスするには、NodeLinkPathおよびSubPathインタフェースのgetUserDataメソッドおよびsetUserDataメソッドを使用します。次に例を示します。

String interaction = (String)link.getUserData("interaction");
double prob = ((Double)link.getUserData("Prob")).doubleValue();

5.14 ネットワーク・データ・モデル・グラフのチュートリアルとその他のリソース

Oracle Technology Networkのhttp://www.oracle.com/technetwork/database-options/spatialandgraphには、ネットワーク・データ・モデル・グラフを含む、Oracle Spatialテクノロジを開始する場合に役立つ貴重なリソースへのリンクが提供されています。ネットワーク・データ・モデルのリソースには、次のものが含まれます。

  • ネットワーク・データ・モデルのチュートリアル(http://www.oracle.com/technetwork/indexes/samplecode/spatial-1433316.htmlにあるndm_tutorial.zip)は、ネットワークの設定と構成を行う手順および分析を行う手順の概要を説明します。また、サンプル・コードと、Oracle Mapを使用して分析結果を表示する方法を説明するWebアプリケーションも含まれています。

  • NDMのホワイト・ペーパー(『A Load-On-Demand Approach to Handling Large Networks in the Oracle Spatial and Graph Network Data Model Graph』)では、詳細な説明と例を提供します。

5.15 Spatialおよび関連する機能のREADMEファイル

README.txtファイルは、『Oracle Spatial開発者ガイド』『Oracle Spatial GeoRaster開発者ガイド』および『Oracle Spatialトポロジおよびネットワーク・データ・モデル開発者ガイド』(このマニュアル)の情報を補足するファイルです。このファイルは、次の場所にあります。

$ORACLE_HOME/md/doc/README.txt