FOSS4G 2012 Osaka
Upcoming SlideShare
Loading in...5
×
 

FOSS4G 2012 Osaka

on

  • 1,184 views

 

Statistics

Views

Total Views
1,184
Views on SlideShare
1,184
Embed Views
0

Actions

Likes
1
Downloads
3
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

FOSS4G 2012 Osaka FOSS4G 2012 Osaka Presentation Transcript

  • 地図画像だけじゃない! Mapion x FOSS4G 株式会社マピオン 松浦慎平 (@PEmugi)
  • 自己紹介● 2003年 - 2006年 – Arc・・・でGIS、RSデビュー@大学● 2006 – 2008 – GISとかRSから離れ石垣島に通いつめる@大学院● 2008 – 現在 – Mapserverを弄りまくる@マピオン
  • おしながき 今回はほとんどgdal/ogrの話です 混み入った処理の話はあまりないです 実際に動いているAPIと使うデータの仕組みを できる限りそのままお届けすること目標に● 標高API● リバースジオコーダAPI
  • データ作成/APIの目標● 高いパフォーマンス – タイル画像に次いで回数を呼ばれるAPIなので – APPサーバは4台 – APPサーバ1台あたり標高APIが250万回/日、リ バースジオコーダAPIが340万回/日呼ばれる● DBを使わない – ライブラリ + dataで完結すれば環境構築が容易 – 色々なところに組み込みやすい – ミドルウェア増やしたくない・・・
  • 標高API 概要 1● 機能 – 標高 ● 入力地点の標高がわかります ● 複数地点、区間での入力も可 – 日の出日の入り、月の出月の入り ● 入力地点の日の出日の入り、月の出月の入りの時間、方角 がわかります ● 標高を元に計算● 要件 – 1スクロールに1回呼ばれる ● PC, スマホ、FPなどすべてのデバイスから呼ばれる (ピーク時で秒間50回ぐらい)
  • 標高API概要 2● 材料 – 基盤地図情報 10m DEM● 配信 – Glassfish v2.1 + varnish – Java EE6(JAX-RS)をつかってみました(glassfish v2の上でうごいでるけど・・・)
  • 用途
  • 用途
  • データの持ち方● GeoTIFF – 等高線、段彩に使うポリゴンの中間生成物 – NFS上に配置● 2次メッシュ単位 – 基盤地図情報の10m標高そのまま – パフォーマンス的にも妥当だった
  • データの作り方基盤地図情報基盤地図情報 (gml) (gml) 基盤地図情報対応GDAL/OGR を使えば 基盤地図情報対応GDAL/OGR を使えば プログラミング無しでGeoTIFFになります プログラミング無しでGeoTIFFになります http://www.osgeo.jp/foss4g-mext/ http://www.osgeo.jp/foss4g-mext/
  • APIの仕組み 2次メッシュ算出 ランダムアクセス ファイル内経度緯度 geotiffファイル特 で ピクセル座標算出 定 ピクセル値取得● とってもシンプル設計です● 画像へのアクセスをするためのライブラリが 豊富 – ImageMagick, libpng, libtiff, libjpeg – JAI(Java Advanced Imaging) – PIL(Python Imaging Library)
  • //2次メッシュコードを求める ピクセル座標の算出double y1 = lat * 60 / 40;double y2 = lat * 60 % 40 / 5;double x1 = Math.floor(lon - 100);double x2 = (lon - Math.floor(lon)) * 60 / 7.5;int code1 = (int) y1 * 100 + (int) x1;int code2 = (int) y2 * 10 + (int) x2;int level2 = code1 * 100 + code2//2次メッシュの左上緯度経度を求めるint code1 = code / 100;int code2 = code - code1 * 100;double yMesh1 = (double) (code1 / 100) / 3.0 * 2.0;double xMesh1 = (code1 - code1 / 100 * 100) + 100;int code2y = code2 / 10;int code2x = code2 - code2y * 10;double yMesh2 = code2y * (2.0 / 3.0 / 8.0);double xMesh2 = code2x * (1.0 / 8.0);double minx = xMesh1 + xMesh2;double miny = yMesh1 + yMesh2;double maxx = minx + (1.0 / 8.0);double maxy = miny + (2.0 / 3.0 / 8.0);//ピクセル座標を求めるdouble uppx = 1.0 / 8.0 / 1125;double uppy = 2.0 / 3.0 / 8.0 / 750;int xIndex = (int) ((lon – minx) / uppx);int yIndex = (int) ((maxy – lat) / uppy);
  • ピクセル座標の算出 GeoTIFFのヘッダ使うパ ターン (javaだけしか試してないのでjavaだけ)int TIEPOINT_TAG = 33922;int PIXEL_SCALE_TAG = 33550; ・GeoTIFFの仕様int WIDTH_TAG = 256; http://www.remotesensing.org/geotiff/spec/geotint HEIGHT_TAG = 257;FileSeekableStream s = new FileSeekableStream(file); ・tiffの仕様TIFFDirectory d = new TIFFDirectory(s, 0); //1directoryの画像の http://partners.adobe.com/public/developer/tiff/場合TIFFField widthField = d.getField(WIDTH_TAG);TIFFField heightField = d.getField(HEIGHT_TAG); com.sun.media.jai.codecパッケージで簡単TIFFField pixelScaleField = d.getField(PIXEL_SCALE_TAG); に画像情報にアクセスできます。TIFFField tiePointField = d.getField(TIEPOINT_TAG);long width = widthField.getAsLong(0); ・TIEPOINTlong height = heightField.getAsLong(0); (...,I,J,K, X,Y,Z...)double[] pixelScale = pixelScaleField.getAsDoubles(); (I,J)がピクセル座標tiepoints = tiePointField.getAsDoubles(); (X,Y)がデータの座標系での座標s.close();double uppx = pixelScale[0];double uppy = pixelScale[1];double minx = tiepoints[3] - uppx * tiepoints[0];double maxy = tiepoints[4] + uppy * tiepoints[1];double maxx = minx + uppx * width;double miny = maxy - uppy * height;int xIndex = (int) ((lon – minx) / uppx);int yIndex = (int) ((maxy – lat) / uppy);
  • リバースジオコーダAPI概要1● 機能 – 住所情報を返します ● 経度緯度からその地点の住所情報を返します● 要件 – 1スクロールに1回呼ばれる ● PC, スマホ、FPなどすべてのデバイスから呼ばれる (ピーク時で秒間50回ぐらい) – 独自にメンテナンス可能 ● 市区町村統廃合などに対応したいので
  • リバースジオコーダAPI概要 2● 材料 – Zenrin住所ポリゴン – 国土数値情報の行政区域データでも応用できるは ず● 配信 – Glassfish v2.1 + varnish – Cubby (地図配信APIの一機能として稼働)
  • 用途
  • 用途● 住所付与 – 緯度経度のみのPOIデータに対して住所を付与 – DBから直接呼んだり、API叩いたり
  • データの持ち方と仕組み ピクセル値がデータファイルのインデック スになってるラスタ(1次メッシュ) 対になるラスタに含まれる住所データ(バイ ナリ) 1 2 -------index section------- 1 1: 県index,市区町村index,大字index,字丁目index 2: 県index,市区町村index,大字index,字丁目index … 2800: 県index,市区町村index,大字index,字丁目index 3 -------県 section------- 4 北海道青森県 -------市区町村 section------- 旭川市江別市札幌市1条通り... -------大字 section------- 6 東南里塚緑ケ丘平和... 5 -------小字丁目 section------- 1丁目2丁目3丁目4丁目... 8 7● GeoTIFF ● 日本全国街区番号まで● 1次メッシュ 入れて1.2GB – 色々試した結果一番効率 – 頑張ればスマホにだっ がよかったので てつめちゃうぞ!!
  • データの作り方 住所polygon1 フィールドには住所 住所情報1 コード(shape file) (漢字、読み、 コード)ポリゴンの重なりを 住所コード変換 市区町村合併等の除去し1次メッシュ単 テーブル 位でshapeを統合 処理 +C 住所polygon2 住所情報2 フィールドには住所 紐付け処理 (漢字、読み、 コード コード) 住所polygon3 フィールドにはイン デックス 住所データ ラスタライズ ラスターデータ 値はインデックス (Byte, UInt16, (最大indexによてデータ Int32) 型が3パターン)
  • データの作り方2● ポリゴンの重なり除去 – OGR_L_SetSpatialFilterで対象ポリゴンと重なっている ポリゴンを検索! – OGR_G_Differenceで対象ポリゴンと重なっているポリ ゴンの重なって無い部分だけ抽出! インデックスの数で 決める● ラスタライズ – gdal_rasterize -a_nodata 0 -ot {Byte,UInt16,UInt32} -co "COMPRESS=LZW" -te {region} -tr {upp} {upp} -a idx -of GTiff -l {layername} {input} {output}"
  • APIの仕組み 2次メッシュ算出 ランダムアクセス ファイル内経度緯度 geotifファイル特 で ピクセル座標算出 定 ピクセル値取得 ピクセル値でデー タファイルから住 所取得● 基本的な仕組みは標高APIと同じ – 1工程多いだけです● 一部メモリ上にデータをキャッシュ – 住所の漢字、読み、コードのデータは全体で40Mだけなの で
  • ラスターデータを使う場合の注意点● 精度 – ラスターの解像度に依存する ● 解像度が高ければ – 精度は向上(元データがラスターの場合元データの解像度が限界) – サイズは肥大化 – 精度が求められるとき ● ベクターデータに対して空間検索等すべき – 地図タイルと一緒に使う場合 ● 精度はタイル画像と同じでよい● 飛び地 – 住所を扱う場合小さな領域が消えてしまうかもしれない
  • まとめ● ラスターは画像として見せる以外にもピクセル 値を使うことで色々なAPIに利用できる● パフォーマンスもいい!● ベクター - ラスター間の変換や処理には gdal/ogrだけでもかなりできる● ラスターをインデックスとして使うときにはベ クターが元データの場合空間解像度に気をつけ る● FOSS4Gは専門的なGISの処理を身近にしてく れるから使う!
  • ご清聴ありがとうございマピオン