SlideShare ist ein Scribd-Unternehmen logo
1 von 24
地図画像だけじゃない!

 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/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);
リバースジオコーダ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の処理を身近にしてく
    れるから使う!
ご清聴ありがとうございマピオン

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (16)

実践QBVH
実践QBVH実践QBVH
実践QBVH
 
色々なOSSで競技プログラミング
色々なOSSで競技プログラミング色々なOSSで競技プログラミング
色々なOSSで競技プログラミング
 
CMSI計算科学技術特論B(11) 大規模MD並列化の技術2
CMSI計算科学技術特論B(11) 大規模MD並列化の技術2CMSI計算科学技術特論B(11) 大規模MD並列化の技術2
CMSI計算科学技術特論B(11) 大規模MD並列化の技術2
 
El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613
 
MapReduceによる大規模データ処理 at Yahoo! JAPAN
MapReduceによる大規模データ処理 at Yahoo! JAPANMapReduceによる大規模データ処理 at Yahoo! JAPAN
MapReduceによる大規模データ処理 at Yahoo! JAPAN
 
CMSI計算科学技術特論B(10) 大規模MD並列化の技術1
CMSI計算科学技術特論B(10) 大規模MD並列化の技術1CMSI計算科学技術特論B(10) 大規模MD並列化の技術1
CMSI計算科学技術特論B(10) 大規模MD並列化の技術1
 
第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)
 
numpyの魅力
numpyの魅力numpyの魅力
numpyの魅力
 
K-means hashing (CVPR'13) とハッシング周り
K-means hashing (CVPR'13) とハッシング周りK-means hashing (CVPR'13) とハッシング周り
K-means hashing (CVPR'13) とハッシング周り
 
Umemoto m
Umemoto mUmemoto m
Umemoto m
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
新版 OutOfMemoryErrorを知る
新版 OutOfMemoryErrorを知る新版 OutOfMemoryErrorを知る
新版 OutOfMemoryErrorを知る
 
El text.tokuron a(2019).katagiri190425
El text.tokuron a(2019).katagiri190425El text.tokuron a(2019).katagiri190425
El text.tokuron a(2019).katagiri190425
 
電子動力学アプリケーションの最適化2
電子動力学アプリケーションの最適化2電子動力学アプリケーションの最適化2
電子動力学アプリケーションの最適化2
 
2011 06 18_open_streetmap_neta_no1
2011 06 18_open_streetmap_neta_no12011 06 18_open_streetmap_neta_no1
2011 06 18_open_streetmap_neta_no1
 
Lispmeetup #45 Common Lispで音声合成
Lispmeetup #45 Common Lispで音声合成Lispmeetup #45 Common Lispで音声合成
Lispmeetup #45 Common Lispで音声合成
 

Andere mochten auch

古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介
古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介
古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介
IWASAKI NOBUSUKE
 
FOSS4Gでオープンデータも 超簡単 FOSS4GツールとOSGeo財団 日本支部・ 宇宙利用プロジェクトのご紹介
FOSS4Gでオープンデータも超簡単FOSS4GツールとOSGeo財団 日本支部・宇宙利用プロジェクトのご紹介FOSS4Gでオープンデータも超簡単FOSS4GツールとOSGeo財団 日本支部・宇宙利用プロジェクトのご紹介
FOSS4Gでオープンデータも 超簡単 FOSS4GツールとOSGeo財団 日本支部・ 宇宙利用プロジェクトのご紹介
FOSS4G_MEXT
 
ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!
ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!
ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!
IWASAKI NOBUSUKE
 
小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会
小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会
小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会
FukuyamaKaoru
 
QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版
QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版
QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版
FOSS4G_MEXT
 

Andere mochten auch (12)

古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介
古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介
古い地図っていいよね!! 歴史的農業環境閲覧システムのご紹介
 
FOSS4Gでオープンデータの 可視化にチャレンジ!
FOSS4Gでオープンデータの可視化にチャレンジ!FOSS4Gでオープンデータの可視化にチャレンジ!
FOSS4Gでオープンデータの 可視化にチャレンジ!
 
FOSS4Gでオープンデータも 超簡単 FOSS4GツールとOSGeo財団 日本支部・ 宇宙利用プロジェクトのご紹介
FOSS4Gでオープンデータも超簡単FOSS4GツールとOSGeo財団 日本支部・宇宙利用プロジェクトのご紹介FOSS4Gでオープンデータも超簡単FOSS4GツールとOSGeo財団 日本支部・宇宙利用プロジェクトのご紹介
FOSS4Gでオープンデータも 超簡単 FOSS4GツールとOSGeo財団 日本支部・ 宇宙利用プロジェクトのご紹介
 
GDALとmod_python、mod_rewriteでタイルマップサービスを作ってみた
GDALとmod_python、mod_rewriteでタイルマップサービスを作ってみたGDALとmod_python、mod_rewriteでタイルマップサービスを作ってみた
GDALとmod_python、mod_rewriteでタイルマップサービスを作ってみた
 
植生タイルの作り方
植生タイルの作り方植生タイルの作り方
植生タイルの作り方
 
QGISセミナー・中級編 Ver. 2.4版
QGISセミナー・中級編 Ver. 2.4版QGISセミナー・中級編 Ver. 2.4版
QGISセミナー・中級編 Ver. 2.4版
 
ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!
ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!
ご存じですか?QGIS・GDAL/OGRで基盤地図情報が使えます!
 
FOSS4Gで地理院地図
FOSS4Gで地理院地図FOSS4Gで地理院地図
FOSS4Gで地理院地図
 
FOSS4G 2015 Osakaハンズオン資料
FOSS4G 2015 Osakaハンズオン資料FOSS4G 2015 Osakaハンズオン資料
FOSS4G 2015 Osakaハンズオン資料
 
小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会
小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会
小学生がQGISで地域の防災マップ作り_名古屋FOSS4G勉強会
 
QGISセミナー初級編 ~QGISの使い方・実践編~ Ver. 2.4版
QGISセミナー初級編 ~QGISの使い方・実践編~ Ver. 2.4版QGISセミナー初級編 ~QGISの使い方・実践編~ Ver. 2.4版
QGISセミナー初級編 ~QGISの使い方・実践編~ Ver. 2.4版
 
QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版
QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版
QGISセミナー初級 ~QGISの使い方・基礎編~ Ver. 2.4版
 

Ähnlich wie FOSS4G 2012 Osaka

ツイートID生成とツイッターリアルタイム検索システムの話
ツイートID生成とツイッターリアルタイム検索システムの話ツイートID生成とツイッターリアルタイム検索システムの話
ツイートID生成とツイッターリアルタイム検索システムの話
Preferred Networks
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
Takeshi Yamamuro
 
Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化
Katsutoshi Makino
 
Exgettextの話
Exgettextの話Exgettextの話
Exgettextの話
k1complete
 
20130626 kawasaki.rb NKT77
20130626 kawasaki.rb NKT7720130626 kawasaki.rb NKT77
20130626 kawasaki.rb NKT77
nkt77
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrake
Masahiro Tanaka
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミング
Kiwamu Okabe
 

Ähnlich wie FOSS4G 2012 Osaka (20)

ツイートID生成とツイッターリアルタイム検索システムの話
ツイートID生成とツイッターリアルタイム検索システムの話ツイートID生成とツイッターリアルタイム検索システムの話
ツイートID生成とツイッターリアルタイム検索システムの話
 
CEDEC 2007 ゲーム開発者向け最新技術論文の解説・実装講座
CEDEC 2007 ゲーム開発者向け最新技術論文の解説・実装講座CEDEC 2007 ゲーム開発者向け最新技術論文の解説・実装講座
CEDEC 2007 ゲーム開発者向け最新技術論文の解説・実装講座
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
Rを用いたGIS
Rを用いたGISRを用いたGIS
Rを用いたGIS
 
Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化
 
ROS 2 Client Library for E^2
ROS 2 Client Library for E^2ROS 2 Client Library for E^2
ROS 2 Client Library for E^2
 
Exgettextの話
Exgettextの話Exgettextの話
Exgettextの話
 
20130626 kawasaki.rb NKT77
20130626 kawasaki.rb NKT7720130626 kawasaki.rb NKT77
20130626 kawasaki.rb NKT77
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrake
 
第162回情報処理学会ハイパフォーマンスコンピューティング研究発表会
第162回情報処理学会ハイパフォーマンスコンピューティング研究発表会第162回情報処理学会ハイパフォーマンスコンピューティング研究発表会
第162回情報処理学会ハイパフォーマンスコンピューティング研究発表会
 
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうかOedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 
pgGeocoderのご紹介
pgGeocoderのご紹介pgGeocoderのご紹介
pgGeocoderのご紹介
 
GIF89a Oldtype
GIF89a OldtypeGIF89a Oldtype
GIF89a Oldtype
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミング
 
kibayos ieice 090915
kibayos ieice 090915kibayos ieice 090915
kibayos ieice 090915
 
An evaluation of Distributions of the Environmental pollutants by (Web)GIS and R
An evaluation of Distributions of the Environmental pollutants by (Web)GIS and RAn evaluation of Distributions of the Environmental pollutants by (Web)GIS and R
An evaluation of Distributions of the Environmental pollutants by (Web)GIS and R
 
V6 unix in okinawa
V6 unix in okinawaV6 unix in okinawa
V6 unix in okinawa
 
Meta Quest 2でUSBシリアル通信してみた
Meta Quest 2でUSBシリアル通信してみたMeta Quest 2でUSBシリアル通信してみた
Meta Quest 2でUSBシリアル通信してみた
 
G2o
G2oG2o
G2o
 

FOSS4G 2012 Osaka

  • 1. 地図画像だけじゃない! Mapion x FOSS4G 株式会社マピオン  松浦慎平 (@PEmugi)
  • 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の処理を身近にしてく れるから使う!