Oracle Spatialを使った接触追跡という記事を参照して、この結果をOracle APEXのマップ・リージョンを使って可視化しようとすると、sdo_obj_tracing.get_all_durationsが行を返してくれない、という現象がありました。(2022年5月9日追記 - sdo_obj_tracing.get_all_durationsの引数track_table_nameにスキーマ名を付けることにより、正常に動作します。そのため、RESTサービスよりは表関数で実装する方が効果的でしょう。)
Oracle APEXは少し特殊なSQLの実行方法なので(以前に説明記事を書いています)、おそらくそれが理由だと思われるのですが、Oracle Spatialの接触追跡を使える環境は限られているため、ワークアラウンドを実装してみました。
APEXから呼ぶと行が返されないのですが、RESTサービスとして呼ぶとsdo_obj_tracing.get_all_durationsは行を返します。なので、RESTサービスとして接触追跡を実装します。
Always FreeのAutonomous DatabaseでOracle Database 21cが使えるのは北米のリージョンだけなので、Ashburnでインスタンスを作成しました。APEXのワークスペースはAPEXDEV、Oracle Spatialの記事の作業はSPATIALUSERではなく、APEXのワークスペース・ユーザーとなるAPEXDEVで作業を行なっています。
以下、実装になります。
RESTサービスは、APEXのRESTfulサービスのUIを使って実装しました。
モジュールをcom.oracle.contacttracing、ベース・パスを/contacts/として作成しています。認証による保護は省略しています。
URIテンプレートはtraceとしています。ハンドラはGETだけを作成しています。
GETハンドラを作成します。ソース・タイプをPL/SQLとし、レスポンスはPL/SQLのコードで生成します。
ソースは以下になります。
APEXのアプリケーションからRESTサービスを検出する際に、パラメータを指定できないケースがあります。実行結果が返されないと、想定されるレスポンスを手作業で登録する必要が出てきます。それは避けたいため、パラメータの指定が無い場合に、必ず実行結果が返される値に置き換えています。
URLの問合せ文字列が、ソースで使用しているバインド変数に渡されるよう、パラメータを設定します。user_id、start_time、end_time、distance、time_tolerance_in_sec、chaining_tolerance_in_secをURLの問合せ文字列として受け付けます。
RESTサービスの作成は以上です。
続いて、このRESTサービスを使ったAPEXアプリケーションを作成します。
アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前はContact Tracingとします。
アプリケーションが作成されます。最初にRESTデータ・ソースを作成します。
共有コンポーネントを開きます。
RESTデータ・ソースを開きます。
作成済みのRESTデータ・ソースが一覧されます。作成をクリックします。
RESTデータ・ソースの作成は最初からのままで、次に進みます。
RESTデータ・ソース・タイプは簡易HTTPを選択します。RESTサービス自体はORDSを使って実装していますが、RESTサービスはORDSの機能を使わず、PL/SQLでコーディングしているためです。名前はContact Tracing、URLエンドポイントとして、先ほど作成したRESTサービスのURLを入力します。
次へ進みます。
作成される内容の確認です。リモート・サーバー、ベースURL、サービスURLパスの変更が必要な場合はほぼ無いので、変更せずに次へ進みます。
ページ区切り(ページング)は実装していないので、ページ区切りタイプはページ区切りなしのままで、次へ進みます。
認証は不要なので、
認証が必要ですは
OFFのままにしておきます。
以上の条件で、検出をクリックします。
RESTサービスのレスポンスが表示されます。APEXのアプリケーションで扱いやすいようにPL/SQLのコードを記述しているので、変更が必要な作業はありません。
RESTデータ・ソースの作成をクリックします。
RESTソースContact Tracingが作成されました。これから、問合せ文字列の設定を追加します。編集のためにContact Tracingを開きます。
RESTデータ・ソースの編集画面から、パラメータの追加を実行します。
パラメータのタイプは問合せ文字列変数です。名前はuser_id、start_time、end_time、distance、time_tolerance_in_sec、chaining_tolerance_in_secの6つです。値はPL/SQLのソースとして設定したデフォルト値と同じにしておきます。目的は入力、静的はOFF、必須をONにします。
追加後、さらに追加をクリックし、パラメータをすべて作成します。
パラメータを作成したら、RESTデータ・ソースの作成は完了です。
変更の適用をクリックします。
ホーム・ページに接触追跡の結果を表示するマップ・リージョンを作成します。
その前に、接触追跡の実行での引数になるページ・アイテムを作成します。
リージョンを作成し、識別の名前をパラメータとします。タイプは静的コンテンツです。作成したリージョンに、6つのページ・アイテム、P1_USER_ID、P1_START_TIME、P1_END_TIME、P1_DISTANCE、P1_TIME_TOLERANCE_IN_SEC、P1_CHAINING_TOLERANCE_IN_SECを作成します。
マップ・リージョンを作成します。識別のタイトルをContact Tracing、タイプをマップとします。
レイヤーを選択します。識別の名前を接触、レイヤー・タイプはポイントとします。ソースの位置として、RESTソースを選択し、RESTソースにContact Tracingを選択します。列のマッピングのジオメトリ列のデータ型として、経度/緯度を選択し、経度列にX、緯度列にYを設定します。
パラメータを選択し、
値の
タイプを
アイテムに変更します。
アイテムにRESTサービスのパラメータとなる
ページ・アイテムを選択します。
最後に送信ボタンを作成します。ボタン名をB_SUBMIT、ラベルを送信とします。
以上で、アプリケーションは完成です。
APEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/rest-contact-tracing.sql
ORDSのRESTサービスのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/ORDS_REST_APEXDEV_com.oracle.contacttracing_2022_04_26.sql
Oracle APEXのアプリケーション作成の参考になれば幸いです。
追記
RESTサービスが呼び出せることの確認だったので、APEXアプリの見栄えは気にしていなかったのですが、せめてCONTACT_IDで色分けしてみます。
レイヤーを選択して、ローカル後処理のタイプをSQL問合せに変更します。SQL問合せに以下を記述します。
select
X,
Y,
to_char(END_TIME, 'YYYY-MM-DD HH24:MI') end_time,
CONTACT_ID,
IN_USER_ID,
to_char(START_TIME, 'YYYY-MM-DD HH24:MI') start_time,
OUT_USER_ID,
NUM_CONTACT_TIMES,
DURATION_IN_MINUTES,
case
when contact_id = 1 then
'red'
when contact_id = 2 then
'green'
when contact_id = 3 then
'yellow'
when contact_id = 4 then
'blue'
else
'black'
end col
from #APEX$SOURCE_DATA#
色を指定する列COLを追加したので、それを外観の塗りつぶしの色に&COL.として指定します。
結果として、以下のように色付けされます。
色だけでなく、例えばアイコンなども同様の手法で変更することができます。