Oracle APEX 21.1よりマップ・リージョンが新設されました。アプリケーションを作成して、使い方を確認してみようと思います。最終的には以下のアプリケーションを作成します。
以前にOracle Spatialの機能をOracle APEXから利用する手順について書いた記事を元にしています。
Oracle Spatialの機能をOracle APEXで使用する元記事に従ってアプリケーションを作成したのち、マップ・リージョンを追加します。または、元記事の手順を飛ばして、以下のアプリケーションをインポートしてから始めることもできます。
https://github.com/ujnak/apexapps/blob/master/exports/drone-permits-app.sql
Drone Permits Appが作成済みでGeocoderを呼び出す機能も追加済み、というのが前提条件です。
ページ番号6のDrone Flight Request - Detailsを開き、新規にリージョンの作成を行います。識別のタイトルをドローン飛行空域とし、タイプにマップを選択します。
最初にドローンの飛行が禁止されている、すべての空域を表示するレイヤーを設定します。新規となっているレイヤーを選択し、識別の名前を禁止空域、レイヤー・タイプにポリゴンを選択します。
ソースの表名にURBAN_AREA_UKを選択します。ドローンの飛行が禁止されている空域は列GEOMに定義されているので、列のマッピングのジオメトリ列のデータ型としてSDO_GEOMETRYを選択し、ジオメトリ列にGEOMを指定します。
ページを実行して結果を確認してみます。英国の禁止空域のみが列GEOMに登録されているため、地図が英国にフィットして表示されています。青く表示されている領域がドローンの飛行禁止空域です。
次に飛行許可を申請した座標をレイヤーとして表示します。左ペインのマップ・リージョンのレイヤーの上でコンテキスト・メニューを表示させ、レイヤーの作成を実行します。
識別の名前をリクエストとし、レイヤー・タイプにポイントを選択します。ソースのタイプはSQL問合せとし、SQL問合せに以下のSELECT文を記述します。
select n002, n003
from apex_collections where collection_name = 'GEOCODER_RESULTS'
and n002 is not null and n003 is not null
列のマッピングのジオメトリ列のデータ型として、経度/緯度を選択し、経度列にN002、緯度列にN003を指定します。外観の塗りつぶしの色は赤(#ff0000)を指定します。
APEXコレクションGEOMETRY_RESULTSへ経度、緯度の情報を投入する処理は、ボタンOBTAIN_FLY_ZONE_INFOをクリックしたときに行われます。
OBTAIN_FLY_ZONE_INFOの動的アクションからジオコーダーが呼び出され、リクエストした住所から座標が得たのちにマップ・リージョンをリフレッシュするよう、動的アクションに処理を追加します。
最初にページのロード時にAPEXコレクションGEOCODER_RESULTSを初期化します。ページがロードされる時点でコレクションを初期化することにより、前回のジオコーダーの呼び出しで取得した座標がマップに表示されることを防ぎます。実行するPL/SQLコードは以下です。
apex_collection.create_or_truncate_collection('GEOCODER_RESULTS');
レンダリング前でプロセスの作成を行います。名前をコレクションの初期化とし、タイプとしてコードを実行を選択します。ソースの位置はローカル・データベース、言語はPL/SQL、PL/SQLコードに上記のAPEX_COLLECTIONの呼び出しを記述します。
座標を取得したのち、マップ・リージョンをリフレッシュさせます。
左ペインに動的アクション・ビューを表示させ、動的アクションであるジオコード取得成功にTrueアクションを作成します。作成したアクションの識別のアクションにリフレッシュを選択します。影響を受ける要素は、選択タイプがリージョンでリージョンはドローン飛行空域です。
ページを実行し、今までの実装を確認します。飛行リクエストの一覧から任意のリクエストを選択します。Obtain Fly Zone Infoのボタンをクリックすると、マップに位置が表示されます。
ドローンの飛行禁止空域にリクエストが含まれている場合、その空域を表示させます。そのためのレイヤーを新たに追加します。表示する空域の選択に、以下のSQL問合せを使います。Oracle Spatialが提供するSDO_ANYINTERACTファンクションを使用しています。
select GEOM
from URBAN_AREA_UK ar,
(
select n002, n003 from apex_collections
where collection_name = 'GEOCODER_RESULTS'
and n002 is not null and n003 is not null
) pt
where sdo_anyinteract(
geom,
mdsys.sdo_geometry(2001, 4326,
mdsys.sdo_point_type(pt.n002, pt.n003, null),
null, null
)
) = 'TRUE'
新規にレイヤーを追加し、識別の名前を該当する禁止空域とします。レイヤー・タイプにポリゴンを選択します。ソースのSQL問合せに上記のSELECT文を記述し、列のマッピングとしてジオメトリ列のデータ型にSDO_GEOMETRY、ジオメトリ列としてGEOMを指定します。
レイヤーの重ね合わせ表示の際に、該当する禁止空域の上にリクエストが表示されるよう、レイヤーの順序を、禁止空域、該当する禁止空域、リクエストの順番に入れ替えます。
以上で完成です。アプケーションを動作させると、一番最初のGIF動画の動作を確認することができます。
今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/drone-permits-app-with-spatial.sql
ジオコーダーは、elocation.oracle.comにたいしてRESTの呼び出しを行なっています。ネットワークACLの設定でOracle Databaseからのリクエストの発行が失敗したときに、以下のコードで接続を許可しました。
begin
dbms_network_acl_admin.create_acl(acl => 'geocoder.xml',
description => 'eLocation',
principal => 'APEX_210100',
is_grant => true,
privilege => 'connect');
dbms_network_acl_admin.assign_acl(acl => 'geocoder.xml',
host => 'elocation.oracle.com');
end;
/
commit;
以上になります。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完