はじめに
ウェブ上で地図の配信を行う手法は、タイルに分割された地図画像をajaxにより書き換える方法と、ベクトルデータを全部・あるいは部分的に読み込む手法が主でした。近年、ベクトルデータをタイル分割し、ajax により書き換える方法が登場しました。それが VectorTileです。このVectorTileの配信を行うオープンソースのモジュールのうちのひとつがTileSplashです。TileSplash は node.js という javascript によるWebサーバのエンジン用ライブラリとして書かれています。プロジェクトは、GitHubで下記にて公開されています。
https://github.com/faradayio/tilesplash
実行に必要なもの
TileSplash を実行させるには、以下のモジュールが必要です。 node.js npm PostgreSQL server PostGIS インストール方法については、割愛します。TileSplash 環境の構築
コマンド・プロンプトにて、npm を利用して SplashTile をインストールします。$ npm install tilesplash尚、-g オプションを使用すると、グローバル環境にモジュールがインストールされますが、ここでは、コマンドを実行したディレクトリ上にモジュールがインストールされるようにします。
PostgreSQL Server に図形テーブルを構築します。注意点として、図形の座標系は、EPSG4326 でないと動作しません。また、ST_Transform(geom,4326) と言った書き方をしてもエラーになるので注意してください。既存のgeometryフィールドが異なるSRIDで作成している場合は、以下のようにフィールドを追加すると良いでしょう。
alter table target_table add column geom2 geometry(‘MultiPolygon’, 4326); update table target_table set geom2 = ST_Transform(geom,4326);エディタで、sptile.js を作成し編集します。
var Tilesplash = require('tilesplash'); // username に postgresql へ接続するユーザ名を指定 // localhost にpostgresql server ホスト名を指定 // dbname に postgresql のデータベース名を指定 var app = new Tilesplash('postgres://username@localhost/dbname); // layer_name はレイヤ名で、ajax によるリクエストの一部として扱われる // table_name は図形テーブル名 // geom は図形フィールド名 // ここではシンプリファイをかけていますが、tile パラメータの x 値により // シンプリファイをかけるパラメータを変更する必要があると思われます app.layer('layer_name', function(tile, render){ render('SELECT ST_AsGeoJSON(ST_Simplify(geom,0.005)) as the_geom_geojson’ ‘FROM target_table WHERE ST_Intersects(St_Simplify(geom,0.005), !bbox_4326!)'); }); // ポート3000にて、Webサーバを起動します app.server.listen(3000);このまま稼働させると、レスポンスが javascript になるため、違うサイト間でのリクエストで CORS(Cross Origin Resource Sharing)の制約にひっかかって動作しない可能性があります。具体的には「No 'Access-Control-Allow-Origin' header is present」といったエラーがブラウザにより返されます。これを解消するには、以下のモジュールを利用します。
http://www.slideshare.net/kitfactory/web-api-34814937
$npm install corser
でモジュールをインストールし、
node_mojules/tilesplash/lib/index.js
ファイルに以下の修正を施します。
this.server.use(pgMiddleware(dbOptions)); var corser = require("corser"); // 以下の2行を CORS 対策として挿入 this.server.use(corser.create()); this.cacheOptions = cacheOptions || {}; this._cache = new Caching(cacheType || 'memory', cacheOptions);これは、レスポンス・ヘッダに
Access-Control-Allow-Origin: *
を付加する事になります。
クライアント実装例
ローカルホストの node サーバに対して、アクセスする例です。<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>GSI Tiles on OpenLayers 3</title> <link rel="stylesheet" href="http://openlayers.org/en/v3.10.1/css/ol.css" type="text/css"> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <script src="http://openlayers.org/en/v3.10.1/build/ol.js" type="text/javascript"></script> <style> body {padding: 0; margin: 0} html, body, #map {height: 100%; width: 100%;} </style> </head> <body> <div id="page"> <div id="head"></div> <div id="main"> <div id="map" style="float:right"; width:640px; margin:0; padding:0; ></div> <div id="left" style="float:left; width:300px; margin:0; padding:0;"></div> </div> </div> <script> var map = new ol.Map({ target: "map", renderer: ['canvas', 'dom'], layers: [ // 地理院タイル・レイヤ new ol.layer.Tile({ source: new ol.source.XYZ({ attributions: [ new ol.Attribution({ html: "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>" }) ], url: "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png", projection: "EPSG:3857" }) }), // topoJson レイヤ (splashtile から引く) new ol.layer.Vector({ source: new ol.source.TileVector({ format: new ol.format.TopoJSON(), projection: 'EPSG:3857', tileGrid: new ol.tilegrid.createXYZ({ maxZoom: 19 }), url: 'http://localhost:3000/' + 'test_layer/{z}/{x}/{y}.topojson' }), style: new ol.style.Style({ fill: new ol.style.Fill({ color: '#9db9e8' }), stroke: new ol.style.Stroke({ color: '#FF0000' }) }) }) ], controls: ol.control.defaults({ attributionOptions: ({ collapsible: false }) }), view: new ol.View({ projection: "EPSG:3857", center: ol.proj.transform([138.7313889, 35.3622222], "EPSG:4326", "EPSG:3857"), maxZoom: 18, zoom: 5 }) }); </script> </body> </html>実行すると、こんな感じになります。 file:/// 上から実行すると、CORSにひっかかります。chrome ではなく、safari で実行しました。 CORS対策の部分は、もうちょい真面目にやらないとダメかもしれません。
0 件のコメント:
コメントを投稿