Contenu connexe
Similaire à FOSS4G 2012 Osaka (20)
FOSS4G 2012 Osaka
- 2. 自己紹介
● 2003年 - 2006年
– Arc・・・でGIS、RSデビュー@大学
● 2006 – 2008
– GISとかRSから離れ石垣島に通いつめる@大学院
● 2008 – 現在
– Mapserverを弄りまくる@マピオン
- 3. おしながき
今回はほとんどgdal/ogrの話です
混み入った処理の話はあまりないです
実際に動いているAPIと使うデータの仕組みを
できる限りそのままお届けすること目標に
● 標高API
● リバースジオコーダAPI
- 4. データ作成/APIの目標
● 高いパフォーマンス
– タイル画像に次いで回数を呼ばれるAPIなので
– APPサーバは4台
– APPサーバ1台あたり標高APIが250万回/日、リ
バースジオコーダAPIが340万回/日呼ばれる
● DBを使わない
– ライブラリ + dataで完結すれば環境構築が容易
– 色々なところに組み込みやすい
– ミドルウェア増やしたくない・・・
- 5. 標高API 概要 1
● 機能
– 標高
● 入力地点の標高がわかります
● 複数地点、区間での入力も可
– 日の出日の入り、月の出月の入り
● 入力地点の日の出日の入り、月の出月の入りの時間、方角
がわかります
● 標高を元に計算
● 要件
– 1スクロールに1回呼ばれる
● PC, スマホ、FPなどすべてのデバイスから呼ばれる
(ピーク時で秒間50回ぐらい)
- 6. 標高API概要 2
● 材料
– 基盤地図情報 10m DEM
● 配信
– Glassfish v2.1 + varnish
– Java EE6(JAX-RS)をつかってみました(glassfish
v2の上でうごいでるけど・・・)
- 9. データの持ち方
● GeoTIFF
– 等高線、段彩に使うポリゴンの中間生成物
– NFS上に配置
● 2次メッシュ単位
– 基盤地図情報の10m標高そのまま
– パフォーマンス的にも妥当だった
- 10. データの作り方
基盤地図情報
基盤地図情報
(gml)
(gml)
基盤地図情報対応GDAL/OGR を使えば
基盤地図情報対応GDAL/OGR を使えば
プログラミング無しでGeoTIFFになります
プログラミング無しでGeoTIFFになります
http://www.osgeo.jp/foss4g-mext/
http://www.osgeo.jp/foss4g-mext/
- 11. APIの仕組み
2次メッシュ算出 ランダムアクセス
ファイル内
経度緯度 geotiffファイル特 で
ピクセル座標算出
定 ピクセル値取得
● とってもシンプル設計です
● 画像へのアクセスをするためのライブラリが
豊富
– ImageMagick, libpng, libtiff, libjpeg
– JAI(Java Advanced Imaging)
– PIL(Python Imaging Library)
- 12. //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);
- 13. ピクセル座標の算出 GeoTIFFのヘッダ使うパ
ターン
(javaだけしか試してないのでjavaだけ)
int TIEPOINT_TAG = 33922;
int PIXEL_SCALE_TAG = 33550; ・GeoTIFFの仕様
int WIDTH_TAG = 256; http://www.remotesensing.org/geotiff/spec/geot
int 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);
・TIEPOINT
long 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);
- 14. リバースジオコーダAPI概要1
● 機能
– 住所情報を返します
● 経度緯度からその地点の住所情報を返します
● 要件
– 1スクロールに1回呼ばれる
● PC, スマホ、FPなどすべてのデバイスから呼ばれる
(ピーク時で秒間50回ぐらい)
– 独自にメンテナンス可能
● 市区町村統廃合などに対応したいので
- 15. リバースジオコーダAPI概要 2
● 材料
– Zenrin住所ポリゴン
– 国土数値情報の行政区域データでも応用できるは
ず
● 配信
– Glassfish v2.1 + varnish
– Cubby (地図配信APIの一機能として稼働)
- 17. 用途
● 住所付与
– 緯度経度のみのPOIデータに対して住所を付与
– DBから直接呼んだり、API叩いたり
- 18. データの持ち方と仕組み
ピクセル値がデータファイルのインデック
スになってるラスタ(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
– 色々試した結果一番効率 – 頑張ればスマホにだっ
がよかったので てつめちゃうぞ!!
- 19. データの作り方
住所polygon1
フィールドには住所
住所情報1
コード(shape file) (漢字、読み、
コード)
ポリゴンの重なりを 住所コード変換 市区町村合併等の
除去し1次メッシュ単 テーブル
位でshapeを統合 処理
+C
住所polygon2 住所情報2
フィールドには住所 紐付け処理 (漢字、読み、
コード コード)
住所polygon3
フィールドにはイン
デックス 住所データ
ラスタライズ ラスターデータ
値はインデックス (Byte, UInt16,
(最大indexによてデータ Int32)
型が3パターン)
- 20. データの作り方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}"
- 21. APIの仕組み
2次メッシュ算出 ランダムアクセス
ファイル内
経度緯度 geotifファイル特 で
ピクセル座標算出
定 ピクセル値取得
ピクセル値でデー
タファイルから住
所取得
● 基本的な仕組みは標高APIと同じ
– 1工程多いだけです
● 一部メモリ上にデータをキャッシュ
– 住所の漢字、読み、コードのデータは全体で40Mだけなの
で
- 22. ラスターデータを使う場合の注意点
● 精度
– ラスターの解像度に依存する
● 解像度が高ければ
– 精度は向上(元データがラスターの場合元データの解像度が限界)
– サイズは肥大化
– 精度が求められるとき
● ベクターデータに対して空間検索等すべき
– 地図タイルと一緒に使う場合
● 精度はタイル画像と同じでよい
● 飛び地
– 住所を扱う場合小さな領域が消えてしまうかもしれない
- 23. まとめ
● ラスターは画像として見せる以外にもピクセル
値を使うことで色々なAPIに利用できる
● パフォーマンスもいい!
● ベクター - ラスター間の変換や処理には
gdal/ogrだけでもかなりできる
● ラスターをインデックスとして使うときにはベ
クターが元データの場合空間解像度に気をつけ
る
● FOSS4Gは専門的なGISの処理を身近にしてく
れるから使う!