Wednesday, November 6, 2013

技術|OpenLayersでGoogle MapとWMSマップを重ねる (Mac OSX 10.8.4)

Shigetです。Marvericksは様子見です。

今回、OpenLayersを利用してGoogle MapとMapServerによるWMSで作成したマップを重ねてみました。

0.リファレンス



▼ 環境の前提

MapserverをMacOS10.8.4へインストールする も参考になるかと思います。

  • Mac OSX 10.8.4 Mountain Lion
  • Apache+PHP
  • MapServerと周辺ライブラリ群一式

1.境界データの準備


テストデータとして、政府の統計窓口から千代田区内の町丁字境界データを入手します。

▼千代田区の境界&人口データをダウンロード

http://www.e-stat.go.jp/SG1/estat/toukeiChiri.do?method=init
平成22年国勢調査(小地域)から「男女別人口総数及び世帯総数」を選択

地域選択で千代田区を選び、境界データ「世界測地系経度緯度座標系・Shape形式」をダウンロードします。

▼ogr2ogrでMySQLへ取り込み

詳しくは「MySQLにシェープファイル(*.shp)をインポートする (Mac OS X 10.8.4)」をご覧いただくとして、下記コマンドでインポートします。

user$ ogr2ogr -s_srs EPSG:4612 -f MySQL MySQL:hojyo,user=root,host=localhost,password=xxxx h22ka13101.shp -lco engine=MYISAM,CHARSET=utf8 -nln chiyoda_boundary -append

投影座標系はEPSG:4612 (世界測地系(新日本測地系))、MySQLに作成したDB (DB名: hojyo、user名:root、pass:xxxx←ダミー、host名:localhost)にchiyoda_boundaryという名前でシェープファイルをインポートしています。

2.WMS向けのマップファイルの作成


MapServerのMapfileは以下のように作成しました。Webディレクトリに置きます。今回、OpenLayersでオーバレイするだけなので最低限の指定です。

”chiyoda.map”
MAP
 NAME "Chiyoda"
 EXTENT 139.77246 35.60397 139.87246 35.80397 # 投影範囲
 PROJECTION # 投影座標系
  "init=EPSG:4612"
 END

 WEB
  METADATA
  "wms_srs" "EPSG:4612 EPSG:900913" # WMSとして利用する投影座標系
  "ows_enable_request" "*" #WMSとして受け付けるリクエスト
  END
 END

 LAYER
  NAME "chiyoda_boundary"
  TYPE LINE
  CONNECTIONTYPE OGR # MySQLをOGR経由で接続
  CONNECTION "MySQL:hojyo,user=root,password=xxxx" # MySQLへ接続
  DATA "SELECT SHAPE FROM chiyoda_boundary" # データの読み出し
  STATUS ON
  TRANSPARENCY 80 ## 透過設定
  CLASS
   COLOR 0 0 100
  END
 END
END

Mapfileをのぞいてみます。

EXTENTは投影範囲ですが、ターミナルからogrinfoでシェープファイルのExtentを抽出して設定しました。
例)ogrinfo -al h22ka13101.shp | grep -i extent

PROJECTIONは投影座標系です。4612はインポートしたシェープファイルの投影座標系(世界測地系(新日本測地系))です。

WEBの中では、WMSとして必要な設定を渡しています。wms_srsはWMSサービスで利用する投影座標系、900913はGoogle mapで使われている投影座標系です。また、own_enable_requestはWMSで利用できるサービスを設定します。今回は、すべてのサービスを利用できるようにしてあります。

LAYERクラスでは、MySQLからデータを読み出しています。

3. Proj4の設定


Mapfileでは900913というGoogle mapの投影座標系を設定しましたが、この座標系を利用するには、投影座標変換を行うProj4に設定を追加する必要があります。

Proj4の設定ファイルepsgファイルをエディタで開いて、末端に下記をくっつけます。

<900913> +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs <>

4. OpenLayers の設置


詳しくは、ダウンロードしてきたファイルのReadmeを参照ください。

OpenLayersはJavascriptのライブラリなので、Web用のディレクトリに設置すれば利用できます。解凍ファイルに含まれているOpenLayers.jsファイル、themeおよびimgディレクトリとファイル群をサーバー上の同じディレクトリに置きます。

そして、OpenLayersを利用したい時はhtmlファイルで呼び出して利用します。

例) <script type="text/javascript" src="/OpenLayers.js" />

5. テスト用のHTMLの作成


OpenLayersはJavascriptなので、HTMLに直接Javascriptを書いても、外部jsファイルとして呼び出して利用してもかまいません。今回は、HTMLに直接書いています。


"chiyoda.html"
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>OpenLayers Example</title>
</head>
<script src="lib/openlayers/OpenLayers.js"></script>
<script src="http://maps.google.co.jp/maps/api/js?v=3.5&sensor=false&language=ja"></script>
<script type="text/javascript">
function init(){ 
// mapインスタンスのオプション設定 
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
units: "m",
}; 
// mapインスタンスの作成 
var map = new OpenLayers.Map('map', options);
map.addControl( new OpenLayers.Control.LayerSwitcher() );
// Google layerの追加
var gmap = new OpenLayers.Layer.Google(
"Google map", {
sphericalmercator: true
}
); 
// 千代田区のWMS Layerの追加 
var wms = new OpenLayers.Layer.WMS(
"Chiyoda", "http://localhost/cgi-bin/mapserv?", {
map:"/Library/WebServer/Documents/boundary.map",
layers: "chiyoda_boundary",
format: "image/png",
transparent: true
}
);
map.addLayers([gmap, wms]);

// 中心点の変換(EPSG:4326 世界測地系→EPSG:900913 Spherical Mercator)
var proj = new OpenLayers.Projection("EPSG:4326");
var point = new OpenLayers.LonLat(139.75361, 35.69388);
map.setCenter(point.transform(proj, map.getProjectionObject()), 14);

}
</script>
<style type="text/css">
#map {
width: 100%;
height: 480px;
border: solid 1px #999;
}
</style>
<body onload="init()">
<div id="map"></div>
</body>
</html>

ヘッダ部分から見てみます。

<script src="lib/openlayers/OpenLayers.js"></script>で、OpenLayersの外部jsファイルを読み込みます。

<script src="http://maps.google.co.jp/maps/api/js?v=3.5&sensor=false&language=ja"></script> では、Google MapのAPIを呼び出しています。

その後、JavascriptでOpenLayersのmapインスタンスを作り、その後Google MapとWMSレイヤーの設定やコントロールの呼び出し、中心点の設定(千代田区役所の経度緯度)を行っています。

地図の大きさは、スタイルシートを使って設定しています。

以上、詳しいことはリファレンスをご覧ください。

6. 実行結果


ブラウザを通してchiyoda.htmlにアクセスすると、ちゃんと重なりました!

ブラウザから見るときちんと重なっていますよ。

7.そのほか


▼ 世界測地系の謎 (コンボイの謎じゃないよ)

世界測地系って一種類かと思っていたのですが、EPSGを見ていると、同じ世界測地系でも4612と4326があります。

世界測地系:JGD2000(EPSG:46121)

JGD2000は世界測地系の方法に乗っ取って作られた測地系です。日本の行政で利用されていた旧日本測地系(Tokyo)の後継として利用されています。

WGS84はアメリカが整備し、GPSなどで使われている世界測地系です。

基本概念は同じだけれども、微妙に手法や精度が異なるそうです。

No comments: