Google Earthのコンテンツでリッチな表現を

第5回データベースを活用したKMLの生成

Google Earthはその特性上、データベースツールと非常に相性の良いツールです。これまで紹介してきた様々なテクニックを、テキストエディタでカリカリ書くのも一つの手段ですが、手元にある大量のデータやコンテンツをKMLとして提供するためには、相応のギミックが必要です。

主に、Google Earthに大量のデータを提供する手段として用いられているもので代表的なものは、CGIやPHPおよびMySQLなどのデータベースで作られたものです。そして、Visual Basicなどで作られたローカルアプリケーションです。前者はウェブで用意されているデータをGoogle Earthのネットワークリンクを用いて提供する手段として、後者はローカルにある大量のデータを、コンテンツの固まりとして、作り上げるために利用されています。

なお、今回の説明するサンプルのコードを以下に用意しました。

Access2007を使用して、KML出力する準備をする

数あるKML化の手段として、Access2007を利用するものがあげられます。理由としてはもっとも簡単なコーディングで最も大きな成果を作り上げることができる優れたツールであり、また、最近になって、Access2007の実行のみを可能とするAccess2007 ランタイム日本語版が配布されたことによって、Accessは開発環境としても、そこで開発されたデータベースの配布手段としても利用しやすいものとなったからです。

Access2007を推奨する理由としては、標準でXMLエクスポートのコマンドをサポートしている点です。また、XSLTでの整形もサポートしているため、わずか数行のコードで、綺麗に整形されたKMLを作り上げることが可能です。もちろん、クエリなどを使いこなすことが可能であるならば、より充実したKMLの作成を可能にすることでしょう。

今回は、地震の観測データをKML化するプログラムを作成したいと思います。まずは、テーブル構造を見てみましょう。

図1 今回作成するアプリのテーブル構造
図1 今回作成するアプリのテーブル構造

Accessに1つのテーブル(earthquake⁠⁠、1つのクエリ(earthquake_query⁠⁠、1つの入力フォームを用いた極めてシンプルな構造のアプリケーションを作成することとします。levelが震度表記、chimeiがその震度を観測した地名、addressが住所となります。

重要なのは、このaddressの部分であり、ここには、一般的な住所(マンション名やビル名はNG)を入力する点にだけ注意してください。そしてこのテーブルを元に全ての列を追加した形で、クエリも用意しておきます。

図2 入力用フォームの参考例
図2 入力用フォームの参考例

入力用フォームはフォームウィザードで自動生成したもので、あらかじめテーブルを元に作成したクエリをソースとして作成されています。表形式のフォームにボタンが1つだけで他に何もありません。ポイントとなる点は、このボタンに当てられているVBAのコードと、整形するために使用しているXSLファイルです。ここまでが準備となります。

Access2007とXSLTを使用した整形処理

Accessでは、XML出力する際に、XSLT処理を行わせることができます。XSLTを利用する場合には、XSLファイルを用意します。このXSLファイルは、いわばKMLファイルを作成するためのテンプレートともいえるもので、このXSLファイルの書き方次第で、様々な形でKMLファイルを出力することができるようになります。

まずは、単純に出力するためのXSLファイルの中身を見てみましょう。シンプルなXSLは、震度(level)と住所(address)を使用して、プレイスマークを羅列する形で出力します。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:fx="#fx-functions" exclude-result-prefixes="msxsl fx">
<xsl:output method="xml" encoding="UTF-8" />
<xsl:template match="//dataroot" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<Folder>
  <name>Access2007 to KML</name>
  <xsl:for-each select="earthquake_query">
  <Placemark>
      <name><xsl:value-of select="level" /></name>
      <visibility>0</visibility>
      <address><xsl:value-of select="address" /></address>
  </Placemark>
  </xsl:for-each>
</Folder>
</Document>
</kml>
</xsl:template>
</xsl:stylesheet>

上記のコードが、今回サンプルコードの中で使用したXSLファイルの中身です。このXSLファイルの中身は、XMLを理解していないと、何を意味しているのかがわからないかと思いますので、簡単に説明しておきます。

1.青字のXML宣言部分

この部分は、いつでもこの文で固定です。<Document>タグの手前までは定例的にこの文章が入るかたちで覚えておいてください。なお、KMLは文字コードがUTF-8と決まっていますので、Shift-JISなどで保存しないでください。

2.赤字のxsl:for-each select部分

ここは、本体のVBAでExportXMLで指定したクエリ名を指定します。このfor-eachは繰り返しを意味し、このクエリの中のデータをひとつひとつ繰り返し、KMLとして出力するという意味を持っています。今回は、クエリ名であるearthquake_queryを指定しました。

3.緑字のxsl:value-of select部分

2と同じく、繰り返しを意味します。特に2で指定したクエリの中身のどの列を繰り返し値をはめ込んでいくかを指定します。今回の例では、テーブルにある「level」「address」の列をはめ込むようにしています。また、KMLをジオコーディングさせるために、前後を<address>タグでくくっています。これにより、KMLとして出力した後、Google Earthに読み込ませることで、住所を緯度経度の情報に変換されるようになります。変換そのものは、GoogleのサーバがGoogle Earth上でこのKMLを読み込んだ際に行ってくれます。

ただし、この際、住所以外のデータ(例:マンション名や階数、部屋番号)などが混入すると、正しく緯度経度情報に変換することができなくなるため、住所データを利用する際には、純粋に番地番号までの住所を利用するようにしてください。

それでは、このXSLファイルを用いて、ファイルを出力してみましょう。

図3 単純なXSL処理後のKMLをGoogle Earthで読み込ませてみた
図3 単純なXSL処理後のKMLをGoogle Earthで読み込ませてみた

1つのフォルダの中に、クエリに含まれているデータ群が、1レコードが1プレイスマークとして出力されています。レコードに登録されている順番で出力されていますが、クエリであるため、抽出条件を加えて、レコードを絞った場合にも、その際に掛かっているソートの順番でレコードは出力されます。

コーディング

さて、準備が整ったことで、コーディングを開始します。といっても、わずか数行のVBAコードだけです。ボタンに直接コードを割り当てても結構ですし、標準モジュール化して、callで呼び出すという手段でも構いません。アプリケーションとして作り込むというのであるならば、後者が望ましいでしょう。では、VBAコードを見てみましょう。

‘各種変数を宣言する
Dim stExFile As String
Dim stExXsl As String
Dim stFile_Add As String

‘変数に値を格納する(カレントディレクトリにあるXSLを指定、出力を指定)
stExFile = CurrentProject.path & "\address.xml"
stExXsl = CurrentProject.path & "\ac20072kml.xsl"
stFile_Add = CurrentProject.path & "\address.kml"

‘ExportXMLメソッドを実行する
Application.ExportXML acExportQuery, "earthquake_query", stExFile

‘TransformXMLメソッドで、XSLT整形を施す。
Application.TransformXML stExFile, stExXsl, stFile_Add, False, acPromptScript

この中で注目すべき点は、先に述べた様に、Accessには、XMLで出力するための専用のメソッドの利用ができる点です。そのメソッドはExportXMLとTransformXMLです。この2つのメソッドを組み合わせることで、いとも簡単にクエリやテーブルをXMLとして出力することができ、さらにはXSLTで整形まで数行のコードで実現できてしまいます。赤字の部分がクエリ名であり、このクエリを元に格納されているデータをXML化後、XSLT処理してKML化します。これで完成です。今回のKML出力のフローを図にしてみました。

図4 プログラムの実行フロー
図4 プログラムの実行フロー

いかがでしょうか? 図3は、出力されたあとに、フォルダ単位でスタイルを共通化させてありますので、アイコン等変更してありますが、プログラムでは、このアイコンのスタイルを震度毎に設定したり、また、大きさを変更するなども可能です。その場合には、XSLファイルの<Document&gtタグの直ぐ後に、Styleでいくつかアイコンスタイルなどを用意しておき、Accessのテーブル側は、その際に設定したスタイル名だけを格納しておき、震度に応じてスタイル名を振っておくなどのテクニックが必要になってきます。⁠震度」「震度が観測されたエリア」に応じてアイコンを指定するというかたちになるかと思います。

より応用的な処理の仕方

しかし、このままでは、いかんせんデータとしての扱いとしては十分とはいえません。ユーザに利用してもらうには、例えば、震度5のものだけを表示させたり、関東近辺のみを表示させるような応用的な処理が必要になります。

そこで、これら羅列されているデータをある基準を持ってフォルダに分類し、KMLとして出力させるためのXSLが必要となってきます。

下記のXSLのソースは、そのフォルダ毎分類を震度の列を基準に分類するためのものです。これを改造して使ってみると良いでしょう。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl=http://www.w3.org/1999/XSL/Transform
  xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:fx="#fx-functions" exclude-result-prefixes="msxsl fx">
 <xsl:output method="xml" encoding="UTF-8" />
<xsl:key name="pon" match="earthquake_query" use="level" />
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="//dataroot">
  <kml xmlns="http://earth.google.com/kml/2.1">
  <Document>
  <xsl:for-each select="earthquake_query[not(level = preceding-sibling::earthquake_query/level)]">
      <Folder>
      <name><xsl:value-of select="level"/></name>
      <xsl:for-each select="key('pon', level)">
        <Placemark>
        <name><xsl:value-of select="chimei" /></name>
          <visibility>0</visibility>
          <address><xsl:value-of select="address" /></address>
        </Placemark>
      </xsl:for-each>
      </Folder>
  </xsl:for-each>
  </Document>
  </kml>
</xsl:template>
</xsl:stylesheet>

1.赤字の宣言部分について

のちの緑字の<xsl:for-each select>する際に、クエリ名と分類する際の基準となる列を指定している部分です。Nameは適当な名前で結構です。今回は、ponという名前をつけました。

2.青字の<xsl:for-each select>文について

フォルダに分類するための構文です。詳細はXSLT関係の書籍を参考にしてもらうとして、この構文でlevelに応じてヒットするプレイスマークが次々に分類されてゆきます。

3.緑字の<xsl:for-each select>文について

青字の<xls:for-each select>にてヒットしたプレイスマークの中身を先ほど定義した赤字の宣言部分に応じて、地名をプレイスマーク名、<address>でジオコーディングさせる部分にaddressを指定しています。addressの部分に関しては、<xsl:value-of select="address" />にて、<address>タグの間に記述しています。

それでは、このXSLファイルを用いた場合の出力結果をみてみましょう。

図5 フォルダ毎に分類した後のKMLを読み込ませてみた
図5 フォルダ毎に分類した後のKMLを読み込ませてみた

いかがでしょうか? 見事、震度の列を基準にフォルダが作成されて、その中に、地名をプレイスマーク名としたものが、分類された状態で入っています。ここで、さらに改造を施すとするならば、もうひとつ「都道府県」の列を追加し、この列を基準に出力させてみる、もしくは、今回のXSLファイルにさらに入れ子の形で、震度別都道府県別という複雑な形で出力させてみることでしょう。

なお、今回紹介したプログラムを使うためには、Access本体が必要です。このコードそのものは、Access2000でもそのまま動作いたします。実行のみであれば、下記のAccess2007ランタイム(WindowsXPおよびVista対応⁠⁠、もしくはネット上で他のプログラムと同梱で提供されているAccess2000以降のランタイム(Windows2000以前のOS対応)をご利用ください。プログラムを作成する、改造する場合には、Access本体を購入する必要性があります。

この他に、PHPやVisual Basic、Excel VBA,などで実現する方法もあります。今回のメソッドに関してはAccess専用のメソッドであるため、たとえばExcel VBAで応用することができませんが、その手順は同じものとなります。また、分類や出力方法の指定、整形を担当するXSLファイルは流用することが可能です。

以上が、大量のデータをKMLに変換するアプリケーションの作成に関する説明となります。ウェブでの提供ではさらに、WebAPI化やPHPを利用してMySQLなどからデータを同じくXSLを利用して整形し、ネットワークリンクで提供などより発展的な内容となりますが、基本は同じです。是非お手持ちの大量のデータを世界の皆様にKMLとして提供してみましょう。

おすすめ記事

記事・ニュース一覧