Oracle Mapsは、Webベースの高性能な対話型マッピング・アプリケーションを開発するための一連のテクノロジの名前です。Oracle Mapsは、MapViewerに同梱されています。
この章の主な項目は、次のとおりです。
Oracle Mapsは、次の主要なコンポーネントから構成されています。
マップ・タイル・サーバー: 事前に生成されるマップ画像タイルをキャッシングして表示します。
対象地物(FOI)サーバー: Oracle Spatialによって管理される地理空間地物をレンダリングします。
AjaxベースのJavaScriptマッピング・クライアント。(Ajaxは、asynchronous JavaScript and XMLの頭字語です。)このクライアントは、マップの閲覧および操作に適した機能と、柔軟なApplication Program Interface(API)を提供します。
マップ・タイル・サーバー(マップ画像キャッシング・エンジン)は、Oracle MapViewerなどのWeb対応マップ・プロバイダによってレンダリングされたマップ画像タイルのフェッチとキャッシングを自動的に実行します。また、キャッシングされたマップ画像タイルをクライアント(Oracle MapsクライアントAPIを使用して開発されたWebアプリケーション)に提供します。提供されたクライアントはその後、複数のマップ画像タイルをまとめ、1つのシームレスで大きなマップを自動的に作成します。それらのマップ画像タイルは事前に生成されキャッシングされるので、アプリケーション・ユーザーにはマップが高速に表示されます。
対象地物(FOI)サーバー(レンダリング・エンジン)は、Oracle Spatialによって管理される空間地物層のみでなく、アプリケーションによって作成されるポイント型、線型またはポリゴン型の個々の地理空間地物のレンダリングも実行します。そのようなFOI(通常は、レンダリング対象の画像も関連する一連の属性データも含まれる)は、その後クライアントに送信され、ユーザーによって操作されます。キャッシングされたイメージ・タイル(通常は静的コンテンツを表す)とは異なり、FOIは動的であり、リアルタイムのデータベース・コンテンツまたはアプリケーション・コンテンツを表します。動的なFOIとキャッシングされた静的なマップ・タイルを使用すると、Webマッピング・アプリケーションを構築できます。
JavaScriptマッピング・クライアントは、サーバーからマップ・コンテンツをフェッチしてクライアント・アプリケーションに表示するブラウザ側マップ表示エンジンです。また、マップのドラッグやクリックといったユーザーとの対話に関するマップ関連のカスタマイズ可能なコントロールをアプリケーションに提供します。JavaScriptマッピング・クライアントは、任意のWebアプリケーションまたはポータルと簡単に統合できます。
Oracle Mapsを使用して開発したWebマッピング・アプリケーションのアーキテクチャを、図8-1に示します。
アプリケーションは、Oracle Mapsアーキテクチャと次のようにやりとりします(図8-1を参照)。
アプリケーションは、JavaScriptを使用して開発され、WebブラウザのJavaScriptエンジン内で動作します。
アプリケーションは、JavaScriptマップ・クライアントを起動してマップ・タイル・サーバーからマップ画像タイルをフェッチし、Webブラウザにマップを表示します。
アプリケーションは、JavaScriptマップ・クライアントを起動してFOIサーバーから動的空間地物をフェッチし、マップ・タイル上に表示します。
JavaScriptマップ・クライアントが、アプリケーションに代わってユーザーとのマップ関連の対話を制御します。
マップ・タイル・サーバーは、マップ画像タイル・リクエストを受信すると、リクエストされたタイルがキャッシング済であるかどうかをまずチェックします。該当するタイルがキャッシング済の場合は、キャッシング済のタイルがクライアントに返されます。該当するタイルがまだキャッシングされていない場合は、該当するタイルをマップ・タイル・サーバーがフェッチしてキャッシュに格納した後、クライアントに返します。タイルは、MapViewerのマップ・レンダリング・エンジンまたは外部Webマップ・サービス・プロバイダから直接フェッチできます。
FOIサーバーは、リクエストを受信すると、MapViewerのマップ・レンダリング・エンジンを使用して地物画像を生成し、それらの画像を地物属性とともにクライアントに送信します。
図8-2は、Oracle Mapsを使用して作成した単純なアプリケーションのインタフェースを示しています。この例は、MapViewerに同梱されており、http://host:port/mapviewer/fsmc/sampleApp.htmlでアクセスできます。このアプリケーションを実行するには、http://host:port/mapviewer/fsmc/tutorial/setup.htmlの手順に従ってデータベース・スキーマおよび必要なマップ・タイル層を設定します。
図8-2に示したアプリケーションでは、顧客をマップ上に表示しています。このマップは、次の2つの層から構成されています。
マップ・タイル層では、海、郡の境界線、都市および高速道路が表示されます。Webブラウザに表示されるマップ・タイル層全体は、マップ・タイル・サーバーによってレンダリングされた複数のマップ画像タイルから構成されます。
FOI層では、マップ・タイル層上に顧客が赤のドット・マーカーで表示されます。顧客を表すマーカーをユーザーがクリックすると、情報ウィンドウが表示され、該当する顧客の一部の属性が表示されます。顧客のマーカーおよび属性は、FOIサーバーによってレンダリングされます。
これら2つの層以外に、マップの左下隅にはスケール・バー、右上隅にはナビゲーション・パネルが表示されます。
アプリケーション・ユーザーは、マウスを使用してマップをドラッグできます。その場合、マップに現在含まれている空間リージョンに対応して、新しいイメージ・タイルおよびFOIが自動的にフェッチされます。また、ユーザーは、組込みマップ・ナビゲーション・ツールを使用して画像のパンやズームを実行したり、「Show customers」ボックスを選択または選択解除して顧客(赤のドット・マーカー)の表示/非表示を切り替えたりすることもできます。
図8-2で示した単純なアプリケーションのソース・コード全体を、例8-1に示します。
例8-1 単純なアプリケーションのソース・コード
<html>
<head>
<META http-equiv="Content-Type" content="text/html" charset=Shift_JIS">
<TITLE>A sample Oracle Maps Application</TITLE>
<script language="Javascript" src="jslib/loadscript.js"></script>
<script language=javascript>
var themebasedfoi=null
function on_load_mapview()
{
var baseURL = "http://"+document.location.host+"/mapviewer";
// Create an MVMapView instance to display the map
var mapview = new MVMapView(document.getElementById("map"), baseURL);
// Add a map tile layer as background.
mapview.addMapTileLayer(new MVMapTileLayer("mvdemo.demo_map"));
// Add a theme-based FOI layer to display customers on the map
themebasedfoi = new MVThemeBasedFOI('themebasedfoi1','mvdemo.customers');
themebasedfoi.setBringToTopOnMouseOver(true);
mapview.addThemeBasedFOI(themebasedfoi);
// Set the initial map center and zoom level
mapview.setCenter(MVSdoGeometry.createPoint(-122.45,37.7706,8307));
mapview.setZoomLevel(4);
// Add a navigation panel on the right side of the map
mapview.addNavigationPanel('east');
// Add a scale bar
mapview.addScaleBar();
// Display the map.
mapview.display();
}
function setLayerVisible(checkBox)
{
// Show the theme-based FOI layer if the check box is checked and
// hide the theme-based FOI layer otherwise.
if(checkBox.checked)
themebasedfoi.setVisible(true) ;
else
themebasedfoi.setVisible(false);
}
</script>
</head>
<body onload= javascript:on_load_mapview() >
<h2> A sample Oracle Maps Application</h2>
<INPUT TYPE="checkbox" onclick="setLayerVisible(this)" checked/>Show customers
<div id="map" style="width: 600px; height: 500px"></div>
</body>
</html>
このサンプル・アプリケーションのコンポーネントとクライアント・アプリケーションを作成するプロセスについては、8.5.3項を参照してください。
この項では、Webブラウザ内でマップを表示する際にJavaScriptクライアントが様々なマップ・コンテンツを内部で編成する方法について解説します。アプリケーションは通常1つのマスターHTML DIVオブジェクトを1つのWebページに配置し、JavaScriptクライアントはそのDIVオブジェクト内に様々なコンテンツ層を追加します。
マップ・クライアントによって表示されるマップ・コンテンツは、一連の層によって編成されます。アプリケーション・スクリプトが適切なマップ・クライアントAPIを起動すると、1つのマップ・コンテナ内に一連のマップ層が作成されます。マップ・コンテナは、ユーザー定義のHTML DIVオブジェクトです。Webページ内では、マップ・コンテナのサイズと位置をカスタマイズできます。マップ層のレイアウトを、図8-3に示します。
図8-3で示したように、マップ・コンテンツ層には、マップ・タイル、テーマベースFOI、ユーザー定義のFOIまたはレッドライン、情報ウィンドウ、固定図という5つのタイプがあります。固定図層を除く層はすべて、ユーザーがマップをドラッグすると、まとまって移動します。これらの可動層は、マップがドラッグされたりズームされたりすると、マップ・クライアントによって自動的に更新されます。(固定図層が移動されることはありません。)
通常のOracle Mapsアプリケーションは、マップ・タイル層を1つ以上持ち、マップ・タイル・サーバーから事前に生成された一連のマップ画像タイルを組み立てて表示します。マップ・タイル層によって表示される静的マップ・コンテンツは、さほど変化しないため、通常はクライアント・アプリケーションによりバックグラウンド・マップとして使用されます。たとえば、8.1.2項および図8-2で説明したサンプル・アプリケーションの場合は、海、郡の境界線、都市および高速道路がすべて、マップ・タイル層として表示されています。マップ・タイル層で実行可能なユーザー操作は、マップのドラッグなどの一部の操作に限られています。
マップ・タイル層は通常、MapViewerベース・マップに関連付けられており、MapViewerサーバーによって管理されます。ただし、外部(MapViewer以外)のマップ・プロバイダにより提供されるマップ画像タイルをキャッシュできるように、マップ・タイル層を構成できます。
またOracle Mapsクライアントは、外部のタイル・サーバーによって提供されるカスタムまたは組み込まれた外部タイル層を表示することもできます。組込みのGoogle Mapsタイル層は、その一例です。組込みGoogle Mapsタイル層の詳細は、JavaScript APIドキュメントのクラスMVGoogleTileLayerを参照してください。(Google Mapsタイル層の上に独自の空間データをオーバーレイする必要がある場合、8.6項「Spherical Mercator座標系へのデータ変換」も参照してください)。
マップ・タイル層は常に、層階層の最下部に位置します。マップ・タイル層には、静的なマップ・コンテンツおよびバックグラウンド・マップ・コンテンツが表示されます。こうした層が複数含まれる場合、すべての層について座標系とズーム・レベルの定義が同一である必要があります。
内部では、マップ・タイル層は、マップDIVコンテナ・ウィンドウのサイズより大きいのが普通です。そのため、ブラウザは、その他のタイルのフェッチおよびキャッシングを実行できます。その結果、それらのタイルは、マップ層がユーザーによってドラッグされるとすぐに表示されます。
テーマベースFOI層は1つ以上存在できます。それぞれのテーマベースFOI層は、MapViewerの事前定義済テーマで定義されている特定の問合せ基準を満たす一連の対話型FOIから構成されています。FOIは、ポイント、線またはポリゴンの場合があります。たとえば、売上高が10万ドルを超えている店舗をすべて、ポイントのテーマベースFOI層として表示することもできます。
ユーザーは、マウスを重ねたり、クリックしたりすることにより、FOIを操作できます。アプリケーションでは、そのようなユーザー操作に対するマップ・クライアントの反応方法をカスタマイズできます。
テーマベースFOI層の地物(地理的および非地理的)はすべて、データベースに格納されます。クライアント・アプリケーションから地物がリクエストされると、FOIサーバーにより地物に対して問合せとレンダリングが実行されます。テーマベースFOI層をサーバーからリフレッシュすることなくマップをドラッグできるような余地を設けられるように、テーマベースFOI層の問合せウィンドウをカスタマイズして、マップDIVウィンドウよりも大きくできます。テーマベースFOI層の詳細は、8.3.1項を参照してください。
ユーザー定義FOIとは、クライアント側で定義されるインタラクティブな地物のことです。FOIは、ポイント地物、線地物またはポリゴン地物の場合があります。ユーザーは、テーマベースFOIの場合と同じ方法で、ユーザー定義FOIを操作できます。ただし、一連の地物としてレンダリングされるテーマベースFOI層の場合とは対照的に、ユーザー定義FOIのリクエストおよびレンダリングは個々に実行されます。ジオメトリの表現やレンダリング・スタイルも含め、ユーザー定義FOIの属性はすべて、アプリケーションで提供する必要があります。たとえば、ユーザー指定の始点アドレスおよび終点アドレスに基づいたルート・ジオメトリは、ユーザー定義の線FOIとしてマップに表示する必要があります。
ユーザー定義のFOI層の処理は、アプリケーションが動作するWebブラウザにより、次のように異なります。
Microsoft Internet Explorerの場合は、アプリケーションによって追加されたユーザー定義の各FOIがすべて、テーマベースFOI層のすぐ上の層の中に配置されます。該当する層は、最大1つしか存在できません。
OperaおよびMozillaベースのブラウザ(Netscape、Firefoxなど)の場合は、ユーザー定義の各FOIがすべて2つの層(一方はポイント地物用、他方はポリラインやポリゴンなどの非ポイント地物用)の内部に配置されます。非ポイント地物層は、ポイント地物層の下に配置されます。
情報ウィンドウとは、マップ内のカスタマイズ可能なコンテンツが表示される小さなポップアップ・ウィンドウのことです。どの情報ウィンドウも、表示される場合は、ユーザー定義の各FOI層(複数可)のすぐ上の層内に配置されます。情報ウィンドウ層は、最大で1つしか存在できません。
マップ・タイル・サーバーは、事前に生成される固定サイズのマップ画像タイルをキャッシングして表示するマップ画像キャッシング・エンジンです。マップ・タイル・サーバーは、MapViewerサーバーの一部であるJavaサーブレットとして実装されます。マップ・タイル・サーバーは、タイルのズーム・レベルおよびタイル位置(メッシュ・コード)によって指定されたマップ画像タイルを要求するリクエストを受け付け、リクエストされたタイルをクライアントに返送します。
マップ・タイル・サーバーの基本的なワークフローを、図8-4に示します。
図8-4のように、マップ・タイル・サーバーは、マップ・タイルを求めるリクエストを受信すると、該当するタイルをキャッシュ・ストレージ・システム内で検索します。該当するタイルがキャッシュされていると、マップ・タイル・サーバーはそのタイルをクライアントに送信します。該当するタイルがキャッシュされていない場合は、該当するタイルをフェッチしてキャッシュに保存した後、クライアントに送信します。
MapViewer管理ツールを使用すると、マップ・タイル・サーバーを管理できます。
この項では、Oracle Mapsを効果的に使用するために知っておくべき、マップ・タイル・サーバーに関する概念について説明します。
マップ・タイル層はすべてマップ・タイル・サーバーで管理されます。マップ・タイル・サーバーは、マップ・タイル層に属するマップ画像タイルのフェッチおよび格納を実行した後、マップ画像タイルをクライアントに返します。マップ・タイル・サーバーでは複数のマップ・タイル層を管理できます。
どのマップ・タイル層にも、事前定義済のズーム・レベルを複数持たせることができます。各ズーム・レベルに、0〜n-1(nはズーム・レベルの総数)のズーム・レベル番号のうち1つが割り当てられます。ズーム・レベル0は最もズーム・アウトしたレベル、ズーム・レベルn-1は最もズーム・インしたレベルです。
マップは、ズーム・レベルごとに、同一サイズの小さな一連のマップ画像タイルに均等に分割されています。クライアントは、そのズーム・レベルおよびタイル・メッシュ・コードによってマップ・タイルを指定します。
マップ・タイル層は、次の2つのタイプのソースから得られます。
MapViewer内部のベース・マップ(MapViewerマップ・レンダリング・エンジンによってレンダリングされる)。MapViewerベース・マップは、事前定義済の一連のテーマから構成され、データベース・ビューUSER_SDO_MAPS内で事前定義済である必要があります。
外部Webマップ・サービス・プロバイダによってレンダリングされたマップ。外部Webマップ・サービス・プロバイダは、Webを介したクライアント・リクエストに対してマップのレンダリングおよび表示を実行するサーバーです。外部マップ・サービス・プロバイダからマップをフェッチできるアダプタを正しく構成すると、マップ・タイル・サーバーは該当する外部マップ・サービス・プロバイダによって生成された一連のマップ・タイルをフェッチして表示できるようになります。(マップ・タイル・サーバーが内部で動作しているMapViewer以外のMapViewerインスタンスも、外部マップ・サービス・プロバイダとみなされます。)
Oracle Mapsでは、ローカル・ファイル・システムを使用して、キャッシュされたイメージ・タイルを格納します。この格納に使用されるパスは、マップ・タイル・サーバーの構成設定の一部としてカスタマイズできます。
マップ・タイル・サーバーでは、同一サイズの小さな矩形のイメージ・タイルとして一連のマップ画像をキャッシュし、管理します。タイル処理は現在、任意の2次元のデカルト座標系でサポートされています。測地座標系も、デカルト座標系であるかのようにマッピングされる場合(図8-5のように経度および緯度が単に2つの直交軸として取り扱われる場合)はサポートされています。
ズーム・レベルごとに、マップ・タイルはマップ座標系全体を2つの次元(XとY。図8-5では緯度と経度)に沿って均等に分割して作成されます。マップ・タイル・サーバーは、マップ画像タイルを作成する際、マップ座標系のこの次元情報を必要とします。そのため、マップ・タイル層の構成設定でこの情報を指定する必要があります。
マップ座標系全体は1つの矩形として表現でき、その境界線は(Xmin, Ymin)および(Xmax, Ymax)として指定します(Xminは座標系で許可される最小のX値、Yminは許可される最小のY値、Xmaxは許可される最大のX値、Ymaxは許可される最大のY値)。図8-5の場合、Xminは–180、Yminは–90、Xmaxは180、Ymaxは90です。
また、マップ・タイル・サーバーがマップ・スケールを計算できるように、座標系の空間参照ID(SRID)も指定する必要があります。
各マップ・タイルは、(Mx, My)という整数のペアとして定義されるメッシュ・コードによって指定します(MxはタイルのXディメンション・インデックス、MyはタイルのYディメンション・インデックスを指定する)。タイルがXminから始まるXディメンション上のi番目のタイルである場合、Mxはi-1になります。タイルがYminから始まるYディメンション上のj番目のタイルである場合、Myはj-1になります。マップ上のタイルのメッシュ・コードを、図8-6に示します。
JavaScriptマップ・クライアントは、Webブラウザにマップを表示するのに必要なタイルを自動的に計算し、メッシュ・コードを指定したリクエストをサーバーに送信します。メッシュ・コードはアプリケーションにとって透過的であり、アプリケーションの開発者はメッシュ・コードを直接取り扱う必要がありません。
マップの分割方法およびタイルの作成方法を決めるタイル処理ルールを作成する必要があります。マップ・タイル・サーバーは、そのようなタイル処理ルールを使用してマップを小さなマップ画像タイルに分割し、タイル・ストレージ・システムに格納します。そのようなルールは、JavaScriptマップ・クライアントも使用します。
1つのズーム・レベルに対応するタイルはすべて同じサイズなので、マップ・タイル・サーバーはタイルの分割を実行するために次の情報を必要とします。
画面ピクセルで指定したマップ・タイル画像のサイズ(幅と高さ)。これは、タイル画像の物理サイズです。
マップ座標系に従って指定されたタイル・サイズ。たとえば、マップで測地座標系を使用する場合、タイルの幅と高さは度の単位で指定します。このサイズは、タイルの幅と高さを使用して明示的に指定することもできますし、マップ・スケールを使用して暗黙的に指定することもできます。(マップ・スケールとタイル画像のサイズから、マップ座標系に従ってタイルの幅と高さを求めることができます。)
先の情報が、ズーム・レベルに対応するタイル処理ルールになります。どのズーム・レベルも、独自のタイル処理ルールを持つ必要があります。マップ・タイル・サーバーに対して構成設定を指定する場合は、8.2.2項で示すように、タイル処理ルールを定義する必要があります。
マップ・タイル・サーバーの構成設定は、ローカルな構成ファイルおよびデータベース・ビューに格納されています。それらの設定は、カスタマイズが可能です。
ロギング・オプションやデフォルトのキャッシュ・ストレージ・ディレクトリといったマップ・タイル・サーバーのグローバル設定は、MapViewer構成ファイルmapViewerConfig.xml(ディレクトリ$MAPVIEWER_HOME/web/WEB-INF/confの下)に格納されています。
マップ・タイル・サーバーの構成設定は、次の例で示すように、トップレベルの<mapperConfig>要素の中の<map_tile_server>要素で定義されています。
<map_tile_server> <tile_storage default_root_path="/scratch/tilecache/"/> </map_tile_server>
<tile_storage>要素は、マップ・タイル・ストレージについての設定を指定します。default_root_path属性では、キャッシングされたタイル画像が格納されるデフォルトのファイル・システム・ディレクトリを指定します。デフォルトのルート・ディレクトリは、設定されていない場合または有効でない場合、$MAPVIEWER_HOME/web/tilecacheになります。マップ・タイル層の構成でそれ自体のマップ・タイル・ストレージ・ディレクトリが指定されていない場合は、今示したディレクトリの下にサブディレクトリが1つ作成され、マップ・タイル層用に使用されます。このサブディレクトリの名前は、マップ・タイル層の名前と同じになります。
マップ・タイル層の構成設定は、メタデータ・ビューUSER_SDO_CACHED_MAPSに格納されます。通常、このビューは直接操作せず、MapViewer管理ツールを介して使用して、マップ・タイル層を構成します。
どのデータベース・ユーザー(スキーマ)も、独自のUSER_SDO_CACHED_MAPSビューを持ちます。このビュー内の各エントリには、各マップ・タイル層の構成設定が格納されます。マップ・タイル層がMapViewer内部ベース・マップに基づく場合、そのマップ・タイル層に関連付けられているベース・マップは、マップ・タイル層の構成設定が格納されているのと同じデータベース・スキーマに定義されている必要があります。
マップ・タイル・サーバーは、MapViewerデータソースによって指定されているデータベース接続を使用してUSER_SDO_CACHED_MAPSビューに問合せを実行し、マップ・ソースの構成を取得します。この処理は、MapViewerの管理リクエストの結果としてマップ・タイル・サーバーが起動された場合またはMapViewerに新しいデータソースが追加された場合に実行されます。
USER_SDO_CACHED_MAPSビューには、表8-1に示す列があります。
表8-1 USER_SDO_CACHED_MAPSビュー
| 列名 | データ型 | 説明 |
|---|---|---|
|
NAME |
VARCHAR2 |
キャッシング対象マップ・ソースの一意な名前 |
|
DESCRIPTION |
VARCHAR2 |
キャッシング対象マップ・ソースのオプションの記述テキスト |
|
TILES_TABLE |
VARCHAR2 |
(現在は未使用) |
|
IS_ONLINE |
VARCHAR2 |
マップ・タイル層がオンラインの場合は |
|
IS_INTERNAL |
VARCHAR2 |
マップ・ソースが内部マップ・ソースの場合は |
|
DEFINITION |
CLOB |
マップ・タイル層のXML定義(この項で後述)。 |
|
BASE_MAP |
VARCHAR2 |
キャッシング対象のMapViewerベース・マップの名前(マップ・ソースが内部マップ・ソースの場合) |
|
MAP_ADAPTER |
BLOB |
外部マップ・サービス・プロバイダのアダプタJavaクラスが含まれるjarファイル(この項で後述)。 |
DEFINITION列の場合、マップ・ソースの定義は一般的に次の形式になります。
<map_tile_layer
name = “map tile layer name”
image_format ="tile-image-format">
<internal_map_source
data_source=”name-of-data-source”
base_map="name-of-MapViewer-base-map"
bgcolor="base-map-background-color"
antialias=”whether-to-turn-on-antialiasing”
/>
</internal_map_source>
<external_map_source
url="external-map-service-url"
adapter_class="name-of-adapter-class"
proxy_host=" proxy-server-host "
proxy_port="proxy-server-port"
timeout="request-timeout"
request_method="http-request-method: 'GET'|'POST'">
<properties>
<property name="property-name" value="property-value"/>
…
</properties>
</external_map_source>
<tile_storage
root_path="disk-path-of-cache-root-directory"
</tile_storage>
<coordinate_system
srid="coordinate-system-srid"
minX="minimum-allowed-X-value"
maxX="maximum-allowed-X-value"
minY="minimum-allowed-Y-value"
maxY="maximum-allowed-Y-value">
</coordinate_system>
<tile_image
width="tile-image-width-in-screen-pixels"
height="tile-image-height-in-screen-pixels" >
</tile_image>
<tile_bound>
<coordinates> … </coordinates>
</tile_bound>
<zoom_levels
levels="number-of-zoom-levels"
min_scale="map-scale-at-highest-zoom-level"
max_scale="map-scale-at-lowest-zoom-level"
min_tile_width="tile-width-specified-in-map-data-units-at-
highest-zoom-level"
max_tile_width="tile-width-specified-in-map-data-units-at-
lowest-zoom-level">
<zoom_level
description="zoom-level-description"
level_name="zoom-level-name"
scale="map-scale-of-zoom-level"
tile_width ="tile-width-specified-in-map-data-units"
tile_height ="tile-height-specified-in-map-data-units">
<tile_bound>
<coordinates> … </coordinates>
</tile_bound>
</zoom_level>
…
</zoom_levels>
</map_tile_layer>
マップ・タイル層を定義するXMLのDTDは、A.9項にリストされています。
例8-2は内部マップ・タイル層のXML定義、例8-3は外部マップ・タイル層のXML定義を示しています。<map_tile_layer>要素およびそのサブ要素の説明は、これらの例の後に示します。
例8-2 内部マップ・タイル層のXML定義
<?xml version = '1.0'?>
<!-- XML definition of an internal map tile layer.
-->
<map_tile_layer image_format="PNG">
<internal_map_source base_map="demo_map"/>
<tile_storage root_path="/scratch/mapcache/"/>
<coordinate_system
srid="8307"
minX="-180" maxX="180"
minY="-90" maxY="90"/>
<tile_image width="250" height="250"/>
<zoom_levels>
<zoom_level description="continent level" scale="10000000"/>
<zoom_level description="country level" scale="3000000"/>
<zoom_level description="state level" scale="1000000"/>
<zoom_level description="county level" scale="300000"/>
<zoom_level description="city level" scale="100000"/>
<zoom_level description="street level" scale="30000"/>
<zoom_level description="local street level" scale="10000"/>
</zoom_levels>
</map_tile_layer>
例8-3 外部マップ・タイル層のXML定義
<?xml version = '1.0'?>
<!-- XML definition of an external map tile layer.
-->
<map_tile_layer image_format="PNG">
<external_map_source
url="http://elocation.oracle.com/elocation/lbs"
adapter_class="mcsadapter.MVAdapter">
<properties>
<property name="data_source" value="elocation"/>
<property name="base_map" value="us_base_map"/>
</properties>
</external_map_source>
<tile_storage root_path="/scratch/mapcache"/>
<coordinate_system
srid="8307"
minX="-180" maxX="180"
minY="-90" maxY="90"/>
<tile_image width="250" height="250"/>
<!—
The following <zoom_levels> element does not have any
<zoom_level> element inside it. But since it has its levels,
min_scale and max_scale attributes set, map tile server will
automatically generate the <zoom_level> elements for the 10
zoom levels.
-->
<zoom_levels levels="10" min_scale="5000" max_scale="10000000" />
</map_tile_layer>
トップレベルの要素は<map_tile_layer>です。image_format属性ではタイル画像の形式を指定しますが、この属性で現在サポートされている値はPNG、GIFおよびJPGです。PNGおよびGIFの画像は一般に、ベクター・ベースのマップに適しています。一方、JPG画像は、圧縮率に優れているので、一般に衛星画像のようなラスター・マップに適しています。現在は、PNG形式のタイル画像のみ、バックグラウンドを透明にできます。
<internal_map_source>要素は、マップ・タイルがMapViewerのローカル・インスタンスによってレンダリングされる場合にのみ必須です。base_map属性は、必須であり、マップ・タイル・サーバーによってキャッシングされる事前定義済のMapViewerベース・マップを指定します。その値は、USER_SDO_CACHED_MAPSビュー内のBASE_MAP列のエントリに一致する必要があります。bgcolor属性は、オプションであり、マップのバックグラウンド・カラーを指定します。この属性の値をNONEに設定すると、バックグラウンドは透明になります。(現在、MapViewerでレンダリングできるのは、透明なPNGマップ・タイルのみです。)
<external_map_source>要素は、マップ・タイルが外部マップ・サービス・プロバイダによってレンダリングされる場合にのみ必須です。この要素には、次の属性があります。
url属性は、必須であり、マップ・タイルをフェッチできるマップ・サービスのURL(http://myhost/mapviewer/omserverなど)を指定します。
adapter_class属性は、必須であり、パッケージ名が含まれる、マップ・アダプタ・クラスのフルネーム(mcsadapter.MVAdapterなど)を指定します。
proxy_host属性およびproxy_port属性は、プロキシ・サーバーを介して外部マップ・プロバイダ・サーバーにアクセスする必要がある場合にのみ必要であり、それぞれプロキシ・サーバーのホスト名およびポート番号を指定します。proxy_hostをNONEとして指定すると、マップ・タイル・リクエストはすべて、プロキシ・サーバーを経由することなく、リモート・サーバーに直接送信されます。proxy_hostを省略するか、空白を指定すると、マップ・タイル・リクエストの送信時に、mapViewerConfig.xmlファイルで定義されているMapViewerのグローバル・プロキシ設定が使用されます。
timeout属性は、オプションであり、外部マップ・タイル画像に対するマップ・タイル・サーバーの最大待ち時間(ミリ秒数)を指定します。デフォルトのタイムアウト値は15000です。
request_method属性は、オプションであり、マップ・タイル・リクエストを送信する場合のHTTPリクエスト・メソッドです。その値は、POST(デフォルト)またはGETです。
<external_map_source>要素内の<properties>要素には<property>要素を複数含めることができ、そのそれぞれではマップ・タイルをフェッチする際にマップ・アダプタが使用する各ユーザー定義パラメータを指定します。マップ・ソース・アダプタが同一でも、別々のパラメータ・セットを使用すれば、別々のマップ・タイル層をフェッチできます。たとえば、MapViewerに同梱されているサンプルのMapViewerアダプタmcsadapter.MVAdapterでは、次のように定義されているパラメータを受け付けます。
<properties> <property name="data_source" value="elocation"/> <property name="base_map" value="us_base_map"/> </properties>
ただし、このアダプタを使用する場合は、value属性の値を変更すれば、同一のデータソースまたは他のデータソースから、別のベース・マップをフェッチできます。
<tile_storage>要素は、マップ・タイル層のストレージ設定を指定します。オプションのroot_path属性では、タイル・ストレージのルート・ディレクトリとして使用するファイル・システム・ディレクトリを指定します。この属性が省略されているか無効であると、mapViewerConfig.xmlファイルで定義されているデフォルトのルート・ディレクトリが使用されます。
<coordinate_system>要素は、マップ座標系を指定し、いくつかの必須属性があります。srid属性では、座標系の空間参照IDを指定します。minX属性ではXディメンションの下限、minY属性ではYディメンションの下限、maxX属性ではXディメンションの上限、maxY属性ではYディメンションの上限を指定します。標準の経度/緯度(WGS 84)座標系の場合、srid値は8307で、minX、minY、maxXおよびmaxYの値はそれぞれ-180、-90、180および90です。
内部マップ・タイル層の場合、マップ座標系はデータ座標系と異なっていてもかまいません。それらが異なっている場合、マップ・タイル・サーバーでは<coordinate_system>要素で定義されている座標系にマップ・データを変換し、その座標系を使用してマップ・タイル画像をレンダリングします。
<tile_image>要素は、タイル画像のサイズ設定を指定し、次の必須属性があります。つまり、widthではタイル画像の幅を画面ピクセル単位で指定し、heightではタイル画像の高さを画面ピクセル単位で指定します。
オプションの<tile_bound>要素では、キャッシングされたマップ・タイルの枠ボックスを指定します。マップ・タイル・サーバーでは、このボックス内のタイルのみをフェッチし、リクエストされたタイルがこのボックスの外部にある場合は空白のタイルを返します。枠ボックスは、マップ・データ座標系内で矩形によって指定します。該当する矩形は、<coordinates>要素により、次の形式で指定します。
<coordinates>minX, minY, maxX, maxY</coordinates>
キャッシュのデフォルトの枠ボックスは、<coordinate_system>要素で指定される枠ボックスと同じです。
<zoom_levels>要素では、事前定義済のズーム・レベルを指定します。事前定義済のズーム・レベルにある画像タイルのみが、マップ・タイル・サーバーによってキャッシングされ、表示されます。<zoom_levels>要素で持つことができる複数の<zoom_level>要素のそれぞれでは、事前定義済の1つのズーム・レベルを指定します。<zoom_level>要素が存在しない場合、マップ・タイル・サーバーは<zoom_levels>要素内の次の属性を使用して、<zoom_level>要素を自動的に生成します。(それらの属性は、省略が可能であり、いずれかの<zoom_level>要素が存在する場合は無視されます。)
levelsでは、ズーム・レベルの総数を指定します。
min_scaleでは、最高のズーム・レベル(最もズーム・インしたレベル)にあるマップ画像のスケールを指定します。
max_scaleでは、最低のズーム・レベル(最もズーム・アウトしたレベル)にあるマップ画像のスケールを指定します。
min_tile_widthでは、最高のズーム・レベルにあるマップ・タイルの幅を指定します。この幅は、マップ・データ単位で指定します。
max_tile_widthでは、最低のズーム・レベルにあるマップ・タイルの幅を指定します。この幅は、マップ・データ単位で指定します。
各ズーム・レベルの定義をマップ・タイル・サーバーが自動的に生成できるようにするには、前述の属性を次のように組み合せて指定する必要があります。
levels、min_scaleおよびmax_scale
levels、min_tile_widthおよびmax_tile_width
ズーム・レベルをこのように定義すると、マップ・タイル・サーバーは各ズーム・レベルの定義をすべて自動的に導出し、それらのズーム・レベルで生成された<zoom_level>要素を使用してXML定義を更新します。各ズーム・レベルはその後、必要に応じて調整できます。
各ズーム・レベルには、ズーム・レベルの定義順に基づいて、マップ・タイル・サーバーによりズーム・レベル番号が割り当てられます。<zoom_levels>要素内で定義される最初のズーム・レベルはズーム・レベル0、2番目のズーム・レベルはズーム・レベル1、...のようになります。これらのズーム・レベル番号は、事前定義済のズーム・レベルを参照するために、タイル・リクエスト内で使用されます。
<zoom_level>要素は、事前定義済のズーム・レベルを指定し、いくつかの属性を持ちます。description属性は、オプションであり、ズーム・レベルの説明文を指定します。level_name属性は、オプションであり、ズーム・レベルの名前を指定します。scale属性は、ズーム・レベルのマップ・スケールを指定し、tile_width属性およびtile_height属性が定義されていない場合は必須です。tile_width属性およびtile_height属性ではそれぞれ、タイルの幅および高さをマップ・データ単位で指定します。fetch_larger_tiles属性は、オプションであり、小さなマップ画像タイルのかわりに大きなマップ画像をフェッチするかどうかを指定します。値がTRUE(デフォルト)の場合は、複数のマップ・タイルから構成される大きなマップ画像がフェッチされ、小さなマップ画像タイルに分割されます。そのため、マップ・タイル・サーバーとマップ・サービス・プロバイダの間のネットワーク・ラウンドトリップを抑えられます。
<zoom_level>要素では、scale属性か、tile_width要素およびtile_height要素の両方を指定する必要があります。
<zoom_level>要素内の<tile_bound>要素では、ズーム・レベルに合せてキャッシュされたマップ・タイルの枠ボックスを指定します(オプション)。マップ・タイル・サーバーでは、このボックス内のタイルのみをフェッチし、リクエストされたタイルがこのボックスの外部にある場合は空白のタイルを返します。枠ボックスは、マップ・データ座標系内で指定された矩形によって指定します。該当する矩形は、<coordinates>要素(この項で前述)によって指定します。<zoom_level>要素内で<tile_bound>要素を指定すると、XML階層内で上位にある<tile_bound>要素で指定されているキャッシュの枠ボックスの設定全体が上書きされます。
外部マップ・ソース・アダプタは、マップ・タイル・サーバーと外部マップ・サービス・プロバイダの間のインタフェースです。外部マップ・サービス・プロバイダからマップ画像タイルをフェッチする必要がある場合、マップ・タイル・サーバーはタイルのズーム・レベル、サイズおよび位置に関する情報を指定して、外部マップ・ソース・アダプタをコールします。外部マップ・ソース・アダプタはその後、プロバイダに固有のリクエストを作成した後、そのリクエストを外部マップ・サービス・プロバイダに送信し、得られたイメージ・タイルをマップ・タイル・サーバーに返します。
外部マップ・ソース・アダプタは、1つのJavaクラスであり、Javaの抽象クラスoracle.mapviewer.share.mapcache.MapSourceAdapter(定義は次のとおり)を拡張する必要があります。
public abstract class MapSourceAdapter
{
public abstract String getMapTileRequest(TileDefinition tile);
public byte[] getTileImageBytes(TileDefinition tile) ;
public Properties getProperties() ;
}
このクラスを拡張するアダプタでは、次のメソッドを実装する必要があります。
public String getMapTileRequest(TileDefinition tile)
このメソッドでは、マップ・サービス・プロバイダに送信してマップ画像タイルをフェッチできるHTTPリクエスト文字列を作成するロジックを実装します。たとえば、マップ・タイルのURLがhttp://myhost/mymapserver?par1=v1&par2=v2&par3=v3の場合、このメソッドから返されるHTTPリクエスト文字列はpar1_v1&par2=v2&par3=v3になります。
マップ・タイル・サーバーは、特定のマップ・タイルが見つからない場合、getTileImageBytesメソッドをコールして該当するタイル画像のバイナリ・データをフェッチします。このメソッドは、getMapTileRequestメソッドをコールし、マップ・タイル・リクエストを作成して該当するタイルをフェッチします。getMapTileRequestメソッドが受け取る唯一のパラメータであるTileDefinitionオブジェクトでは、リクエストされたタイルのズーム・レベル、枠ボックス、画像サイズおよび画像形式を指定します。このメソッドでは、HTTPリクエスト文字列を返します。
また、マップ・ソース・アダプタは、クラスMapSourceAdapterに実装されているすべてのメソッドを継承します。それらの中で、他のメソッドに比べて重要なメソッドは次のとおりです。
public byte[] getTileImageBytes(TileDefinition tile)
このメソッドは、外部マップ・サービス・プロバイダから実際のバイナリ・マップ・タイル画像データをフェッチします。このメソッドは、実装済です。このメソッドは、抽象メソッドgetMapTileRequestをコールしてマップ・タイル・リクエストを作成し、そのリクエストを外部マップ・サービス・プロバイダに送信します。HTTPリクエストの送信によってマップ・タイルをフェッチできない場合は、このメソッドを上書きし、マップ・ソースから画像タイルをフェッチするための適切なロジックを実装できます。このメソッドが受け取る唯一のパラメータであるTileDefinitionオブジェクトでは、リクエストされたタイルのズーム・レベル、枠ボックス、画像サイズおよび画像形式を指定します。このメソッドは、マップ・タイル層の構成設定で指定されている画像形式でエンコードされたバイナリ・タイル画像データを返します。
public Properties getProperties()
このメソッドでは、8.2.2.2項で説明したマップ・タイル層の構成設定内で定義されている、プロバイダに固有のパラメータを返します。
MapSourceAdapterクラスおよびTileDefinitionクラスは、mvclient.jar($MAPVIEWER_HOME/web/WEB/libディレクトリ内)にパッケージされています。
外部マップ・ソース・アダプタの例を、例8-4に示します。
例8-4 外部マップ・ソース・アダプタ
/**
* This is a sample map source adapter that can be used to fetch map
* tiles from a MapViewer instance.
*/
package mcsadapter ;
import java.awt.Dimension;
import java.net.URL;
import java.util.Properties;
import oracle.lbs.mapclient.MapViewer;
import oracle.lbs.mapcommon.MapResponse;
import oracle.mapviewer.share.mapcache.*;
/**
* The map source adapter must extend class
* oracle.lbs.mapcache.cache.MapSourceAdapter.
*/
public class MVAdapter extends MapSourceAdapter
{
/**
* Gets the map tile request string that is to be sent to the map
* service provider URL.
* @param tile tile definition
* @return request string
*/
public String getMapTileRequest(TileDefinition tile)
{
// Get map source specified parameters
Properties props = this.getProperties() ;
String dataSource = props.getProperty("data_source") ;
String baseMap = props.getProperty("base_map") ;
// Use oracle.lbs.mapclient.MapViewer to construct the request string
MapViewer mv = new MapViewer(this.getMapServiceURL()) ;
mv.setDataSourceName(dataSource);
mv.setBaseMapName(baseMap);
mv.setDeviceSize(new Dimension(tile.getImageWidth(),
tile.getImageHeight()));
mv.setCenterAndSize(tile.getBoundingBox().getCenterX(),
tile.getBoundingBox().getCenterY(),
tile.getBoundingBox().getHeight());
int format = MapResponse.FORMAT_PNG_STREAM ;
String req = null ;
switch(tile.getImageFormat())
{
case TileDefinition.FORMAT_GIF:
mv.setImageFormat(MapResponse.FORMAT_GIF_URL);
req = mv.getMapRequest().toXMLString().replaceFirst(
"format=\"GIF_URL\"", "format=\"GIF_STREAM\"") ;
break ;
case TileDefinition.FORMAT_PNG:
mv.setImageFormat(MapResponse.FORMAT_PNG_URL);
req = mv.getMapRequest().toXMLString().replaceFirst(
"format=\"PNG_URL\"", "format=\"PNG_STREAM\"") ;
break ;
case TileDefinition.FORMAT_JPEG:
mv.setImageFormat(MapResponse.FORMAT_JPEG_URL);
req = mv.getMapRequest().toXMLString().replaceFirst(
"format=\"JPEG_URL\"", "format=\"JPEG_STREAM\"");
break ;
}
byte[] reqStr = null ;
try
{
reqStr = req.getBytes("UTF8") ;
}
catch(Exception e)
{}
// Return the request string.
return "xml_request="+ new String(reqStr);
}
}
MapSourceAdapter.getTileImageBytesメソッドの実装を、例8-5に示します。
例8-5 MapSourceAdapter.getTileImageBytesの実装
/**
* Fetches the map image tile from the external map service provider by
* sending the HTTP map tile request to the map service provider, and
* return the binary tile image data. You can rewrite this method so that
* the adapter can fetch the tile from an external map service provider
* that does not accept HTTP requests at all.
* @param tile the tile definition
* @return the binary tile image data.
* @throws Exception
*/
public byte[] getTileImageBytes(TileDefinition tile)
throws Exception
{
// construct request string
String request = getMapTileRequest(tile) ;
if(request == null)
{
throw new Exception("Null map tile request string in map source adapter!") ;
}
// set proxy settings
Proxy proxy = null ;
/* If the proxyHost is "NONE", the request is sent directly to the
* external server. If the proxyHost is a valid host, that host will
* be used as the proxy server. If the proxyHost is empty of omitted,
* the global proxy setting in mapViewerConfig.xml will be in effect.
*/
boolean noProxy = "NONE".equalsIgnoreCase(getProxyHost()) ;
if(getProxyHost()!=null && !noProxy)
{
SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort);
proxy = new Proxy(Proxy.Type.HTTP, addr);
}
// send the request and get the tile image binary
PrintWriter wr = null ;
BufferedInputStream bis = null;
try
{
String urlStr = mapServiceURL ;
if("GET".equalsIgnoreCase(httpMethod))
urlStr = mapServiceURL + "?" + request ;
log.finest("http "+httpMethod+": "+urlStr);
URL url = new URL(urlStr);
// Open a URL connection based on current proxy setting
URLConnection conn =
proxy!=null? url.openConnection(proxy):
(noProxy? url.openConnection(Proxy.NO_PROXY):
url.openConnection()) ;
conn.setConnectTimeout(timeOut);
if("GET".equalsIgnoreCase(getHTTPMethod()))
conn.connect();
else
{
conn.setDoOutput(true);
wr = new PrintWriter(conn.getOutputStream());
wr.print(request);
wr.flush();
wr.close();
wr = null ;
}
bis = new BufferedInputStream(conn.getInputStream());
byte[] result = toBytes(bis) ;
bis.close();
bis = null ;
return result;
}
catch(Exception ioe)
{
throw new Exception("Failed to fetch external map tile.", ioe);
}
finally
{
try
{
if(bis != null)
{
bis.close();
bis = null;
}
if(wr != null)
{
wr.close();
wr = null;
}
}
catch(IOException ioee)
{
throw ioee;
}
}
}
対象地物(FOI)とは、Webブラウザ内で動作するJavaScriptマップ・クライアントを使用して操作できるビジネス・エンティティまたは地理的地物のことです。FOIデータは、動的に表示され、マップ・タイル層の一部ではありません。FOIにはポイント、線文字列、ポリゴンなどの任意の空間ジオメトリ・タイプを使用できます。FOIの検索、参照、検査および操作機能は、位置ベースのサービスにとって必要不可欠です。
FOIサーバーは、MapViewer内で動作するJavaサーブレットです。FOIサーバーは、データベースに対する問合せ、FOI画像のレンダリング、およびクライアントに対するFOI画像とFOI属性データの送信を実行することにより、JavaScriptマップ・クライアントから受け取るFOIリクエストに応答します。JavaScriptマップ・クライアントは、FOI画像をエンド・ユーザーに表示し、画像を操作する機能を提供します。
FOIサーバーは、テーマベースおよびユーザー定義という2つのタイプのFOIリクエストを受け付けます。いずれのタイプのFOIリクエストも、リクエストのタイプに適したデータ層を返します。
テーマベースFOI層は、類似した特性を備えデータベースに格納される空間地物の集合です。クライアントは、テーマベースFOI層リクエストをFOIサーバーに送信することにより、テーマベースFOI層をフェッチします。このリクエストの結果として、特定の問合せ基準を満たす一連のFOIデータ・エントリが得られます。各FOIデータ・エントリは、該当するFOI画像と、JavaScriptマップ・クライアントがクライアント側の双方向性を実装する際に使用できる一連のFOI属性から構成されます。
テーマベースFOI層は、事前定義済のMapViewerテーマ(8.3.1.1項を参照)または動的JDBC問合せテーマ(8.3.1.3項を参照)に基づいており、FOIデータのレンダリングに必要なすべての情報を定義します。この情報には、ジオメトリ地物の格納先の表、データベース問合せ時に使用される基準、FOIデータの一部である属性およびFOI画像のレンダリング時に使用されるスタイルが含まれます。事前定義済テーマの定義および構成は、Map Builderツール(第9章を参照)を使用して行えます。
クライアントは、事前定義済テーマベースFOIリクエストを使用してFOIデータをリクエストする場合、事前定義済テーマの名前、地物画像のスケール、およびジオメトリ地物に対する問合せの際に使用する問合せウィンドウを指定する必要があります。テーマの名前はアプリケーションが定義する必要がありますが、地物画像のスケールおよび問合せウィンドウはJavaScriptマップ・クライアントによって自動的に計算されます。
たとえば、次のような定義を持つCUSTOMERSという名前の表上では、CUSTOMERSという事前定義済テーマを定義できます。
SQL> DESCRIBE CUSTOMERS Name Null? Type --------------------------------- ------ ---------------------------- NAME VARCHAR2(64 CHAR) CITY VARCHAR2(64 CHAR) COUNTY VARCHAR2(64 CHAR) STATE VARCHAR2(64 CHAR) LOCATION SDO_GEOMETRY SALES NUMBER
LOCATION列は、顧客マーカーのレンダリングに使用される空間列です。
CUSTOMERSテーマのXMLスタイリング・ルールを、例8-6に示します。
例8-6 FOI層用事前定義済テーマのXMLスタイリング・ルール
<?xml version="1.0" standalone="yes"?>
<styling_rules>
<hidden_info>
<field column="CITY" name="City"/>
<field column="SALES" name="Sales"/>
</hidden_info>
<rule>
<features style="M.CIRCLE"> </features>
<label column="NAME" style="T.TEXT"> 1 </label>
</rule>
</styling_rules>
例8-6のスタイリング・ルールでは、次の事柄を指定しています。それらの指定がマップ表示に与えている影響を見るには、8.1.2項の「図8-2 Oracle Mapsを使用して作成したアプリケーション」を参照してください。
マーカー・スタイルM.CIRCLEは、顧客のレンダリングに使用。
NAME列は、ラベル付け用属性として使用(label column="NAME")。NAME列の値(顧客の名前)は、ユーザーがマウスを顧客マーカーの上に移動したときにJavaScriptマップ・クライアントが表示する情報ウィンドウに含まれる。
情報ウィンドウには、該当する顧客の<hidden_info>要素(この例ではCITYおよびSALES)で指定されている列の値も含まれる。各<field>要素では、2つの属性を指定する。つまり、columnではデータベース列を指定し、nameでは情報ウィンドウで使用されるテキスト文字列を指定する。
MapViewerの事前定義済テーマには、標準の事前定義済テーマとテンプレート付き事前定義済テーマがあります。いずれのタイプの事前定義済テーマも、USER_SDO_THEMESビューを使用して定義します。ただし、標準の事前定義済テーマの問合せ条件は固定ですが、テンプレート付き事前定義済テーマの問合せ条件には動的なバインディング変数を含められ、それらの値はテーマ・リクエストの発行時に変更可能です。
バインディング変数を2つ使用するテンプレート付き事前定義済テーマのXMLスタイリング・ルールを、例8-7に示します(該当するテキストは<features>要素内の太字部)。
例8-7 テンプレート付き事前定義済テーマのXMLスタイリング・ルール
<?xml version="1.0" standalone="yes"?>
<styling_rules>
<hidden_info>
<field column="NAME" name="Name"/>
<field column="CITY" name="City"/>
<field column="SALES" name="Sales"/>
</hidden_info>
<rule>
<features style="M.CIRCLE">(city=:1 and sales>:2)</features>
<label column="NAME" style="T.TEXT"> 1 </label>
</rule>
</styling_rules>
例8-7では、必要条件を満たす地物が存在する都市の名前をバインディング変数:1、必要条件を満たす地物の最低売上高をバインディング変数:2で指定しています。(つまり、指定した都市で特定の最低値を超える売上高を持つ顧客のみに、店舗マーカーが表示されます。)これら2つのバインディング変数の値は、テーマの定義時には確定されず、クライアントがサーバーに送信するリクエストの中で与えられます。
クライアントは、動的JDBCテーマベースFOIリクエストを使用してFOIデータをリクエストする際、JDBCテーマの完全な定義を指定する必要があります。テーマの定義では、すべてのジオメトリ属性および非ジオメトリ属性を含め、レンダリング・スタイルと、FOIデータの問合せに使用されるSQL問合せを指定する必要があります。
例8-8は、各顧客位置の回りにバッファを表示するFOI層を作成するためのJavaScriptクライアント・コードを示しています。
例8-8 動的JDBC問合せのテーマ
var theme = '<themes><theme name="JDBC_THEME" >' +
'<jdbc_query asis="true" spatial_column="location"
jdbc_srid="8307" render_style="C.RED"
datasource="mvdemo">' +
'select sdo_geom.sdo_buffer(A.location,1,0.005,'+
'\'unit=mile arc_tolerance=0.005\') location '+
' from customers A' +
'</jdbc_query></theme></themes>' ;
buffertheme = new MVThemeBasedFOI('buffertheme',theme);
ユーザー定義FOIとは、クライアント側で定義される地物のことです。地物の集合としてレンダリングされるテーマベースFOI層とは異なり、ユーザー定義FOIの場合はリクエストとレンダリングが個々に実行されます。
ジオメトリの表現やレンダリング・スタイルも含め、ユーザー定義FOIの属性はすべて、アプリケーションで提供する必要があります。JavaScriptマップ・クライアントでは、ジオメトリ表現およびレンダリング・スタイルに関する情報を指定したリクエストを、FOIサーバーに送信します。FOIサーバーは、FOI画像をレンダリングし、クライアントに返します。レンダリング・スタイルは、USER_SDO_STYLESビュー内で事前定義済である必要があります。
Oracle Maps JavaScriptクライアントは、ブラウザベースのマップ視覚化エンジンであり、マップ・タイル・サーバーおよびFOIサーバーの上位で動作します。次の機能が実装されています。
マップ・タイル・サーバーからマップ・タイルをフェッチし、マップ・タイル層としてWebブラウザに表示する機能。
FOIリクエストをFOIサーバーに送信し、ユーザー定義の地物およびOracle Spatial問合せベースの地物をマップ・タイル層の上にオーバーレイ表示する機能。
マップ・ナビゲーション用のドラッグ、FOIのクリック、矩形の描画、レッドライニングなどのユーザー操作を制御する機能。
矩形の描画とは、アプリケーション・ユーザーが矩形の1つの隅をクリックした後、マウス・ボタンを押したままマウスを対角の隅までドラッグし、マウス・ボタンを離して矩形を作成することです。
レッドライニングとは、アプリケーション・ユーザーがマウス・ボタンをクリックした後、マウスを移動しクリックを複数回実行する(各クリックにより、まっすぐな線分を使用してレッドラインを伸ばす)ことにより、ポリゴンまたはポリラインを作成することです。(多くの場合レッドラインの描画は赤色でレンダリングされますが、任意の色を使用する線スタイルも指定できます。)
これらの機能にアクセスするには、いくつかのJavaScriptクラスから構成される次のようなJavaScript APIを使用します。
MVMapViewクラスは、該当APIのメインのエントリ・ポイントです。ほとんどのマップ制御インタフェースが実装されています。
MVMapTileLayerクラス(以前の名称はMVBaseMapクラス)は、マップ・タイル・サーバーによってレンダリングされたマップ・タイルを表示するマップ・タイル層を定義します。
MVThemeBasedFOIクラスでは、テーマベースFOI層の定義および制御を実行します。
FOIクラスでは、ユーザー定義FOIの定義と制御を実行します。
MVSdoGeometryクラスでは、ジオメトリ・オブジェクトを定義します。ジオメトリには、Oracle Spatialでサポートされている任意のジオメトリ・タイプを使用できます。
MVRedLineToolクラスでは、レッドライン・ユーティリティの定義および制御を実行します。
MVRectangleToolクラスでは、矩形ツールの定義および制御を実行します。
MVOverviewMapクラスでは、メイン・マップが小さな矩形としてミニチュア表示される概要マップ(自体は矩形ツール内にあるマップ)の定義および制御を実行します。
MVMapDecorationクラスでは、マップ装飾の定義および制御を実行します。
MVMapViewは、Webブラウザ内の全マップ操作におけるメインのエントリ・クラスです。ユーザーのWebマッピング・アプリケーションにロジックを追加するための必須のインタフェースはすべて、MVMapViewなどのクラスによって提供されます。そのような論理的インタフェースには、次のようなものがあります。
マップ・クライアント・インスタンスを作成し、それをWebページ内で作成したマップ・コンテナDIVオブジェクトと関連付けるもの。
マップの中心やズーム・レベルなどのマップ・パラメータを構成するもの。
マップ・タイル層を作成し、操作するもの。
テーマベースFOI層を作成し、操作するもの。
ユーザー定義の各FOIを作成し、操作するもの。
マップ上に情報ウィンドウを表示するもの。
マップ・タイトル、カスタムな著作権表示、コントロール・ボタンなどの固定のマップ装飾を作成するもの。
ナビゲーション・バー、スケール・バー、矩形ツール、レッドライン・ツール、概要マップなどの組込みユーティリティにアクセスするもの。
イベント・リスナーを使用してイベント処理をカスタマイズするもの。適切なAPIメソッドを使用すると、イベント・リスナーをMVMapViewクラス、MVThemeBasedFOIクラスおよびMVFOIクラスに追加できます。
Oracle Maps JavaScript API内の全クラスの詳細は、Javadocスタイルのリファレンス・ドキュメント(MapViewerに同梱されており、次の場所で利用可能)を参照してください。
http://host:port/mapviewer/fsmc/apidoc
すべてのマップ・データがOracleデータベースに格納されており、Oracle Fusion MiddlewareにMapViewerがデプロイされている場合は、この項で示す手順に従ってOracle Mapsを使用すれば、Webベースのマッピング・アプリケーションを開発できます。
MapViewerがサービスを提供するクライアント側に表示される各マップ・タイル層について、対応するマップ・タイル層をMapViewerサーバー側に作成する必要があります。たとえば、8.1.2項で説明したサンプル・アプリケーションの場合、クライアント側にマップ・タイル層として海、郡の境界線、都市および高速道路を表示するには、サーバー側にマップ・タイル層を作成する必要があります。ただし、タイル層がカスタムまたは組込み外部タイル層の場合、サーバー側にタイル層を定義する必要はありません。
マップ・タイル層を作成する場合は、マップ・タイル画像のレンダリング元となるマップ・ソースが使用可能な状態にあることを事前に確認する必要があります。データベースに格納されているマップ・データに基づいてマップ・タイル画像をレンダリングする場合は、事前定義済の一連のテーマから構成されるMapViewerベース・マップを作成する必要があります。(ベース・マップの作成は、第9章で説明するMap Builderツールを使用して行えます。)外部マップ・プロバイダを使用してマップ・タイル画像をレンダリングする場合は、マップ・タイル・サーバーによって指定されているタイル画像の定義を使用して外部サーバーからマップ画像をフェッチできるマップ・ソース・アダプタを作成する必要があります。
マップ・ソースが使用可能な状態にある場合は、1.5.3項で説明したように、MapViewer管理ページを使用して、マップ・タイル層を作成できます。マップ・タイル層を作成する場合は、適切な座標系の定義、マップ・ソースの定義(内部または外部)およびズーム・レベルの定義(ズーム・レベルの数とマップ・スケール)を指定する必要があります。
マップ・タイル層は、作成し終わったら、MapViewerに同梱されているJavaServer Page(JSP)デモ・アプリケーションを使用してテストできます。JSPデモ・アプリケーションには、http://host:port/mapviewer/fsmc/omaps.jspでアクセスできます。このアプリケーションでは、ユーザーの入力に基づいて、MapViewerインスタンスで定義されている任意のマップ・タイル層によって表示されるマップを表示できます。
データベース問合せの結果に基づきアプリケーションで動的地物をテーマベースFOI層として表示する必要がある場合は、テーマベースFOI層ごとに、事前定義済のMapViewerテーマを作成する必要があります。個々の動的地物をアプリケーションでユーザー定義FOIとして表示する必要がある場合は、FOIサーバーによって使用されるレンダリング・スタイル(複数可)を定義してFOI画像をレンダリングする必要があります。事前定義済のテーマおよびレンダリング・スタイルを作成するには、Map Builderツール(第9章を参照)を使用します。
Webブラウザ内で動作するOracle Mapsクライアント・アプリケーションは、プラグインを必要としない純粋なHTMLページやJavaScriptページです。したがって、そうしたアプリケーションは、純粋なHTMとしてコンテンツを配信する任意のWebテクノロジを使用して構築できます。そのようなテクノロジには、JavaServer Pages、Javaサーブレット、ASP、.NET C#などがあります。この項では純粋なHTML形式を使用したクライアント・アプリケーションの開発についてのみ説明しますが、この説明は他のWebテクノロジにも簡単に適用できます。
8.1.2項の例8-1で示したように、Oracle Mapsアプリケーションのソース・コードは通常HTMLページにパッケージされ、次の部分から構成されます。
<script>要素: Oracle Mapsクライアント・ライブラリをブラウザのJavaScriptエンジンにロードします。例8-1の場合、この要素は次のとおりです。
<script language="Javascript" src="jslib/loadscript.js"></script>
HTML DIV要素: Webページ内でマップ・コンテナとして使用されます。DIV要素のサイズと位置は、ユーザーのニーズに合せてカスタマイズできます。例8-1の場合、この要素は次のとおりです。
<div id="map" style="left:10; top:60;width: 600px; height: 500px"></div>
JavaScriptコード: マップ・クライアント・インスタンスの作成および初期化を実行します。マップ・クライアント・インスタンスの作成、初期マップ・コンテンツ(マップ・タイル層、FOI層など)の設定、初期マップの中心とズーム・レベルの設定、アプリケーションに固有なロジックの実装、マップの表示、およびその他のアプリケーションに固有なロジックの実装が実行されます。
このコードは、JavaScript関数(サーバーからクライアントWebブラウザにHTMLページがロードされたときに実行される関数)の中にパッケージします。例8-1の場合、この関数はon_load_mapviewという名前です。
function on_load_mapview()
{
var baseURL = "http://"+document.location.host+"/mapviewer";
// Create an MVMapView instance to display the map
var mapview = new MVMapView(document.getElementById("map"), baseURL);
// Add a map tile layer as background.
mapview.addMapTileLayer(new MVMapTileLayer("mvdemo.demo_map"));
// Add a theme-based FOI layer to display customers on the map
var themebasedfoi = new MVThemeBasedFOI('themebasedfoi1','mvdemo.customers');
themebasedfoi.setBringToTopOnMouseOver(true);
mapview.addThemeBasedFOI(themebasedfoi);
// Set the initial map center and zoom level
mapview.setCenter(MVSdoGeometry.createPoint(-122.45,37.7706,8307));
mapview.setZoomLevel(4);
// Add a navigation panel on the right side of the map
mapview.addNavigationPanel('east');
// Add a scale bar
mapview.addScaleBar();
// Display the map.
mapview.display();
}
この関数は、<body>要素のonload属性で指定するため、Webページがロードされた後に実行されます。例8-1の場合、このコードは次のとおりです。
<body onload= JavaScript:on_load_mapview() >
その他のHTML要素およびJavaScriptコード: アプリケーションに固有なその他のユーザー・インタフェースおよび制御ロジックを実装します。8.1.2項の例8-1の場合、JavaScript関数setLayerVisibleは、ユーザーが「Show customers」チェック・ボックスを選択または選択解除したときにテーマベースFOI層を表示または非表示にするために実装されています。setLayerVisible関数のコードは、次のとおりです。
function setLayerVisible(checkBox)
{
// Show the theme-based FOI layer if the check box is checked
// and hide the theme-based FOI layer otherwise.
if(checkBox.checked)
themebasedfoi.setVisible(true) ;
else
themebasedfoi.setVisible(false);
}
この関数は、チェック・ボックスを定義する<INPUT>要素のonclick属性で指定されているので、該当するチェック・ボックスをユーザーがクリックするたびに実行されます。例8-1の場合、このコードは次のとおりです。
<INPUT TYPE="checkbox" onclick="setLayerVisible(this)" checked/>Show customers
Google MapsやMicrosoft Bing Mapsのような一般的なオンライン・マップ・サービスは、地図にSpherical Mercator投射を使用します。Oracle Databaseリリース11.1.0.7より前の製品を使用し、Google MapsやMicrosoft Bing Mapsといったタイル層の上に独自の空間データをオーバーレイする必要がある場合は、タイル層の座標系と独自のデータ座標系間で座標系の変換を正しく処理できるように、データベースを設定する必要があります(2つの座標系が異なる場合)。
|
注意: この項のアクションを実行するには、データベースのリリースが10.2.0.1以降である必要があります。 |
Google MapsはSpherical Mercator座標系(EPSG: 3785)を使用しています。これは、Yahoo! MapsやMicrosoft Bing Mapsなどの商用APIプロバイダでも広く使用されています。この座標系(SRID 3785)は、Oracle Spatialリリース11.1.0.7より前の製品では提供されていませんでした。独自データをこの座標系に変換するためにMapViewerおよびOracle Spatialを有効にするには、先にこの座標系定義をOracleデータベースに追加する必要があります(まだ定義されていない場合)。
この座標系が定義されているかチェックするには、以下の文を入力します。
SELECT srid FROM mdsys.cs_srs WHERE srid=3785;
この文で行が返された場合、この項のアクションを実行する必要はありません。この文で行が返されない場合は、この項のアクションを実行して、独自の空間データをタイル層の上にオーバーレイできるようにする必要があります。
次の手順を実行します。
DBAロールを持つユーザーなど、権限のあるユーザーとしてデータベースに接続します。
次のようにcsdefinition.sqlスクリプトを実行します。($OC4J_HOMEを、MapViewerがデプロイされているOC4Jインスタンスのルート・ディレクトリと置き換え、コマンドを1行で入力します)。
Linux: $OC4J_HOME/j2ee/home/applications/mapviewer/web/WEB-INF/admin/csdefinition.sql
Windows: $OC4J_HOME\j2ee\home\applications\mapviewer\web\WEB-INF\admin\csdefinition.sql
必要に応じて、指定の座標系からSpherical Mercator座標系に変換する際に、Oracle Spatialがデータ変換をスキップするように変換ルールを作成します。このような変換ルールを作成する必要があるかどうか判断するには、8.6.1項を参照してください。
パフォーマンスを良くするために空間データを事前に変換するか、MapViewerによって実行時にデータ変換を行ってください(「オンザフライ」)。データベースのリリースが10.2.0.4より前の場合、事前に変換するしか手段はありません。
すべてのデータをSpherical Mercator座標系に事前に変換するには、すべてのデータにSDO_CS.TRANSFORM_LAYERプロシージャを使用し、変換されたデータをマッピングに使用します。(『Oracle Spatial開発者ガイド』のSDO_CS.TRANSFORM_LAYERのリファレンスの項を参照してください)。
MapViewerで実行時にデータを変換する場合、マッピングに使用する前にデータを変換しないでください。
空間データは通常、WGS84やBNGなどの楕円データに基づく座標系で使用されます。この場合、データをSpherical Mercator座標系に変換する際に、Oracle Spatialはデフォルトでデータ変換を適用します。これによって、ユーザーのデータとGoogle Mapsや他のマップ・サービス・タイルとの間で、わずかな不一致や誤差が発生します。この問題を解決するには、指定の座標系からSpherical Mercator座標系に変換する際に、Oracle Spatialがデータ変換をスキップするようにトランスフォーメーション・ルールを作成します。
例8-9は、csdefinition.sqlスクリプトに含まれている、こうしたトランスフォーメーション・ルールを作成するSQL文を示します。ただし、使用する空間データの座標系が例8-9に示すルールの対象でない場合は、独自のルールを作成できます(データの座標系がこれらのルールの対象でない場合)。(座標系のトランスフォーメーション・ルールの作成の詳細は、『Oracle Spatial開発者ガイド』を参照してください)。
図8-9 csdefinition.sqlスクリプトに定義されたトランスフォーメーション・ルール
-- Create the tfm_plans, that is, the transformation rules. -- Note: This will result in an incorrect conversion since it ignores a datum -- datum between the ellipsoid and the sphere. However, the data will match -- up better on Google Maps. -- For wgs84 (8307) call sdo_cs.create_pref_concatenated_op( 83073785, 'CONCATENATED OPERATION 8307 3785', TFM_PLAN(SDO_TFM_CHAIN(8307, 1000000000, 4055, 19847, 3785)), NULL); -- For 4326, EPSG equivalent of 8307 call sdo_cs.create_pref_concatenated_op( 43263785, 'CONCATENATED_OPERATION_4326_3785', TFM_PLAN(SDO_TFM_CHAIN(4326, 1000000000, 4055, 19847, 3785)), NULL); -- For OS BNG, Oracle SRID 81989 call sdo_cs.create_pref_concatenated_op( 819893785, 'CONCATENATED OPERATION 81989 3785', TFM_PLAN(SDO_TFM_CHAIN(81989, -19916, 2000021, 1000000000, 4055, 19847, 3785)), NULL); -- For 27700, EPSG equivalent of 81989 call sdo_cs.create_pref_concatenated_op( 277003785, 'CONCATENATED_OPERATION_27700_3785', TFM_PLAN(SDO_TFM_CHAIN(27700, -19916, 4277, 1000000000, 4055, 19847, 3785)), NULL); commit;