ラベル 国土交通省 の投稿を表示しています。 すべての投稿を表示
ラベル 国土交通省 の投稿を表示しています。 すべての投稿を表示

2026年9月10日木曜日

国土地理院が公開している自然災害伝承碑データより伝承碑の位置を表示するAPEXアプリをCodexで作成する

国土交通省の機関である国土地理院よりオープン・データとして、自然災害伝承碑データが公開されています。過去に発生した災害を後世に伝えるために全国各地に建立されている伝承碑の、位置情報および災害名、災害種別、伝承内容などがオープン・データに含まれています。

国土地理院 - 自然災害伝承碑データの提供について
https://www.gsi.go.jp/bousaichiri/denshouhi_datainfo.html

このオープン・データのGeoJSONファイルより、OpenAI Codexを使って伝承碑が存在する場所や伝承碑の説明を表示するAPEXアプリケーションを作成します。一覧する伝承碑を絞り込むために、ファセット検索も組み込みます。

Codexが作成したAPEXアプリケーションは以下のように動作します。


OpenAI CodexとモデルにGPT-6 Astra(軽)を使用しました。

Oracle APEXのアプリケーションを作成するため、Oracle Corporationから配布されているOracle DatabaseとAPEXlangのスキルを使用しています。

APEXlangのスキルはOracle APEXのリリース・サイクルとは独立してアップデートされています。APEXlangスキルのリリース・ノートは以下のリンクで公開されています。本記事の公開時点での最新リリースは2026.8.26です。


以前は指示通りに生成できなかったアプリケーションも、更新されたAPEXlangスキルでは生成できる可能性があります。

OpenAI CodexやClaude CodeといったAIコーディング・エージェントとAPEXlangを使ったアプリケーション作成については、Oracle APEX 26.1がリリースされたときにOracle CorporationのScott SpendoliniさんがAPEX Office Hoursで紹介されています。


このセッションの中で、SQLcl MCPサーバーの構成が推奨されています。


少なくてもCodexはSQLclをCLIで扱えるので、SQLclの構成は必要なさそうです。本記事ではSQLcl MCPサーバーは構成せず、SQLclのみでデータベースを操作しています。

また、あらかじめスターター・アプリケーションを作成することが推奨されていますが、最新のAPEXlangスキルでは、これも不要に見えます。本記事ではスターター・アプリケーションは作成していません。


GitHubにあるAPEXlangのREADME.mdにPrompt Examples by Taskとして、いくつかのプロンプトが紹介されています。


その中にWhole app from beginning to endとして、以下のプロンプトが紹介されています。
Create a dashboard page for order operations with KPI cards, a monthly revenue chart, and an interactive report. Use existing schema evidence and ask before guessing missing columns.
一般的なスターター・アプリケーションは不要と思われますが、APEX 26.1で導入されたボイラープレートのように、会社固有のテーマ、あらかじめ作成済みの認証スキーム、LOV、プラグインを含んでいるアプリケーションであれば、作成してプロジェクト・フォルダにエクスポートしておくと、アプリケーションの作成に必要な要件や指示が減り、時間とコストの節約になるでしょう。

以下よりCodexで行なった作業を紹介します。

最初にローカルのPCに作業フォルダを作成します。今回はndmm_monumentsとしてフォルダを作成しました。

国土地理院 - 自然災害伝承碑データの提供についてのページにアクセスし、ページの一番下にある免責事項に同意するをクリックすると、データのダウンロード・ページに移ります。

GeoJSON形式のデータをダウンロードします。


ファイルは000250767.zipとしてダウンロードされます。このファイルを作業フォルダに配置し解凍します。解凍するとフォルダ20260827_GeoJSONが作成され、その下に20260827.geojsonとして、GeoJSON形式のデータファイルが作成されます。

ndmm_monuments % ls -l 20260827_GeoJSON

total 4760

-rw-rw-rw-@ 1 ********  staff     6729 12月 23  2021 0_はじめにお読みください(国土地理院コンテンツ利用規約).txt

-rw-rw-rw-@ 1 ********  staff     1229  1月 15  2024 1_データについて_geojson.txt

-rw-rw-rw-@ 1 ********  staff  2422479  8月 31 07:35 20260827.geojson

ndmm_monuments % 


作業フォルダにOracle DatabaseとAPEXlangのスキルをインストールします。スキルのインストール方法には色々ありますが、本記事ではMicrosoft APMを使用します。APMはあらかじめインストールしておきます。

作業ディレクトリに移動し、Oracle APEXとOracle DBのスキルをインストールします。

apm install oracle/skills/apex --target codex
apm install oracle/skills/db --target codex
apm deps list

APEXlangのスキルはoracle/skills/apexに含まれています。

ndmm_monuments % apm install oracle/skills/apex --target codex

[*] Validating 1 package...

[+] oracle/skills/apex

[*] Updated apm.yml with 1 new package(s)

[>] Installing 1 new package...

[>] Resolving skills-apex...

[i] Targets: codex  (source: --target flag)

  [+] github.com/oracle/skills/apex #default @fcbc9430

  |-- Skill integrated -> .agents/skills/

  [!] 1 dependency unpinned: oracle/skills -- add #tag or #sha to prevent drift

[*] Installed 1 APM dependency in 6.4s.

ndmm_monuments % apm install oracle/skills/db --target codex

[*] Validating 1 package...

[+] oracle/skills/db

[*] Updated apm.yml with 1 new package(s)

[>] Installing 1 new package...

[>] Resolving skills-db...

[i] Targets: codex  (source: --target flag)

  [+] github.com/oracle/skills/db #default @fcbc9430

  |-- Skill integrated -> .agents/skills/

  [!] 1 dependency unpinned: oracle/skills -- add #tag or #sha to prevent drift

[*] Installed 1 APM dependency in 6.7s.

ndmm_monuments % apm deps list                              

                                       APM Dependencies (Project)                                      

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━┓

┃ Package                     ┃ Version ┃ Source   ┃ Prompts ┃ Instructions ┃ Agents ┃ Skills ┃ Hooks ┃

┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━┩

│ oracle/skills/apex          │ unknown │ github   │    -    │      -       │   -    │   1    │   -   │

│ oracle/skills/db            │ unknown │ github   │    -    │      -       │   -    │   1    │   -   │

│ oracle/skills/apex/apexlang │ unknown │ orphaned │    -    │      -       │   -    │   1    │   -   │

└─────────────────────────────┴─────────┴──────────┴─────────┴──────────────┴────────┴────────┴───────┘

[!] 1 orphaned package(s) found (not in resolved dependency graph):

[!]   - oracle/skills/apex/apexlang

[i] Run 'apm prune' to remove orphaned packages

ndmm_monuments % 


OpenAI ChatGPTのデスクトップ・アプリよりCodexを選択し、プロジェクトを作成します。

プロジェクトタイプにローカルを選択します。次へ進みます。


プロジェクト名は自然災害伝承碑マップとします。ソースフォルダに作成済みの作業フォルダーを割り当てます。

以上でプロジェクトを作成します。


プロジェクトを作成したのち、最初の指示として以下を与えました。概ね口頭での話し言葉で実施してほしい作業を伝えています。

SQLclの実行ファイルの位置、SQLclの保存済みの接続名、接続先となるスキーマ名やAPEXワークスペース名は作業を行う環境に合わせて変更します。
国土地理院からダウンロードした日本の自然災害伝承碑のGeoJSONのデータを、Oracle DatabaseにロードしてOracle APEXのマップ上に表示するアプリケーションを作成します。

データベースに接続するために使用するSQLclの実行ファイルは/opt/homebrew/bin/sqlclです。

接続先となるデータベースは、SQLclの保存済みの接続local-26ai-apexdevを使って接続します。

APEXアプリケーションを作成するワークスペースはAPEXDEVです。

保存済みの接続local-26ai-apexdevでは、スキーマAPEXDEVに接続されます。これはAPEXのワークスペースAPEXDEVのデフォルト・パーシング・スキーマです。

表などのデータベース・オブジェクトはスキーマAPEXDEV以下に作成します。

データを保存する表は、これから伝える条件で作成してください。

自然災害伝承碑のデータを利用するにあたって、公開されている以下のファイルの内容に配慮してください。
20260827_GeoJSON/0_はじめにお読みください(国土地理院コンテンツ利用規約).txt
20260827_GeoJSON/1_データについて_geojson.txt

ソースとなる自然災害伝承データは、 ファイル20260827_GeoJSON/20260827.geojsonに保存されています。

このGeoJSONファイルをデータベースの表にロードしてください。

作成する表はNDMM_MONUMENTSとします。

GeoJSONの1つのFeatureを1行として保存し、proppertiesはそれぞれ列として定義します。

Featureには、"ID", 碑名",  "建立年","所在地", "災害名", "災害種別", "伝承内容", "公開日", "修正等公開日", "制限事項" があります。

これらのFeatureを表の列として定義します。この他に自然災害伝承碑の座標を列として定義します。

表の列として定義するにあたり、列名は英語にしてください。データ型はファイルから実際のデータ型を参照して適切なデータ型を選んでください。

geometryについては、SDO_GEOMETRY型の列として保存してください。

データベースに表を作成したら、ファイル20260827_GeoJSON/20260827.geojsonの内容を作成した表NDMM_MONUMENTSにロードしてください。

データをすべて表NDMM_MONUMENTSにロードした後、geometryを保存した列にOracle Spatialの空間索引を作成してください。

これから、新規に作成するAPEXアプリケーションの要件を説明します。

新規に作成するAPEXアプリケーションの名前は「自然災害伝承碑マップ」とします。

アプリケーション別名はndmm_monumentsとします。

上記の表NDMM_MONUMENTSをデータ・ソースとしたファセット検索付きのマップ・リージョンを持つページを作成してください。

作成したページには、国土地理院コンテンツ利用規約に沿って、出典と行なった加工と編集について表示してください。

マップ・リージョンの他に、マップ上に表示されている自然災害伝承碑の行を一覧するクラシック・レポートのリージョンを作成してください。

災害種別と災害名をファセットとしてください。

マップ上にそれぞれの自然災害伝承碑を配置してください。

マップ上のポイントをクリックして開く情報ボックスに、表NDMM_MOMENTSのgeometryを除く列を表示するようにしてください。
APEXlangのスキルには、与えられた指示から作業プランをMarkdownファイルに生成してから作業を始めるようなワークフローが定義されている模様です。作業フォルダ以下には、そういった作業途中で生成されたファイルが残されています。


APEXlang形式のアプリケーションの保存先を聞かれたり、Chromeが起動して作成されたAPEXアプリケーションへのサインインを求められました。Chromeの操作のために、コンピュータの制御をCodex Computer Useが行えるように許可しておく必要があります。

22分で表の作成とデータロードを含めて、指示したAPEXアプリケーションが作成されました。


最初に作成されたアプリケーションです。修正したい部分がいくつか見つかりました。


災害種別のファセットが"洪水・土砂災害"のように、複数の種別がファセットの選択肢として1つになっていました。これはもともとGeoJSONの"災害種別"のプロパティの値が"洪水・土砂災害"であったためです。これを・で分割して、それぞれを災害種別として選択できるように変更を依頼しました。

「災害種別のファセットは複数の値を「はい」にして、区切り文字を・、そして選択した値はANDで表示する伝承碑を選択するように、ファセットの設定を変更してください。」


3分40秒で修正が完了しました。

表示中の自然災害伝承碑を一覧するクラシック・レポートとリージョンの間にパディングが含まれていていたため、削除するよう依頼しました。

「表示中の自然災害伝承碑のクラシック・レポートのパディングを削除して、リージョンの外枠との隙間を無くしてください。」


約7分で修正が完了しました。

クラシック・レポートのページ送りのコントロールがクラシック・レポートの右下のみに配置されていました。これを右上にも配置するよう依頼しました。

「ページ送りのコントールをリージョンの右下だけでなく、右上にも追加してください。」


13分半で修正が完了しました。人の感覚ではちょっとした作業なのですが、AIの作業としては時間がかかっていて不思議な感じがします。

地図をズーム・イン/アウトしたり移動したときに、地図の表示範囲に含まれる伝承碑がクラシック・レポートに一覧されています。この処理がファセットに適用されていませんでした。

同様の処理をファセットに実装するよう依頼しました。

「地図上に表示されている伝承碑はクラシック・レポートに反映されていますが、検索条件を表示するファセットには反映されていません。クラシック・レポートと同様にファセットにも反映するようにしてください。」

2回アプリケーションへのログインを要求されていますが、これは1回目は修正に失敗していてエラーが発生していました。そのエラーを修正した後に2回目のログインを要求されています。


約11分で修正が完了しました。

地図上のポイントをクリックしたときに表示される情報ボックスの大きさが縦に長く、地図上に全体が表示されずに溢れていたため、情報ボックスが横長になるように修正を依頼しました。

「地図上の伝承碑のポイントをクリックしたときに表示される情報ボックスですが、地図の領域からはみ出てすべての情報が表示されません。横幅を2倍に広げて、縦方向の長さは半分にしてください。」


約5分で修正が完了しました。

以上で、記事の先頭のGIF動画のアプリケーションが作成されました。

修正点のまとめです。


実は先日までCodexとGPT-5.6 Sol(中)で、同じ仕様のAPEXアプリケーションを作成していました。初回はコマンドラインのCodexで作成し、Codexだけで作成できることを確認するのにだいたい1日かかりました。次に作業環境をデスクトップ・アプリのCodexに移し、GPT-5.6 Sol(中)で同じ指示でアプリケーションを作成しました。これは半日程度かかりました。なかなか動くコードが生成されず、プロンプトの与え方を色々と変えたり追加のプロンプトが必要だったことと、Computer Useが今ひとつでCodexによるデバッグに制限があったためだと考えています。

GPT-5.6 Solで作業をしていたプロジェクトは削除し、新しくプロジェクトを作成した上でGPT-6 Astraで作業しているのですが、昨日までの作業の成功例が反映された結果、GPT-6 Astraの作業がスムーズに進んだ可能性はあります。

そのような可能性はありますが、それでもGPT-6 AstraによるAPEXアプリケーションの生成は印象的でした。

全ての指示を文字で与えていますが、与えた指示自体は話ことばにしています。おそらくAPEXアプリケーションは、AIコーディング・エージェントと会話をしながらでも作成できるでしょう。

今回、Codexが作成したAPEXアプリケーションのエクスポートを以下に置いています。
https://github.com/ujnak/APEXlang-exports/tree/main/ndmm_monuments

GPT-6 Astraが生成したコードも印象的です。

今回の記事は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。

完

2023年10月31日火曜日

国土交通省のデータを使って簡易的な逆ジオコーディングを実装する

Oracle APEXのマップ上でクリックした位置で逆ジオコーディングを行い、住所を取得する要件がありました。Oracle APEXやOracle Autonomous Databaseは無料で使えるジオコーディングAPIを提供していますが、Oracle Maps Cloud(Oracle eLocation Service - このリンクを見る範囲ではHEREのデータ)を呼び出しているためか、日本語および日本の住所をサポートしていません。

GoogleやAzureが提供しているマップ・サービスに含まれるAPIを呼び出すこともできますが、それほど厳密に住所が得られなくてもよいので、国土交通省からダウンロードできる行政区域と位置参照情報を使って簡易的な逆ジオコーディングを実装してみました。

Oracle Spatialの機能を活用しています。


クイックSQLの以下のモデルから表を3つ作成します。表MLIT_DATAは、国土交通省からダウンロードした行政区域データのファイルを保存するために使用します。表MLIT_MUNICIPALITY_ADMINSは行政区域データ、表MLIT_LOCATION_REFERENCESは位置参照情報を保存します。

SQLの生成、SQLスクリプトを保存、レビューおよび実行をクリックします。


SQLスクリプトが開きます。表MLIT_MUNICIPALITY_ADMINSの列GEOMETRYと
GEOM_Rの型をNUMBERからOracle Spatialのオブジェクトを保存するSDO_GEOMETRYへ変更します。また表MLIT_LOCATION_REFERENCESの列LOCATIONもSDO_GEOMETRYへ変更します。

変更したDDLを実行します。確認画面では即時実行をクリックします。


すべての行が成功しエラーがなければ、3つの表が作成されています。

この画面からはアプリケーションの作成は行いません。


アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。アプリケーションの名前は逆ジオコーディングとします。

アプリケーションの作成をクリックします。


アプリケーションが作成されます。

行政区域のファイルをアップロードする画面を作成します。

ページの作成を実行します。


対話モード・レポートを選択します。


対話モード・レポートのページ番号は2、名前は行政区域ファイル一覧とします。ページ・モードは標準です。フォーム・ページを含めるをオンにします。

フォーム・ページ番号は3、フォーム・ページ名は行政区域ファイル編集とします。フォーム・ページ・モードはドロワーとします。

データ・ソースの表/ビューの名前としてMLIT_DATAを指定します。

ナビゲーションはデフォルトから変更せず、ブラッドクラムの使用、ナビゲーションの使用ともにオンとします。

次へ進みます。


主キー列1としてID (Number)を選択します。

ページの作成をクリックします。


ページが作成されます。

対話モード・レポートのページのリージョン行政区域ファイル一覧に含まれる列CONTENTを選択します。BLOB属性のMIMEタイプ列にCONTENT_MIMETYPE、ファイル名列にCONTENT_FILENAME、最終更新列にCONTENT_LASTUPD、文字セット列にCONTENT_CHARSETを設定します。

保存をクリックします。


ページ・デザイナでページ番号3のフォームのページを開きます。

タイプがファイル参照のページ・アイテムP3_CONTENTを選択します。

設定のMIMEタイプ列にCONTENT_MIMETYPE、ファイル名列にCONTENT_FILENAME、文字セット列にCONTENT_CHARSET、BLOB最終更新列にCONTENT_LASTUPDを設定します。これらの項目のオンライン・ヘルプには「大文字のページまたはアプリケーション・アイテム名を入力します。」と記述されていますが、アイテム名ではなく列名です。(つまりP3_といった接頭辞は付かない)。


ページ・アイテムP3_CONTENT_FILENAME、P3_CONTENT_MIMETYPE、P3_CONTENT_CHARSET、P3_CONTENT_LASTUPDはユーザーによってデータを入力されることはないため、すべて選択して構成のビルド・オプションを使ってコメント・アウトします。

以上でファイルのアップロードができるようになりました。

保存をクリックします。


国土交通省のWebページより、行政区域のデータをダウンロードします。

TOP > 国土数値情報 > 行政区域データ



Webページを下にスクロールします。今回は神奈川県のデータを使用することにしました。

N03-20230101_14_GML.zipをダウンロードします。アンケートのページが表示されるので、アンケートに答えてダウンロードに進むをクリックします。


ダウンロードしたN03-20230101_14_GML.zipを解凍すると、範囲がGEOJSON形式で表現されているファイルN03-23_14_230101.geojsonが見つかります。このファイルをアップロードします。

アプリケーションを実行し、ナビゲーション・メニューから行政区域ファイル一覧を開きます。

作成をクリックします。


ドロワーが開きます。

ContentとしてN03-23_14_230101.geojsonを選択します。

作成をクリックして、選択したファイルを表MLIT_DATAにアップロードします。


行政区域のファイルがアップロードされました。


行政区域のデータを、区域ごとの行として表MLIT_MUNICIPALITY_ADMINSへロードする処理を追加します。

ページ・デザイナでページ番号3のフォームのページを開きます。

リージョン行政区域ファイル編集のRegion Bodyにボタンを作成します。

識別のボタン名はLOAD、ラベルはLoad、外観のテンプレート・オプションを開き、詳細のWidthにStretchを選択します。動作のアクションはデフォルトのページの送信のまま、変更しません。


アップロード済みのファイルをロードの対象とするため、サーバー側の条件のタイプとしてアイテムはNULLではないを選択し、アイテムとしてP3_IDを指定します。


プロセス・ビューを開き、ボタンを押した時に実行されるロード処理を定義します。

新しくプロセスを作成し、プロセスプロセス・フォーム行政区域ファイル編集とダイアログを閉じるの間に配置します。

識別の名前を行政区域データのロードとし、タイプに実行チェーンを選択します。データ量によっては行政区域データのロードに時間がかかることも考えられるため、バックグラウンドで実行させます。設定のバックグラウンドで実行をオンにします。

サーバー側の条件のボタン押下時にLOADを設定します。


実行チェーン行政区域データのロード上でコンテキスト・メニューを表示させ、子プロセスの追加を実行します。


識別の名前をロードとし、タイプはコードを実行を選択します。ソースのPL/SQLコードとして以下を記述します。


以上で表MLIT_MUNICIPALITY_ADMINSへのデータのロード処理が実装できました。


プロセスダイアログを閉じるを選択し、サーバー側の条件の値にLOADを追加します。LOADを押した時に、ドロワーが閉じるようになります。

保存をクリックします。


バックグラウンドで実行されるプロセスを確認するための、簡単なページを作成します。

ページの作成を開始し、対話モード・レポートを選択します。


ページ番号は4、名前はバックグラウンド処理とします。データ・ソースのソース・タイプとしてSQL問合せを選択し、SQL SELECT文を入力に以下を記述します。

select * from APEX_APPL_PAGE_BG_PROC_STATUS

ページの作成をクリックします。


バックグランド処理を一覧するページが作成されました。

アプリケーションを実行し、表MLIT_MUNICIPALITY_ADMINSへのデータ・ロードを実行します。

ナビゲーション・メニューから行政区域ファイル一覧を開き、すでにアップロード済みのファイルを選択します。

ボタンLoadをクリックし、データのロードを開始します。バックグラウンドで処理されるため、処理の完了を待たずにドロワーは閉じます。


バックグラウンド処理のページを開き、処理が正常に終了していることを、列StatusやStatus Codeから確認します。


表MLIT_MUNICIPALITY_ADMINSの列GEOM_R(rectify実行後のデータ)に、行政区域を表す矩形データが準備できました。逆ジオコーディングを実行する際に、最初に指定した地点がどの行政区域に含まれるかを探し、見つけた行政区域内で住所を検索します。指定した地点が含まれる行政区域の検索を速くするために、列GEOM_Rに空間索引を作成します。

オブジェクト・ブラウザを開き、表MLIT_MUNICIPALITY_ADMINSを選択します。索引タブを開き、作成をクリックします。


索引のタイプとして空間を選択します。索引名はデフォルトでMLIT_MUNICIPALITY_ADMINS_SXになるので、そのまま使用します。索引列1にGEOM_Rを指定します。システム管理索引はオン、表にはポイント・オブジェクトのみが含まれるはオフです。

列GEOM_Rの空間メタ・データが未登録の場合、索引の作成の代わりに列の登録というボタンが表示されます。

列の登録をクリックします。


座標系や許容範囲の値が表示されます。通常、変更は不要です。

空間メタデータの追加をクリックします。


APEX 23.1ではエラーが発生し、空間メタデータの作成ができません。おそらく不具合です。


ワークアラウンドとして、SQLのプレビューをクリックし、表示されたSQLをSQLコマンドから実行します。

SQLをコピーします。


一旦、索引の作成を取消し、SQLコマンドからコピーしたSQLを実行します。


列GEOM_Rの空間メタデータが作成されました。先ほどと同じ手順で空間索引の作成を行います。

空間メタデータが作成済みなため、Spatialレジストリに列GEOM_Rの座標系IDと座標系名が表示されます。(実際は国土交通省の行政区域データの座標系IDは6668、座標系名はJGD2011ですが、4326、WGS84として扱っても問題ないと判断しています)。

索引の作成をクリックします。


空間索引MLIT_MUNICIPALITY_ADMINS_SXが作成されます。ステータスがVALIDであることを確認します。


以上で行政区域データの、データベースへのロードが完了しました。

続いて、位置参照情報をデータベースにロードします。

国土交通省のWebページから位置参照情報をダウンロードします。

国土数値情報ダウンロードサイトの位置参照情報を開き、都道府県単位をクリックします。


今回の作業は神奈川県に限定しているため、都道府県選択として神奈川県にのみチェックを入れます。データは全てを選択し、データ整備年度は令和4年にします。

選択をクリックします。


全ての街区レベルを選択、全ての大字・町丁目レベルを選択にチェックを入れます。

選択をクリックします。


利用約款の同意を求められます。利用約款を読み、同意できる場合は同意します。

利用約款に同意すると、以下のようなダウンロード画面が表示されます。今回は、市区町村全域の街区を含むデータをダウンロードします。


ダウンロードの確認を求められます。OKをクリックします。


今回の対象(神奈川県)では、ファイル14000-21.0a.zipがダウンロードされました。このファイルを解凍すると14_2022.csvというCSVファイルが含まれており、これに位置参照情報(住所と座標値)が記録されています。

このCSVファイルを表MLIT_LOCATION_REFRENCESにロードするために、データ・ロード定義を作成します。

共有コンポーネントのデータ・ロード定義を開きます。


作成をクリックします。


データ・ロードの作成として最初からを選択します。

次へ進みます。


ターゲットの名前は位置参照情報とします。ターゲット・タイプは表、表名にMLIT_LOCATION_REFERENCESを指定します。

次へ進みます。


サンプル・データとして先ほどダウンロードしたファイルに含まれているCSVファイル(今回の例では14_2022.csv)を選択します。

次へ進みます。


列見出しの最初の行にヘッダーが含まれるにチェックを入れ、ファイル・エンコーディングとして日本語(Shift JIS)を選択します。

列のマッピングとして、以下を指定します。

ソース列      マップ先
都道府県名             REGION
市区町村名             MUNICIPALITY
大字_丁目名           STREET
小字_通称名           PLACE_NAME
街区符号_地番       SEC_UNIT


座標系番号、X座標、Y座標はロード対象から外します(マップ先を設定しない)。

ソース列        マップ先
緯度                        LATITUDE
経度                        LONGITUDE
住居表示フラグ         IS_INDICATED_AS_RESIDENCE
代表フラグ               IS_REPRESENTED_ADDRESS
変更前履歴フラグ      OPERATION_PREVIOUS_YEAR
変更後履歴フラグ      OPERATION_CURRENT_YEAR

データ・ロードの作成をクリックします。


データ・ロード定義位置参照情報が作成されました。

表MLIT_LOCATION_REFERENCESの列LOCATIONおよびMUNICIPALITY_IDにデータを投入する設定(データ・プロファイル列)を追加します。

データ・ロード定義位置参照情報を開きます。


データ・プロファイルの編集をクリックします。


データ・プロファイルの定義画面が開きます。

列の追加をクリックします。


列LOCATIONのデータ・プロファイルを定義します。

列タイプにSQL式を選択します。名前はLOCATIONです。データ型としてジオメトリ(SDO_GEOMETRY)を選択します。

SQL式として以下を記述します。ロードされる行に含まれるLATITUDEとLONGITUDEの値から、SDO_GEOMETRY型のポイントのデータを生成しています。

sdo_geometry(2001, 4326,sdo_point_type("LONGITUDE","LATITUDE",null),null,null)

作成をクリックします。


同様の手順で列MUNICIPALITY_IDのデータ・プロファイルを定義します。MUNICIPALITY_IDには、この位置参照情報を含む行政区域のIDを設定します。

列タイプにSQL問合せ(単一の値を返す)を選択します。名前はMUNICIPALITY_IDです。データ型としてNUMBERを選択します。

SQL問合せとして以下を記述します。
select id from mlit_municipality_admins
where sdo_contains(geom_r,sdo_geometry(2001, 4326,sdo_point_type("LONGITUDE","LATITUDE",null),null,null)) = 'TRUE'
作成をクリックします。


以上で、データ・プロファイルの設定は完了です。

変更の適用をクリックします。


変更の適用をクリックし、データ・ロード定義の編集を終了します。


作成したデータ・ロード定義を使って、データ・ロードのページを作成します。

ページの作成をクリックします。


データ・ロードを選択します。


ページ番号は5、名前は位置参照情報ロードとします。データ・ロードとして先ほど作成した、位置参照情報を選択します。データのアップロード元はファイル、最大ファイル・
サイズ(MB)は100に上限を引き上げます。

ページの作成をクリックします。


データ・ロードのページが作成されます。

処理は時間がかかるため、ロード処理がバックグランドで実行されるように設定を追加します。

左ペインでプロセス・ビューを表示します。

プロセスを新規に作成します。識別の名前はバックグラウンド処理、タイプは実行チェーンとします。設定のバックグラウンドで実行をオンにします。

一時ファイル処理にMove、一時ファイル・アイテムとしてF5_FILEを選択します。

サーバー側の条件のボタン押下時にLOADを指定します。


プロセスデータのロードを選択し、識別の実行チェーンとしてバックグラウンド処理を指定します。


以上でデータ・ロードのページは完成です。

アプリケーションを実行し、作成した位置参照情報ロードのページを開きます。

ファイルの選択から、ダウンロードした位置参照情報のファイルを選択します。


プレビューが表示されます。データのロードをクリックします。


バックグラウンド処理を開いて、列StatusやSofarを見て実行状況を確認します。


データのロードが完了すると、神奈川県で逆ジオコーディングを行うための準備は完了です。

ホーム・ページにマップ・リージョンを作成し、逆ジオコーディングを実装します。

ページ・デザイナでホーム・ページを開きます。

マップ上で選択した位置の緯度経度を保持するためのページ・アイテムを作成します。

緯度を保持するページ・アイテムを作成します。識別の名前はP1_LATITUDE、タイプは数値フィールド、ラベルは緯度とします。


経度を保持するページ・アイテムを作成します。識別の名前はP1_LONGITUDE、タイプは数値フィールド、ラベルは経度とします。P1_LATITUDEの右に配置されるよう、レイアウトの新規行の開始をオフにします。


マップ・リージョンを作成します。

識別のタイトルは地図、タイプにマップを選択します。詳細の静的IDにmapを設定します。


レイヤーを選択します。

識別の名前を位置、レイヤー・タイプにポイントを選択します。ソースのタイプにSQL問合せを選択し、SQL問合せに以下を記述します。ページ・アイテムP1_LATITUDEとP1_LONGITUDEに設定されている座標にマーカーを表示します。

select to_number(:P1_LATITUDE) lat, to_number(:P1_LONGITUDE) lon from dual

送信するページ・アイテムとしてP1_LATITUDEとP1_LONGITUDEを設定します。

列のマッピングのジオメトリ列のデータ型として経度/緯度を選択し、経度にLON、緯度にLATを選択します。


地図上をクリックしたときに、クリックした位置の緯度経度をページ・アイテムP1_LATITUDEとP1_LONGITUDEに設定する動的アクションを作成します。クリックした位置にマーカーを表示するため、座標をページ・アイテムに設定した後に、リージョン地図をリフレッシュします。

リージョン地図上でコンテキスト・メニューを表示させ、動的アクションの作成を実行します。


作成された動的アクションの識別の名前は、地図をクリックとします。タイミングのイベントとして、マップがクリックされました[マップ]を選択します。選択タイプはリージョン、リージョンは地図です。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定のコードに以下を記述します。
apex.items.P1_LATITUDE.setValue(this.data.lat);
apex.items.P1_LONGITUDE.setValue(this.data.lng);
apex.region("map").refresh();


この状態で、マップ上の任意の地点をクリックすると、その位置の緯度経度の値が取得され、マーカーが移動します。


今回は神奈川県に限定して逆ジオコーディングを行うので、初期位置を横浜駅にします。

リージョン地図を選択し、プロパティ・エディタの属性タブを開きます。

初期位置およびズームのタイプに静的値、経度に139.62261961841、緯度に35.46606942124を指定します。ズーム・レベルは8にします。

レイヤーは1つだけなので、凡例の表示はオフにします。


今まで準備したデータを使って逆ジオコーディングを行うパイプライン表関数do_reverse_encodingを作成します。以下のスクリプトを実行します。


SQLスクリプトなどを使って実行します。


逆ジオコーディングを行なって得られた住所をページ・アイテムの選択リストに表示します。

ページ・アイテムを作成します。

識別の名前をP1_ADDRESS、タイプは選択リスト、ラベルは住所とします。

LOVのタイプをSQL問合せとし、SQL問合せとして以下を記述します。クリックした地点に近い順の住所を5つまで取得しています。
select address d, address r
from (
    select region || ' ' || municipality || ' ' || street || ' ' || sec_unit address
    from table(do_reverse_geocoding(
        p_latitude => to_number(:P1_LATITUDE)
        ,p_longitude => to_number(:P1_LONGITUDE)
        ,p_count => 5
    ))
)
追加値の表示はオフ、NULL値の表示もオフにします。

座標が変わった時に住所が更新されるよう、カスタケードLOVの親アイテムとしてP1_LATITUDEとP1_LONGITUDEを指定します。親が必要はオンです。


以上で、逆ジオコーディングを行うアプリケーションは完成です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回は神奈川県の行政区域と位置参照情報を紐づけて、行政区域で絞り込んでから座標に近い住所を探しています。そのため、行政区域と位置参照情報の紐付けを行なっていますが、いくつかの住所は行政区域に紐づけられませんでした。

以下のSELECT文の結果をマップに表示して確認しました。
select location, municipality, street, sec_unit from mlit_location_references where municipality_id is null and operation_current_year <> 3

地図の表示は以下になります。


一部を拡大すると、位置参照情報が県境を超えている場合があるようです。


地図データの扱いも色々と考慮しないといけないことが多いみたいです。

今回のアプリケーションはAlways FreeのAutonomous Databaseに実装しています。地域を神奈川に限定しているため、なんとか応答が返ってきていますが、全国のデータを扱うとどの程度の応答時間になるかは分かりません。そのような場合、表MLIT_MUNICIPALITY_ADMINSおよびMLIT_LOCATION_REFERENCESをパーティション分割し、パラレル問合せを発行することで応答時間が短縮できるでしょう。パーティションは単純なハッシュ分割で良いかと思います。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-reverse-geocoding.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

完