2025年10月17日金曜日

Protégé DesktopにOracle Pluginを組み込む

Stanford大学が開発しているオープン・ソースのオントロジー・エディタProtégéのデスクトップ版Protégé Desktopに、Oracleに接続するプラグインを組み込んでみます。

OracleのプラグインはOracle JDK 17以降で動作します。Protégé Desktopに含まれているOpenJDK 11のJREでは動作しません。そのため、Protégé Desktopのプラットフォーム非依存版を使用します。

Protégé DesktopにOracleのプラグインを組み込むには、以下のソフトウェアが必要です。
  • Oracle JDK 17以降
  • Protégé Desktopのプラットフォーム非依存版
  • Protégé DesktopのOracleプラグイン
それぞれのアーカイブをダウンロードして、Oracleプラグインを組み込んだ状態でProtégé Desktopを起動するまでの作業を実施します。

作業はmacOSで実施します。Protégé Desktopのプラットフォーム非依存版を使用するため、LinuxやWindowsでも、概ね似たような手順でセットアップができるのではと思います。


Oracle JDK 17のダウンロード



OracleのJava Downloadsのページにアクセスします。


本記事はmacOSで作業しているため、macOSのARM64 DMG Installerをダウンロードしてインストールします。


それぞれの環境に合わせたJDKをダウンロードし、インストールします。


Protégé Desktopのプラットフォーム非依存版のダウンロード



GitHub上のProtégéのReleasesのページを開きます。


最新リリースのAssetsに含まれる、-platform-independent.zipが付いたアーカイブをダウンロードします。2025年10月17日現在では、Protege-5.6.8-platform-independent.zip がそのファイルになります。



Oracleプラグインのダウンロード



Protégé DesktopのOracleプラグインを含むアーカイブは、Oracle Software Delivery Cloudからダウンロードします。


サインインにはOracleプロファイルが必要です。

Oracle Graph - Support Adaptors and Pluginsで検索します。

いくつかのパッケージが見つかります。その中の以下をダウンロードします。

Oracle Graph - Support Adaptors and Plugins 19c and 23a


リンクをクリックしてダウンロードするアイテムとして追加します。

View Itemsをクリックすると、ダウンロード対象のアイテムを確認できます。

Continueをクリックします。


Oracle Graph - Support Adaptors and Plugins 19c and 23a をチェックし、Continueをクリックします。


ライセンス確認の画面が表示されます。同意するとダウンロードのページが開きます。

V1051657-01(V1051657-01.zip)のリンクをクリックします。V1051657-01.zipが手元にダウンロードされます。


以上でProtégé Desktopのプラグインを含んだアーカイブがダウンロードできました。


Protégé Desktopの実行



Oracle JDK 17はインストール済みとします。作業ディレクトリを作成し、ダウンロードした2つのアーカイブ、Protege-5.6.8-platform-independent.zipV1051657-01.zipを配置します。

Protege % ls

Protege-5.6.8-platform-independent.zip V1051657-01.zip

Protege % 


ファイルV1051657-01.zipに含まれるprotege_pluginを解凍します。

unzip V1051657-01.zip "protege_plugin/*"

Protege % unzip V1051657-01.zip "protege_plugin/*"

Archive:  V1051657-01.zip

   creating: protege_plugin

  inflating: protege_plugin/OraclePlugin_Protege550-3.12.0.jar  

   creating: protege_plugin/doc

  inflating: protege_plugin/doc/Protege5_5_Guide.pdf  

  inflating: protege_plugin/OWLUpdater.jar  

Protege % 


Protégé Desktopを解凍します。

unzip Protege-5.6.8-platform-independent.zip

ディレクトリProtege-5.6.8が作成され、その下にファイルが作成されます。
 

Protege % unzip Protege-5.6.8-platform-independent.zip 

Archive:  Protege-5.6.8-platform-independent.zip

   creating: Protege-5.6.8

   creating: Protege-5.6.8/app

   creating: Protege-5.6.8/bundles

   creating: Protege-5.6.8/conf

   creating: Protege-5.6.8/conf/deprecation

   creating: Protege-5.6.8/plugins

  inflating: Protege-5.6.8/app/Protege.icns  

  inflating: Protege-5.6.8/app/Protege.ico  

  inflating: Protege-5.6.8/run.bat   

  inflating: Protege-5.6.8/bundles/guava.jar  

  inflating: Protege-5.6.8/bundles/protege-launcher.jar  

  inflating: Protege-5.6.8/bundles/pfl-dynamic.jar  

  inflating: Protege-5.6.8/bundles/org.eclipse.equinox.registry.jar  

  inflating: Protege-5.6.8/bundles/gmbal.jar  

  inflating: Protege-5.6.8/bundles/jul-to-slf4j.jar  

  inflating: Protege-5.6.8/bundles/owlapi-osgidistribution.jar  

  inflating: Protege-5.6.8/bundles/asm-util.jar  

  inflating: Protege-5.6.8/bundles/management-api.jar  

  inflating: Protege-5.6.8/bundles/jaxb-api.jar  

  inflating: Protege-5.6.8/bundles/protege-common.jar  

  inflating: Protege-5.6.8/bundles/protege-editor-owl.jar  

  inflating: Protege-5.6.8/bundles/org.eclipse.jgit.jar  

  inflating: Protege-5.6.8/bundles/glassfish-corba-orb.jar  

  inflating: Protege-5.6.8/bundles/maven-artifact.jar  

  inflating: Protege-5.6.8/bundles/logback-classic.jar  

  inflating: Protege-5.6.8/bundles/slf4j-api.jar  

  inflating: Protege-5.6.8/bundles/logback-core.jar  

  inflating: Protege-5.6.8/bundles/asm-analysis.jar  

  inflating: Protege-5.6.8/bundles/org.eclipse.equinox.supplement.jar  

  inflating: Protege-5.6.8/bundles/asm.jar  

  inflating: Protege-5.6.8/bundles/jsr305.jar  

  inflating: Protege-5.6.8/bundles/javax.activation.jar  

  inflating: Protege-5.6.8/bundles/org.apache.servicemix.bundles.javax-inject.jar  

  inflating: Protege-5.6.8/bundles/glassfish-corba-omgapi.jar  

  inflating: Protege-5.6.8/bundles/pfl-basic.jar  

  inflating: Protege-5.6.8/bundles/JavaEWAH.jar  

  inflating: Protege-5.6.8/bundles/org.eclipse.equinox.common.jar  

  inflating: Protege-5.6.8/bundles/asm-tree.jar  

  inflating: Protege-5.6.8/bundles/commons-io.jar  

  inflating: Protege-5.6.8/bundles/protege-editor-core.jar  

  inflating: Protege-5.6.8/bundles/jaxb-core.jar  

  inflating: Protege-5.6.8/bundles/log4j-over-slf4j.jar  

  inflating: Protege-5.6.8/bundles/glassfish-corba-internal-api.jar  

  inflating: Protege-5.6.8/bundles/pfl-tf.jar  

  inflating: Protege-5.6.8/bundles/jaxb-impl.jar  

  inflating: Protege-5.6.8/bundles/org.apache.felix.main.jar  

  inflating: Protege-5.6.8/conf/deprecation/obi.yaml  

  inflating: Protege-5.6.8/conf/deprecation/basic.yaml  

  inflating: Protege-5.6.8/conf/deprecation/go.yaml  

  inflating: Protege-5.6.8/conf/logback.xml  

  inflating: Protege-5.6.8/conf/logback-win.xml  

  inflating: Protege-5.6.8/conf/config.xml  

  inflating: Protege-5.6.8/conf/jvm.conf  

  inflating: Protege-5.6.8/run.sh    

  inflating: Protege-5.6.8/plugins/explanation-workbench-3.0.1.jar  

  inflating: Protege-5.6.8/plugins/sparql-query-plugin-3.0.0.jar  

  inflating: Protege-5.6.8/plugins/code-generation-2.0.0.jar  

  inflating: Protege-5.6.8/plugins/owldoc-3.0.3.jar  

  inflating: Protege-5.6.8/plugins/existentialquery-2.0.0.jar  

  inflating: Protege-5.6.8/plugins/rdf-library-3.0.0.jar  

  inflating: Protege-5.6.8/plugins/ontograf-2.0.3.jar  

  inflating: Protege-5.6.8/plugins/elk-protege-0.6.0.jar  

  inflating: Protege-5.6.8/plugins/cellfie-2.1.0.jar  

  inflating: Protege-5.6.8/plugins/owlviz-5.0.3.jar  

  inflating: Protege-5.6.8/plugins/org.coode.dlquery-4.0.1.jar  

  inflating: Protege-5.6.8/plugins/swrltab-plugin-2.0.10.jar  

  inflating: Protege-5.6.8/plugins/org.semanticweb.hermit-1.4.3.456.jar  

  inflating: Protege-5.6.8/run.command  

Protege % 


ホーム・ディレクトリ直下に、プラグインを配置するディレクトリ~/.Protege/pluginsを作成します。

mkdir -p ~/.Protege/plugins

Protege % mkdir -p ~/.Protege/plugins

Protege % 


ディレクトリprotege_pluginの下にあるOraclePlugin_Protege550-3.12.0.jar ~/.Protege/pluginsの下にコピーします。この作業により、Protégé Desktopの起動時にOracleプラグインが組み込まれます。

cp protege_plugin/OraclePlugin_Protege550-3.12.0.jar ~/.Protege/plugins

Protege % cp protege_plugin/OraclePlugin_Protege550-3.12.0.jar ~/.Protege/plugins 

Protege % 


Protégé Desktopを起動します。ディレクトリProtege-5.8.6に移動します。

cd Protege-5.8.6

Protege % cd Protege-5.6.8

Protege-5.6.8 % 


デフォルトで選択されるjavaのバージョンが、Oracle JDK 17であることを確認します。

Protege-5.6.8 % java -version

java version "17.0.16" 2025-07-15 LTS

Java(TM) SE Runtime Environment (build 17.0.16+12-LTS-247)

Java HotSpot(TM) 64-Bit Server VM (build 17.0.16+12-LTS-247, mixed mode, sharing)

Protege-5.6.8 % 


Protégé Desktopの起動スクリプトrun.sh(Windowsではrun.bat)を実行します。

./run.sh

Protege-5.6.8 % ./run.sh

CompileCommand: exclude javax/swing/text/GlyphView.getBreakSpot bool exclude = true

******************************************************************************** 

**                                  Protege                                   ** 

******************************************************************************** 

 

----------------- Initialising and Starting the OSGi Framework ----------------- 

FrameworkFactory Class: org.apache.felix.framework.FrameworkFactory 

 

The OSGi framework has been initialised 

------------------------------- Starting Bundles ------------------------------- 

Starting bundle org.protege.common 

Starting bundle org.eclipse.equinox.common 

Starting bundle org.eclipse.equinox.supplement 

Starting bundle org.protege.editor.core.application 

Starting bundle org.eclipse.equinox.registry 

Starting bundle org.glassfish.pfl.pfl-dynamic 

Starting bundle log4j.over.slf4j 



[以下省略]


Protégé Desktopが起動します。メニューにOracleが含まれています。


PreferencesのPluginsを開くと、Oracle Plugin 3.12.0が組み込まれていることが確認できます。


今回の作業は以上になります。

xeoglを使ってブラウザに東京都デジタルツインの点群データを表示する

Oracle Databaseにアップロードした点群データをブラウザに表示する方法をChatGPTに聞いてみたところ、そのような用途にはxeoglというJavaScriptライブラリが使えると勧められました。コード生成についてはClaude Sonnet 4.5の方が精度が高いので、Claudeでサンプルとなる点群データを生成し、xeoglで表示するHTMLページを作ってもらいました。こちらがそのコードになります。

Claudeが生成したコードを元に、東京都デジタルツイン実現プロジェクト区部点群データのLasデータをブラウザに表示するAPEXアプリケーションを作成してみました。

作成した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はそれほど長い値ではないので、レイアウト列スパンを指定します。


表示するタイルを選択するページ・アイテム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のアプリケーション作成の参考になれば幸いです。