ヘッダーをスキップ
Oracle Application Server MapViewerユーザーズ・ガイド
10g(10.1.3.1.0)
B40016-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

8 Oracle Maps

Oracle Mapsは、Webベースの高性能な対話型マッピング・アプリケーションを開発するための一連のテクノロジの名前です。Oracle Mapsは、OracleAS MapViewerに同梱されています。

この章の主な項目は、次のとおりです。

8.1 Oracle Mapsの概要

Oracle Mapsは、次の主要なコンポーネントから構成されています。

マップ・キャッシュ・サーバー(map画像キャッシング・エンジン)は、Oracle MapViewerなどのWeb対応マップ・プロバイダによってレンダリングされたmap画像タイルのフェッチとキャッシングを自動的に実行します。また、キャッシングされたmap画像タイルをクライアント(Oracle MapsクライアントAPIを使用して開発されたWebアプリケーション)に提供します。それらのクライアントはその後、複数のmap画像タイルをまとめ、1つのシームレスで大きなベース・マップを自動的に作成します。それらのmap画像タイルは事前に生成されキャッシングされるので、アプリケーション・ユーザーにはマップが高速に表示されます。

対象地物(FOI)サーバー(レンダリング・エンジン)は、Oracle Spatialによって管理される空間地物層のみでなく、アプリケーションによって作成されるポイント型、線型またはポリゴン型の個々の地理空間地物のレンダリングも実行します。そのようなFOI(通常は、レンダリング対象の画像も関連する一連の属性データも含まれる)は、その後クライアントに送信され、ユーザーによって操作されます。キャッシングされたイメージ・タイル(通常は静的コンテンツを表す)とは異なり、FOIは動的であり、リアルタイムのデータベース・コンテンツまたはアプリケーション・コンテンツを表します。動的なFOIとキャッシングされた静的なベース・マップを使用すると、Webマッピング・アプリケーションを作成できます。

JavaScriptマッピング・クライアントは、サーバーからマップ・コンテンツをフェッチしてクライアント・アプリケーションに表示するブラウザ側マップ表示エンジンです。また、マップのドラッグやクリックといったユーザーとの対話に関するマップ関連のカスタマイズ可能なコントロールをアプリケーションに提供します。JavaScriptマッピング・クライアントは、任意のWebアプリケーションまたはポータルと簡単に統合できます。

8.1.1 Oracle Mapsアプリケーションのアーキテクチャ

Oracle Mapsを使用して開発したWebマッピング・アプリケーションのアーキテクチャを、図8-1に示します。

図8-1 Oracle Mapsアプリケーションのアーキテクチャ

図8-1の説明は図の下
「図8-1 Oracle Mapsアプリケーションのアーキテクチャ」の説明

アプリケーションは、Oracle Mapsアーキテクチャと次のようにやりとりします(図8-1を参照)。

  • アプリケーションは、JavaScriptを使用して開発され、WebブラウザのJavaScriptエンジン内で動作します。

  • アプリケーションは、JavaScriptマップ・クライアントを起動してマップ・キャッシュ・サーバーからmap画像タイルをフェッチし、Webブラウザにマップを表示します。

  • アプリケーションは、JavaScriptマップ・クライアントを起動してFOIサーバーから動的空間地物をフェッチし、ベース・マップ上に表示します。

  • JavaScriptマップ・クライアントが、アプリケーションに代わってユーザーとのマップ関連の対話を制御します。

  • マップ・キャッシュ・サーバーは、map画像タイル・リクエストを受信すると、リクエストされたタイルがキャッシング済であるかどうかをまずチェックします。該当するタイルがキャッシング済の場合は、キャッシング済のタイルがクライアントに返されます。該当するタイルがまだキャッシングされていない場合は、該当するタイルをマップ・キャッシュ・サーバーがフェッチしてキャッシュに格納した後、クライアントに返します。タイルは、OracleAS MapViewerのマップ・レンダリング・エンジンまたは外部Webマップ・サービス・プロバイダから直接フェッチすることができます。

  • FOIサーバーは、リクエストを受信すると、OracleAS MapViewerのマップ・レンダリング・エンジンを使用して地物画像を生成し、それらの画像を地物属性とともにクライアントに送信します。

8.1.2 Oracle Mapsを使用した単純な例

図8-2は、Oracle Mapsを使用して作成した単純なアプリケーションのインタフェースを示しています。この例は、MapViewerに同梱されており、http://host:port/mapviewer/fsmc/sampleApp.htmlでアクセスできます。このアプリケーションを実行するには、http://host:port/mapviewer/fsmc/tutorial/setup.htmlの手順に従ってデータベース・スキーマおよび必要なマップ・キャッシュ・インスタンスを設定します。

図8-2 Oracle Mapsを使用して作成したアプリケーション

図8-2の説明は図の下
「図8-2 Oracle Mapsを使用して作成したアプリケーション」の説明

図8-2に示したアプリケーションでは、顧客をマップ上に表示しています。このマップは、次の2つの層から構成されています。

  • ベース・マップ層では、海、郡の境界線、都市および高速道路が表示されます。Webブラウザに表示されるベース・マップ全体は、マップ・キャッシュ・サーバーによってレンダリングされた複数のmap画像タイルから構成されます。

  • FOI層では、ベース・マップ上に顧客が赤のドット・マーカーで表示されます。顧客を表すマーカーをユーザーがクリックすると、情報ウィンドウが表示され、該当する顧客の一部の属性が表示されます。顧客のマーカーおよび属性は、FOIサーバーによってレンダリングされます。

これら2つの層以外に、マップの左下隅にはスケール・バー、右上隅にはナビゲーション・パネルが表示されます。

アプリケーション・ユーザーは、マウスを使用して、マップをドラッグすることができます。その場合、マップに現在含まれている空間リージョンに対応して、新しいイメージ・タイルおよびFOIが自動的にフェッチされます。また、ユーザーは、組込みマップ・ナビゲーション・ツールを使用して画像のパンやズームを実行したり、「Show customers」ボックスを選択または選択解除して顧客(赤のドット・マーカー)の表示/非表示を切り替えたりすることもできます。

図8-2で示した単純なアプリケーションのソース・コード全体を、例8-1に示します。

例8-1 単純なアプリケーションのソース・コード

<html>
<head>
<META http-equiv="Content-Type" content="text/html" charset=UTF-8">
<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 base map layer as background.
  mapview.addBaseMapLayer(new MVBaseMap("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項を参照してください。

8.1.3 マップ・コンテンツの編成

この項では、Webブラウザ内でマップを表示する際にJavaScriptクライアントが様々なマップ・コンテンツを内部で編成する方法について解説します。アプリケーションは通常1つのマスターHTML DIVオブジェクトを1つのWebページに配置し、JavaScriptクライアントはそのDIVオブジェクト内に様々なコンテンツ層を追加します。

マップ・クライアントによって表示されるマップ・コンテンツは、一連の層によって編成されます。アプリケーション・スクリプトが適切なマップ・クライアントAPIを起動すると、1つのマップ・コンテナ内に一連のマップ層が作成されます。マップ・コンテナは、ユーザー定義のHTML DIVオブジェクトです。Webページ内では、マップ・コンテナのサイズと位置をカスタマイズできます。マップ層のレイアウトを、図8-3に示します。

図8-3 マップ内の一連の層

図8-3の説明は図の下
「図8-3 マップ内の一連の層」の説明

図8-3で示したように、マップ・コンテンツ層には、ベースマップ・タイル、テーマベースFOI、ユーザー定義のFOIまたはレッドライン、情報ウィンドウ、固定図という5つのタイプがあります。固定図層を除く層はすべて、ユーザーがマップをドラッグすると、まとまって移動します。これらの可動層は、マップがドラッグされたりズームされたりすると、マップ・クライアントによって自動的に更新されます。(固定図層が移動されることはありません。)

8.1.3.1 ベース・マップ層

通常のOracle Mapsアプリケーションは、ベース・マップ層を1つ以上持ち、マップ・キャッシュ・インスタンスから事前に生成された一連のmap画像タイルを組み立てて表示します。ベース・マップによって表示される静的マップ・コンテンツは、さほど変化しないため、通常はクライアント・アプリケーションによりバックグラウンド・マップとして使用されます。たとえば、8.1.2項および図8-2で説明したサンプル・アプリケーションの場合は、海、郡の境界線、都市および高速道路がすべて、ベース・マップ層として表示されています。ベース・マップ層で実行可能なユーザー操作は、マップのドラッグなどの一部の操作に限られています。

マップ・キャッシュ・インスタンスは、通常はMapViewerベース・マップと関連付けられており、MapViewerサーバーによって管理されます。ただし、マップ・キャッシュ・インスタンスを構成して、map画像タイルを外部(MapViewer以外)のマップ・プロバイダからキャッシングすることもできます。

ベース・マップ層は常に、層階層の最下部に存在します。ベース・マップ層には、静的なマップ・コンテンツおよびバックグラウンド・マップ・コンテンツが表示されます。一連のマップ・キャッシュ・インスタンスの複数の層がベース・マップ層に含まれる場合、それらの層の座標系とズーム・レベルの定義はすべて同じにしてください。

内部では、マップ・タイル層は、マップDIVコンテナ・ウィンドウのサイズより大きいのが普通です。そのため、ブラウザは、その他のタイルのフェッチおよびキャッシングを実行できます。その結果、それらのタイルは、マップ層がユーザーによってドラッグされるとすぐに表示されます。

8.1.3.2 テーマベースFOI層

テーマベースFOI層は、1つまたは複数存在することができます。それぞれのテーマベースFOI層は、MapViewerの事前定義済テーマで定義されている特定の問合せ基準を満たす一連の対話型FOIから構成されています。FOIは、ポイント、線またはポリゴンの場合があります。たとえば、売上高が10万ドルを超えている店舗をすべて、ポイントのテーマベースFOI層として表示することもできます。

ユーザーは、マウスを重ねたり、クリックしたりすることにより、FOIを操作できます。アプリケーションでは、そのようなユーザー操作に対するマップ・クライアントの反応方法をカスタマイズすることができます。

テーマベースFOI層の地物(地理的および非地理的)はすべて、データベースに格納されます。クライアント・アプリケーションから地物がリクエストされると、FOIサーバーにより地物に対して問合せとレンダリングが実行されます。テーマベースFOI層の問合せウィンドウは、テーマベースFOI層をサーバーからリフレッシュすることなくマップをドラッグできるような余地を設けるように、カスタマイズにより、マップDIVウィンドウより大きくすることができます。テーマベースFOI層の詳細は、8.3.1項を参照してください。

8.1.3.3 ユーザー定義のFOI層

ユーザー定義FOIとは、クライアント側で定義されるインタラクティブな地物のことです。FOIは、ポイント地物、線地物またはポリゴン地物の場合があります。ユーザーは、テーマベースFOIの場合と同じ方法で、ユーザー定義FOIを操作できます。ただし、テーマベースFOI層(一連の地物としてレンダリングされる)の場合とは対照的に、ユーザー定義FOIのリクエストおよびレンダリングは個々に実行されます。ジオメトリの表現やレンダリング・スタイルも含め、ユーザー定義FOIの属性はすべて、アプリケーションで提供する必要があります。たとえば、ユーザー指定の始点アドレスおよび終点アドレスに基づいたルート・ジオメトリは、ユーザー定義の線FOIとしてマップに表示する必要があります。

ユーザー定義のFOI層の処理は、アプリケーションが動作するWebブラウザにより、次のように異なります。

  • Microsoft Internet Explorerの場合は、アプリケーションによって追加されたユーザー定義の各FOIがすべて、テーマベースFOI層のすぐ上の層の中に配置されます。該当する層は、高々1つしか存在することができません。

  • OperaおよびMozillaベースのブラウザ(Netscape、Firefoxなど)の場合は、ユーザー定義の各FOIがすべて2つの層(一方はポイント地物用、他方はポリラインやポリゴンなどの非ポイント地物用)の内部に配置されます。非ポイント地物層は、ポイント地物層の下に配置されます。

8.1.3.4 情報ウィンドウ層

情報ウィンドウとは、マップ内のカスタマイズ可能なコンテンツが表示される小さなポップアップ・ウィンドウのことです。どの情報ウィンドウも、表示される場合は、ユーザー定義の各FOI層(複数可)のすぐ上の層内に配置されます。情報ウィンドウ層は、高々1つしか存在することができません。

8.1.3.5 固定図層

最上位層には、すべての固定図(著作権表示、スケール・バー、ナビゲーション・パネル、ユーザー定義のマップ装飾地物などの不動要素)が含まれます。(ユーザー定義のマップ装飾地物とは、任意のカスタムなHTMLコンテンツ(マップ・タイトルやカスタム・コントロール・ボタンなど)を含むことができるアプリケーション定義要素のことです。)固定図層は、他のすべてのものの上に表示され、ユーザーがマップをドラッグしても移動されません。

8.2 マップ・キャッシュ・サーバー

マップ・キャッシュ・サーバーは、事前に生成される固定サイズのmap画像タイルをキャッシングして表示するmap画像キャッシング・エンジンです。マップ・キャッシュ・サーバーは、OracleAS MapViewerサーバーの一部であるJavaサーブレットとしてインプリメントされます。マップ・キャッシュ・サーバーは、タイルのズーム・レベルおよびタイル位置(メッシュ・コード)によって指定されたmap画像タイルを要求するリクエストを受け付け、リクエストされたタイルをクライアントに返送します。

マップ・キャッシュ・サーバーの基本的なワークフローを、図8-4に示します。

図8-4 マップ・キャッシュ・サーバーのワークフロー

図8-4の説明は図の下
「図8-4 マップ・キャッシュ・サーバーのワークフロー」の説明

図8-4のように、マップ・キャッシュ・サーバーは、マップ・タイルを求めるリクエストを受信すると、該当するタイルをキャッシュ記憶域システム内で検索します。該当するタイルがキャッシングされていると、マップ・キャッシュ・サーバーはそのタイルをクライアントに送信します。該当するタイルがキャッシングされていない場合は、該当するタイルをマップ・キャッシュ・サーバーがフェッチしてキャッシュに保存した後、クライアントに送信します。

MapViewer管理ツールを使用すると、マップ・キャッシュ・サーバーを管理できます。

8.2.1 マップ・キャッシュ・サーバーに関する概念

この項では、Oracle Mapsを効果的に使用できるように知っておくべき、マップ・キャッシュ・サーバーに関する概念について説明します。

8.2.1.1 マップ・キャッシュ・インスタンスとベース・マップ・ソース

各ベース・マップは、マップ・キャッシュ・サーバー内のマップ・キャッシュ・インスタンスによって管理されます。マップ・キャッシュ・インスタンスは、ベース・マップに属するmap画像タイルのフェッチおよび格納を実行した後、map画像タイルをクライアントに返します。マップ・キャッシュ・サーバーは複数のマップ・キャッシュ・インスタンスを持つことができ、各マップ・キャッシュ・インスタンスは別々のベース・マップを管理します。

どのベース・マップも、事前定義済の複数のズーム・レベルを持つことができます。どのズーム・レベルにも0〜n-1(nはズーム・レベルの総数)の範囲のズーム・レベル番号が1つ割り当てられています。ズーム・レベル0は最もズーム・アウトしたレベル、ズーム・レベルn-1は最もズーム・インしたレベルです。

ベース・マップは、ズーム・レベルごとに、同一サイズの小さな一連のmap画像タイルに均等に分割されています。クライアントは、そのズーム・レベルおよびタイル・メッシュ・コードによってマップ・タイルを指定します。

ベース・マップは、次の2つのタイプのソースから得られます。

  • MapViewer内部のベース・マップ(MapViewerマップ・レンダリング・エンジンによってレンダリングされる)。MapViewerベース・マップは、事前定義済の一連のテーマから構成され、データベース・ビューUSER_SDO_USER_MAPS内で事前定義済である必要があります。

  • 外部Webマップ・サービス・プロバイダによってレンダリングされたマップ。外部Webマップ・サービス・プロバイダは、Webを介したクライアント・リクエストに対してマップのレンダリングおよび表示を実行するサーバーです。外部マップ・サービス・プロバイダからマップをフェッチできるアダプタを正しく構成すると、マップ・キャッシュ・インスタンスは該当する外部マップ・サービス・プロバイダによって生成されたマップをフェッチし、表示することができます。(マップ・キャッシュ・サーバーが内部で動作しているMapViewer以外のMapViewerインスタンスも、外部マップ・サービス・プロバイダとみなされます。)

8.2.1.2 map画像タイルの記憶域

Oracle Mapsでは、ローカル・ファイル・システムを使用して、キャッシングされたイメージ・タイルを格納します。この格納に使用されるパスは、マップ・キャッシュ・サーバーの構成設定の一部としてカスタマイズできます。

8.2.1.3 マップ・タイルの座標系

map画像のキャッシュおよび管理は、同一サイズの小さな矩形のイメージ・タイルとしてマップ・キャッシュ・サーバーによって実行されます。四角形処理は現在、任意の2次元のデカルト座標系でサポートされています。測地座標系も、デカルト座標系であるかのようにマッピングされる場合 (図8-5のように経度および緯度が単に2つの直交軸として取り扱われる場合) はサポートされています。

図8-5 経度/緯度座標系を使用した四角形処理

図8-5の説明は図の下
「図8-5 経度/緯度座標系を使用した四角形処理」の説明

ズーム・レベルごとに、マップ・タイルはマップ座標系全体を2つの次元(XとY。図8-5では緯度と経度)に沿って均等に分割して作成されます。マップ・キャッシュ・サーバーは、map画像タイルを作成する際、マップ座標系のこの次元情報を必要とします。そのため、ユーザーは、マップ・キャッシュ・インスタンスの構成設定でこの情報を指定する必要があります。

マップ座標系全体は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)も指定する必要があります。

8.2.1.4 タイル・メッシュ・コード

各マップ・タイルは、(Mx, My)という整数のペアとして定義されるメッシュ・コードによって指定します(MxはタイルのXディメンション・インデックス、MyはタイルのYディメンション・インデックスを指定する)。タイルがXminから始まるXディメンション上のi番目のタイルである場合、Mxはi-1になります。タイルがYminから始まるYディメンション上のj番目のタイルである場合、Myはj-1になります。マップ上のタイルのメッシュ・コードを、図8-6に示します。

図8-6 タイルのメッシュ・コード

図8-6の説明は図の下
「図8-6 タイルのメッシュ・コード」の説明

JavaScriptマップ・クライアントは、Webブラウザにマップを表示するのに必要なタイルを自動的に計算し、メッシュ・コードを指定したリクエストをサーバーに送信します。メッシュ・コードはアプリケーションにとって透過的であり、アプリケーションの開発者はメッシュ・コードを直接取り扱う必要がありません。

8.2.1.5 四角形処理に関するルール

マップの分割方法およびタイルの作成方法を決める四角形処理に関するルールを作成する必要があります。マップ・キャッシュ・サーバーは、四角形処理に関するそのようなルールを使用してマップを小さなmap画像タイルに分割し、タイル・ストレージ・システムに格納します。そのようなルールは、JavaScriptマップ・クライアントも使用します。

1つのズーム・レベルに対応するタイルはすべて同じサイズなので、マップ・キャッシュ・サーバーはタイルの分割を実行するのに次の情報が必要です。

  • 画面ピクセルで指定したマップ・タイル画像のサイズ(幅と高さ)。これは、タイル画像の物理サイズです。

  • マップ座標系に従って指定されたタイル・サイズ。たとえば、マップで測地座標系を使用する場合、タイルの幅と高さは度の単位で指定します。このサイズは、タイルの幅と高さを使用して明示的に指定することもできますし、マップ・スケールを使用して暗黙的に指定することもできます。(マップ・スケールとタイル画像のサイズから、マップ座標系に従ってタイルの幅と高さを求めることができます。)

先の情報が、ズーム・レベルに対応する四角形処理のルールになります。どのズーム・レベルも、独自の四角形処理ルールを持つ必要があります。マップ・キャッシュ・サーバーに対して構成設定を指定する場合は、8.2.2項で示すように、四角形処理ルールを定義する必要があります。

8.2.2 マップ・キャッシュ・サーバーの構成

マップ・キャッシュ・サーバーの構成設定は、ローカルな構成ファイルおよびデータベース・ビューに格納されています。それらの設定は、カスタマイズが可能です。

8.2.2.1 マップ・キャッシュ・サーバーのグローバル構成

ロギング・オプションやデフォルトのキャッシュ記憶域ディレクトリといったマップ・キャッシュ・サーバーのグローバル設定は、MapViewer構成ファイルmapViewerConfig.xml(ディレクトリ$MAPVIEWER_HOME/web/WEB-INF/confの下)に格納されています。

マップ・キャッシュ・サーバーの構成設定は、次の例で示すように、最上位の<mapperConfig>要素の中の<map_cache_server>要素で定義されています。

<map_cache_server>
   <logging
      log_level="info"
      log_thread_name="false"
      log_time="true">
     <log_output name="System.err"/>
    <log_output name="../log/mapcacheserver.log" />
   </logging>
   <cache_storage default_root_path="/scratch/mapcache/"/>
</map_cache_server>

<logging>要素では、ロギング・オプションを指定します。この構文とオプションは、mapViewerConfig.xmlファイル内のMapViewerの<logging>要素(1.5.2.1項を参照)と同じです。ただし、マップ・キャッシュ・サーバーによって生成されたロギング情報はMapViewerのログ・ファイルに書き込まれないので、該当する情報をロギングするには、<map_cache_server>要素内で<logging>要素を指定する必要があります。

<cache_storage>要素では、マップ・タイル・ストレージに関する設定値を指定します。default_root_path属性では、キャッシングされたタイル画像が格納されるデフォルトのファイル・システム・ディレクトリを指定します。デフォルトのルート・ディレクトリは、設定されていない場合または有効でない場合、$MAPVIEWER_HOME/web/mapcacheになります。マップ・キャッシュ・インスタンスの設定で自体のマップ・タイル・ストレージ・ディレクトリが指定されていない場合は、今示したディレクトリの下にサブディレクトリが1つ作成され、それがマップ・キャッシュ・インスタンス用に使用されます。このサブディレクトリの名前は、マップ・キャッシュ・インスタンスの名前と同じになります。

8.2.2.2 マップ・キャッシュ・インスタンスの構成

キャッシュ・インスタンスの構成設定は、メタデータ・ビュー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

マップ・キャッシュ・インスタンスがオンラインの場合はYES、マップ・キャッシュ・インスタンスがオフラインの場合はNO。キャッシュでタイルが見つからず、マップ・キャッシュ・インスタンスがオンラインの場合、マップ・キャッシュ・サーバーは該当するタイルをフェッチし、フェッチしたタイルをクライアントに戻します。タイルが見つからず、マップ・キャッシュ・インスタンスがオフラインの場合、マップ・キャッシュ・サーバーは該当するタイルをフェッチせず、ブランク画像をクライアントに戻します。

IS_INTERNAL

VARCHAR2

マップ・ソースが内部マップ・ソースの場合はYES、マップ・ソースが外部マップ・ソースの場合はNO

DEFINITION

CLOB

マップ・キャッシュ・インスタンスのXML定義(この項で後述)。

BASE_MAP

VARCHAR2

キャッシング対象のMapViewerベース・マップの名前(マップ・ソースが内部マップ・ソースの場合)

MAP_ADAPTER

BLOB

外部マップ・サービス・プロバイダのアダプタJavaクラスが含まれるjarファイル(この項で後述)。


DEFINITION列の場合、マップ・ソースの定義は一般的に次の形式になります。

  <cache_instance
     image_format ="tile-image-format">
    <internal_map_source
      base_map="name-of-MapViewer-base-map"
      bgcolor="base-map-background-color"/>
    </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>
    <cache_storage
       root_path="disk-path-of-cache-root-directory"
    </cache_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>
    <cache_bound>
       <coordinates> … </coordinates>
    </cache_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-
                       tile-width-specified-in-map-data-units-at-"
       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">
        <cache_bound>
          <coordinates> … </coordinates>
        </cache_bound>
      </zoom_level>
      …
    </zoom_levels>
  </cache_instance>

例8-2は内部マップ・キャッシュ・インスタンスのXML定義、例8-3は外部マップ・キャッシュ・インスタンスのXML定義を示しています。<cache_instance>要素およびそのサブ要素の説明は、これらの例の後で示します。

例8-2 内部マップ・キャッシュ・インスタンスのXML定義

<?xml version = '1.0'?>
<!-- XML definition of an internal map cache instance.
-->
<mapcache_config>
   <cache_instance image_format="PNG">
      <internal_map_source base_map="demo_map"/>
      <cache_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>
   </cache_instance>
</mapcache_config>

例8-3 外部マップ・キャッシュ・インスタンスのXML定義

<?xml version = '1.0'?>
<!-- XML definition of an external map cache instance.
-->
<mapcache_config>
   <cache_instance 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>
      <cache_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 cache server will
         automatically generate the <zoom_level> elements for the 10
         zoom levels.
      -->
      <zoom_levels levels="10" min_scale="5000" max_scale="10000000" />
   </cache_instance>
</mapcache_config>

最上位の要素は<cache_instance>です。image_format属性ではタイル画像の形式を指定しますが、この属性で現在サポートされている値はPNGGIFおよび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_hostNONEとして指定すると、マップ・タイル・リクエストはすべて、プロキシ・サーバーを経由することなく、リモート・サーバーに直接送信されます。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属性の値を変更すれば、同一のデータ・ソースまたは他のデータ・ソースから別のベース・マップをフェッチすることができます。

<cache_storage>要素では、キャッシュ・インスタンスのキャッシュ記憶域設定を指定します。オプションのroot_path属性では、キャッシュ・インスタンス・ストレージのルート・ディレクトリとして使用するファイル・システム・ディレクトリを指定します。この属性が省略されているか無効であると、mapViewerConfig.xmlファイルで定義されているデフォルトのルート・ディレクトリが使用されます。

<coordinate_system>要素は、マップ座標系を指定し、いくつかの必須属性があります。srid属性では、座標系の空間参照IDを指定します。minX属性ではXディメンションの下限、minY属性ではYディメンションの下限、maxX属性ではXディメンションの上限、maxY属性ではXディメンションの上限を指定します。標準の経度/緯度(WGS 84)座標系の場合、srid値は8307で、minXminYmaxXおよびmaxYの値はそれぞれ-180、-90、180および90です。

内部マップ・キャッシュ・インスタンスの場合、マップ座標系はデータ座標系と異なっていてもかまいません。それらが異なっている場合、マップ・キャッシュ・サーバーでは<coordinate_system>要素で定義されている座標系にマップ・データを変換し、その座標系を使用してマップ・タイル画像をレンダリングします。

<tile_image>要素は、タイル画像のサイズ設定を指定し、次の必須属性があります。つまり、widthではタイル画像の幅を画面ピクセル単位で指定し、heightではタイル画像の高さを画面ピクセル単位で指定します。

オプションの<cache_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では、最高のズーム・レベル(最もズーム・インしたレベル)にあるmap画像のスケールを指定します。

  • max_scaleでは、最低のズーム・レベル(最もズーム・アウトしたレベル)にあるmap画像のスケールを指定します。

  • min_tile_widthでは、最高のズーム・レベルにあるマップ・タイルの幅を指定します。この幅は、マップ・データ単位で指定します。

  • max_tile_widthでは、最低のズーム・レベルにあるマップ・タイルの幅を指定します。この幅は、マップ・データ単位で指定します。

各ズーム・レベルの定義をマップ・キャッシュ・サーバーが自動的に生成できるようにするには、前述の属性を次のように組み合せて指定する必要があります。

  • levelsmin_scaleおよびmax_scale

  • levelsmin_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属性は、オプションであり、小さなmap画像タイルのかわりに大きなmap画像をフェッチするかどうかを指定します。値がTRUE(デフォルト)の場合は、複数のマップ・タイルから構成される大きなmap画像がフェッチされ、小さなmap画像タイルに分割されます。そのため、マップ・キャッシュ・サーバーとマップ・サービス・プロバイダの間のネットワーク・ラウンドトリップを抑えることができます。

<zoom_level>要素では、scale属性か、tile_width要素とtile_height要素の両方を指定する必要があります。

<zoom_level>要素内の<cache_bound>要素では、ズーム・レベルに合せてキャッシングされたマップ・タイルの枠ボックスを指定します(オプション)。マップ・キャッシュ・インスタンスでは、このボックス内のタイルのみをフェッチし、リクエストされたタイルがこのボックスの外部にある場合は空白のタイルを戻します。枠ボックスは、マップ・データ座標系内で指定された矩形によって指定します。該当する矩形は、<coordinates>要素(この項で前述)によって指定します。<zoom_level>要素内で<cache_bound>要素を指定すると、XML階層内で上位にある<cache_bound>要素で指定されているキャッシュの枠ボックスの設定全体が無効になります。

8.2.3 外部マップ・ソース・アダプタ

外部マップ・ソース・アダプタは、マップ・キャッシュ・インスタンスと外部マップ・サービス・プロバイダの間のインタフェースです。外部マップ・サービス・プロバイダからmap画像タイルをフェッチする必要がある場合、マップ・キャッシュ・インスタンスはタイルのズーム・レベル、サイズおよび位置に関する情報を指定して、外部マップ・ソース・アダプタをコールします。外部マップ・ソース・アダプタはその後、プロバイダに固有のリクエストを作成した後、そのリクエストを外部マップ・サービス・プロバイダに送信し、得られたイメージ・タイルをマップ・キャッシュ・インスタンスに戻します。

外部マップ・ソース・アダプタは、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)

    このメソッドでは、マップ・サービス・プロバイダに送信してmap画像タイルをフェッチすることが可能な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 an OracleAS 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;
    }
  }
}

8.3 対象地物(FOI)サーバー

対象地物(FOI)とは、Webブラウザ内で動作するJavaScriptマップ・クライアントを使用して操作できるビジネス・エンティティまたは地理的地物のことです。FOIデータは、動的に表示され、ベース・マップの一部です。ポイント、線文字列、ポリゴンなどの任意の空間ジオメトリ・タイプをFOIとすることができます。FOIの検索、参照、検査および操作機能は、位置ベースのサービスにとって必要不可欠です。

FOIサーバーは、MapViewer内で動作するJavaサーブレットです。FOIサーバーは、データベースに対する問合せ、FOI画像のレンダリング、およびクライアントに対するFOI画像とFOI属性データの送信を実行することにより、JavaScriptマップ・クライアントから受け取るFOIリクエストに応答します。JavaScriptマップ・クライアントは、FOI画像をエンド・ユーザーに表示し、画像を操作する機能を提供します。

FOIサーバーは、テーマベースおよびユーザー定義という2つのタイプのFOIリクエストを受け付けます。いずれのタイプのFOIリクエストも、リクエストのタイプに適したデータ層を戻します。

8.3.1 テーマベース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章を参照)を使用して行うことができます。

8.3.1.1 事前定義済テーマベースFOI層

クライアントは、事前定義済テーマベース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では情報ウィンドウで使用されるテキスト文字列を指定する。

8.3.1.2 テンプレート付き事前定義済テーマ

標準の事前定義済テーマまたはテンプレート付き事前定義済テーマを、MapViewerの事前定義済テーマとすることができます。いずれのタイプの事前定義済テーマも、USER_SDO_THEMESビューを使用して定義します。ただし、標準の事前定義済テーマの問合せ条件は固定ですが、テンプレート付き事前定義済テーマの問合せ条件は動的なバインディング変数を含むことができ、それらの値はテーマ・リクエストの発行時に変更が可能です。

バインディング変数を2つ(該当するテキストは<features>要素内の太字部)使用するテンプレート付き事前定義済テーマのXMLスタイリング・ルールを、例8-7に示します。

例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つのバインディング変数の値は、テーマの定義時には確定されず、クライアントがサーバーに送信するリクエストの中で与えられます。

8.3.1.3 動的JDBC問合せのテーマベースFOI層

クライアントは、動的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);

8.3.2 ユーザー定義のFOIリクエスト

ユーザー定義FOIとは、クライアント側で定義される地物のことです。地物の集合としてレンダリングされるテーマベースFOI層とは異なり、ユーザー定義FOIの場合はリクエストとレンダリングが個々に実行されます。

ジオメトリの表現やレンダリング・スタイルも含め、ユーザー定義FOIの属性はすべて、アプリケーションで提供する必要があります。JavaScriptマップ・クライアントでは、ジオメトリ表現およびレンダリング・スタイルに関する情報を指定したリクエストを、FOIサーバーに送信します。FOIサーバーは、FOI画像をレンダリングし、クライアントに戻します。レンダリング・スタイルは、USER_SDO_STYLESビュー内で事前定義済である必要があります。

8.4 Oracle Maps JavaScript API

Oracle Maps JavaScriptクライアントは、ブラウザベースのマップ視覚化エンジンであり、マップ・キャッシュ・サーバーおよびFOIサーバーの上位で動作します。次の機能が実装されています。

これらの機能にアクセスするには、次のようなJavaScript API(いくつかのJavaScriptクラスから構成される)を使用します。

MVMapViewは、Webブラウザ内の全マップ操作におけるメインのエントリ・クラスです。ユーザーのWebマッピング・アプリケーションにロジックを追加するための必須のインタフェースはすべて、MVMapViewなどのクラスによって提供されます。そのような論理的インタフェースには、次のようなものがあります。

Oracle Maps JavaScript API内の全クラスの詳細は、Javadocスタイルのリファレンス・ドキュメント(MapViewerに同梱されており、次の場所で利用可能)を参照してください。

http://host:port/mapviewer/fsmc/apidoc

8.5 Oracle Mapsアプリケーションの開発

すべてのマップ・データがOracleデータベースに格納されており、Oracle Application ServerにMapViewerがデプロイされている場合は、この項で示す手順に従ってOracle Mapsを使用すれば、Webベースのマッピング・アプリケーションを開発できます。

8.5.1 1つまたは複数のマップ・キャッシュ・インスタンスの作成

Oracle Mapsアプリケーションは通常、静的なマップ背景としてベース・マップ層を1つ以上表示します。マップ・キャッシュ・インスタンスは、ベース・マップごとに作成する必要があります。たとえば、8.1.2項で説明したサンプル・アプリケーションの場合は、海、郡の境界線、都市および高速道路を表示するベース・マップ用のマップ・キャッシュ・インスタンスを作成する必要があります。

マップ・キャッシュ・インスタンスを作成する場合は、マップ・タイル画像のレンダリング元となるマップ・ソースが使用可能な状態にあることを事前に確認する必要があります。データベースに格納されているマップ・データに基づいてマップ・タイル画像をレンダリングする場合は、事前定義済の一連のテーマから構成されるMapViewerベース・マップを作成する必要があります。(ベース・マップの作成は、第9章で説明するMap Builderツールを使用して行うことができます。)外部マップ・プロバイダを使用してマップ・タイル画像をレンダリングする場合は、マップ・キャッシュ・サーバーによって指定されているタイル画像の定義を使用して外部サーバーからmap画像をフェッチできるマップ・ソース・アダプタを作成する必要があります。

マップ・ソースが使用可能な状態にある場合は、1.5.3項で説明したように、MapViewer管理ページを使用して、マップ・キャッシュ・インスタンスを作成することができます。マップ・キャッシュ・インスタンスを作成する場合は、適切な座標系の定義、マップ・ソースの定義(内部または外部)およびズーム・レベルの定義(ズーム・レベルの数とマップ・スケール)を指定する必要があります。

マップ・キャッシュ・インスタンスは、作成し終わったら、MapViewerに同梱されているJavaServer Page(JSP)デモ・アプリケーションを使用してテストすることができます。JSPデモ・アプリケーションには、http://host:port/mapviewer/fsmc/omaps.jspでアクセスできます。ユーザーの入力に基づいて、このアプリケーションでは、MapViewerインスタンスで定義されている任意のマップ・キャッシュ・インスタンスによって表示されるマップを表示できます。

ベース・マップ層をアプリケーションで複数表示する必要がある場合は、ベース・マップごとにマップ・キャッシュ・インスタンスを作成します。

8.5.2 FOIメタデータの定義

データベース問合せの結果に基づきアプリケーションで動的地物をテーマベースFOI層として表示する必要がある場合は、テーマベースFOI層ごとに、事前定義済のMapViewerテーマを作成する必要があります。個々の動的地物をアプリケーションでユーザー定義FOIとして表示する必要がある場合は、FOIサーバーによって使用されるレンダリング・スタイル(複数可)を定義してFOI画像をレンダリングする必要があります。事前定義済のテーマおよびレンダリング・スタイルを作成するには、Map Builderツール(第9章を参照)を使用します。

8.5.3 クライアント・アプリケーションの作成

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 base map layer as background.
      mapview.addBaseMapLayer(new MVBaseMap("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