Oracle Databaseにアップロードした点群データをブラウザに表示する方法をChatGPTに聞いてみたところ、そのような用途には
xeoglというJavaScriptライブラリが使えると勧められました。コード生成についてはClaude Sonnet 4.5の方が精度が高いので、Claudeでサンプルとなる点群データを生成し、xeoglで表示するHTMLページを作ってもらいました。
こちらがそのコードになります。
作成したAPEXアプリケーションは以下のように動作します。ページ左の選択リストで、アップロードしたメッシュを選択して表示します。ズームなどのカメラのコントロールはAPEXのページ・アイテムにスライダーが無かったため、リージョンにタイプがrangeのINPUT要素を直に記述しています。
カメラ・コントールについてはClaudeが生成したコードをほぼそのまま流用していて、あまり動作について精査できていません。動かしている限りでは、概ね期待した動作はしています。
以下よりAPEXアプリケーションの作成手順を簡単に紹介します。
最初に、データベースにロードするLasデータをダウンロードします。東京都デジタルツイン実現プロジェクトの区部点群データの
オリジナルデータ(DSM)及びグランウドデータ(DEM)のページより、東京駅付近の09LD1884、09LD1885、09LD1894、09LD1895のメッシュを選択しダウンロードしました。他のメッシュは試していませんが表示できると思います。
この4つのメッシュ(Lasファイル)で合計1GB弱、CSVに変換すると1GBを超えます。Oracle Database Freeのような無料で使えるOracle Databaseの場合、サーバー側のリソースが潤沢ではないので、データベースに保存できるデータ量も限られていますし、また、サーバーが利用できるメモリも限られているため、1つのメッシュに含まれる点群も間引かないと(今回は1/10に間引きました)ブラウザにデータを返すことができません。
上記の4つのメッシュはZIPファイルとしてダウンロードされます。それらをunzipで解凍すると、それぞれ09LD1884.las、09LD1885.las、09LD1894.las、09LD1895.lasが作成されます。
これらのLasデータを含むファイルをCSVに変換します。変換には
LAStoolsに含まれるlas2txt64を使用します。LAStoolsの導入はプラットフォームごとに手順が異なります。本記事の作業で使用しているmacOSでは、リポジトリをクローンしてビルドしています。ビルド手順については
こちらの記事で紹介しています。
ダウンロードしたZIPファイルが存在するディレクトリより、SQLclでLasデータのロード先となるデータベースに接続し、以下のスクリプトを実行します。この後の作業で、アップロードした点群データを表示するAPEXアプリケーションを作成するため、接続先はAPEXのワークスペース・スキーマにします。
tokyo_pc % sql wksp_apexdev@localhost/freepdb1
SQLcl: 金 10月 17 11:42:07 2025のリリース25.2 Production
Copyright (c) 1982, 2025, Oracle. All rights reserved.
パスワード (**********?) ******
接続先:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.9.0.25.07
SQL> @prepare_tokyo_point_clouds
Table TOKYO_POINT_CLOUDSが削除されました。
Table TOKYO_POINT_CLOUDSは作成されました。
Archive: 09LD1874.zip
inflating: 09LD1874.las
csv
column_names off
delimiter ,
enclosures ""
double off
encoding UTF8
row_limit off
row_terminator default
skip_rows 0
skip_after_names
データを表にロードします WKSP_APEXDEV.TOKYO_POINT_CLOUDS
batch_rows 10000
batches_per_commit 10
clean_names transform
column_size rounded
commit on
date_format
errors 50
map_column_names off
method insert
timestamp_format
timestamptz_format
locale
scan_rows 100
truncate off
unknown_columns_fail on
#INFO 処理された行数: 6,385,968
#INFO エラーのある行数: 0
#INFO 最後にコミットされたバッチで処理された最後の行: 6,385,968
成功: エラーなしで処理されました
6,385,968行更新しました。
コミットが完了しました。
[09LD1875, 09LD1884, 09LD1885のメッシュ分、繰り返し]
Table TOKYO_POINT_CLOUD_TILESが削除されました。
Table TOKYO_POINT_CLOUD_TILESは作成されました。
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.9.0.25.07から切断されました
tokyo_pc %
以上でデータの準備は完了です。
APEXアプリケーションの作成に移ります。
空のAPEXアプリケーションを作成します。名前はxeogl point cloudとします。
アプリケーションが作成されます。機能はすべてホーム・ページに実装します。
ページ・デザイナでホーム・ページを開き、ページのデザインから始めます。
表示するタイルの選択とカメラのコントールを配置するリージョンを作成します。
識別の名前はControls、外観のテンプレートにBlank with Attributesを選択します。このリージョンは、タイル選択のリージョンとカメラ・コントロールのリージョンを横並びにするために作成しています。
タイル選択のためのリージョンTile Selectionを、リージョンControlsのサブ・リージョンとして作成します。タイルIDはそれほど長い値ではないので、レイアウトの列スパンに2を指定します。
表示するタイルを選択するページ・アイテムP1_TILE_IDを作成します。タイプは選択リスト、ラベルはTile IDとします。
LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select tile_id d, tile_id r from tokyo_point_cloud_tiles
追加値の表示はオフにします。
選択したタイルの点群をブラウザに表示するボタンDRAWを作成します。動作のアクションは動的アクションで定義とします。
ボタンDRAWをクリックしたときに実行される動的アクションをonClick DRAWとして作成します。TRUEアクションにJavaScriptコードの実行を選択し、設定のコードに以下を記述します。
createPointCloud();
ファンクションcreatePointCloudは静的アプリケーション・ファイルに記述し、ページ・ロード時にロードします。
リージョン
Controlsに、カメラ・コントロールを含む
サブ・リージョンを作成します。
名前は
Zoomとします。
タイプは静的コンテンツ、ソースのHTMLコードとして以下を記述します。直書きされたINPUT要素はAPEXのページ・アイテムとしては扱えませんが、APEXのアプリケーションで作れないわけではありません。
<label>ズーム: <span id="zoomValue">400</span></label>
<input type="range" id="zoom" min="-600" max="0" value="0" step="5">
<label>水平回回転: <span id="yawValue">0</span>°</label>
<input type="range" id="yaw" min="-180" max="180" value="0" step="5">
<label>垂直回転: <span id="pitchValue">0</span>°</label>
<input type="range" id="pitch" min="-89" max="89" value="0" step="5">
<label>中心座標 X: <span id="centerXValue">81308.9</span></label>
<input type="range" id="centerX" min="-800000" max="800000" value="0" step="5">
<label>中心座標 Y: <span id="centerYValue">-35609.3</span></label>
<input type="range" id="centerY" min="-800000" max="800000" value="0" step="5">
<label>中心座標 Z: <span id="centerZValue">10</span></label>
<input type="range" id="centerZ" min="-100" max="800" value="0" step="5">
リージョンTile Selectionの右隣に配置するため、レイアウトの新規行の開始をオフにします。
xeoglで使用するCANVAS要素を配置するリージョンを作成します。名前はxeoglとします。
ソースのHTMLコードに以下を記述します。
<canvas id="myCanvas" style="width:100%; height:800px"></canvas>
装飾は不要なので外観のテンプレートにBlank with Attributesを選択します。
ページ・プロパティのCSSのインラインに以下を記述します。
#myCanvas {
background: linear-gradient(to bottom, #1a1a2e, #0f0f1e);
}
input[type="range"] {
width: 100%;
}
以上でページのデザインは完成です。アプリケーションを実行すると、ホーム・ページが以下のように表示されます。
APEXアプリケーションにコードを埋め込みます。
データベースから点群データを取り出すAjaxコールバックを、GET_POINT_CLOUDSとして作成します。
ソースのPL/SQLコードとして以下を記述します。
メッシュに含まれるすべての点群を取り出すにはサーバーのメモリが足りないため、点群を取り出すにあたってSAMPLE(10)を付加し、取り出すデータを10%(1/10)に削減しています。
静的アプリケーション・ファイルとしてapp.jsを作成します。ファイルには以下のコードを記述します。
ページ・プロパティのJavaScriptのファイルURLに以下を記述し、ページ・ロード時にxeoglのライブラリと静的アプリケーション・ファイルapp.jsをロードするようにします。
https://cdn.jsdelivr.net/npm/xeogl@0.9.0/build/xeogl.min.js
#APP_FILES#app#MIN#.js
以上でアプリケーションは完成です。
アプリケーションを実行すると、タイルとして09LD1884、09LD1885、09LD1894、09LD1895が選択でき、それぞれをページに表示することができます。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/xeogl-point-cloud.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完