Code for History

"Code for History"はIT技術を歴史学上の問題の解決に使うコミュニティです。強調したいのは、我々にとってIT技術は「手段」であって「目的」ではありません。「目的」は歴史学上の問題を解決する事であって、必要であればITでない手段も活用します。常に最優先なのは、問題を解決することです。

ちずぶらりの座標変換性能が思った以上に酷かった & ThinPlateSplineJSに代わる愛称募集

オープンソースでちずぶらりの代替に使えるThinPlateSplineJSも作ったので、ちずぶらりとの性能比較もやらなきゃなあと思ったまま放置してきたのですが、ようやくやってみました。
比較とか言う前にそれぞれのライブラリでも単独で機能確認しておくべきだったものの、ちずぶらり内部にいた頃はサボってしまっていたのですが、今回初めて行ったところ、ちずぶらりの変換性能が思った以上に悪い事が判明しました。
まあ、2年前の私のレベル、という事で…。

比較条件

お題の変換元は、ちずぶらりの1タイトル『ふじぶらり』の中に含まれている、『マイレール・岳南鉄道ラシックス』のデータを使いました。
本来、ちずぶらりは歪んだ古地図を扱うための技術なので、このデータで使われているような正確な地図は不得手ではあるのですが、

  1. 正確な地図故に、変換結果を図示すると変換異常を表し易い
  2. ちずぶらり運営側自身がその特性に気付かずに、正確な地図にまで適用を拡げつつあるので、技術としての限界を明示しておくべき

と思い、このデータを選びました。

データは全て、iTunesで同期したふじぶらりアプリの中から取得したマッピングkmlデータ等を使用しております。
ThinPlateSplineJS側でも、全く同じマッピングポイントを元に変換しております。
ロジックは、ThinPlateSplineJS側はThinPlateSplineJS+こちらで使っているemscripten版Proj.4のタッグ、ちずぶらり側は、ちずぶらりトップページの日本地図をハンドリングしている、JavaScript版ちずぶらりのロジックを用いました。
実証内容はライセンス的に公開するのは難しいので、希望者がありましたら、jsFiddle上で実証してますのでアカウント作成の上申し出ていただければお見せしますが、不特定多数には結果のみの公表とします。

変換精度

このデータで示されている地図範囲全域に対して、経度、緯度とも0.01度刻みでグリッドを設定し、その格子を絵地図上のピクセル座標に変換した結果を下記の図に示します。
赤がちずぶらりによる変換、青がThinPlateSplineJSによる変換です。
先述の通り、どちらも同じマッピングポイント(ちずぶらり用に作られたもの、全57点指定)を元に変換しています。

ご覧の通り、ThinPlateSplineJSの方がほぼ全域で格子を設定できているのに対し、ちずぶらりでは近隣にマッピングポイントを設定できない海上等で、致命的に格子が破壊されています。
陸上域でも隅の方等になると、変換に使えるマッピングポイントが少ないせいか、かなり歪な格子になっています。

この理由は、ちずぶらりが変換したい点の近傍のマッピングポイントを都度計算して、それを元に変換計算をしているためです。
なので、変換点は非連続に突然入れ替わります*1し、近傍にマッピングポイントが存在しなければ、遠くのマッピングポイントを元に計算する事になるため、突然誤差が大きくなります。
原理上、射影でいうところの、全射でもなければ単射でもありません。

ですので、格子を維持しようと思うと、ちずぶらりではどうしても地図面全体にまんべんのないマッピングポイントが必要になるのです。
例えば、マッピングポイントを57点から6点に絞ってみましょう。

ThinPlateSplineJSだと、まだちょっと納得はいかないレベルではあるものの、ある程度は格子の変換が収束してきています。
一方、ちずぶらりではグダグダです。

ちなみに、こういう正確な地図では、本来は投影系を特定してTMSというデータ形式の地図にするのが常道です。
それならば、マッピングポイントの指定も原理上は3〜4点指定するだけで、全域で寸分の狂いもないレベルの地図を作成できます。
何より、TMSだと、ちずぶらりみたいな特殊な環境でしか使えないデータではなく、ごくごく一般なGoogle Maps API等の地図の上にそのまま貼付けられる地図になります。
ですのでThinPlateSplineJSも、単独で全て解決、というスタンスで臨むのではなく、同じ画像とマッピングデータを使ってTMSとThinPlateSplineJS双方のデータを生成できるソリューションにしたいと思っております。

変換速度

上記のデータによる変換速度について調べてみました。
結果は以下の通り。

Average of 5 times test.

Transform count: 234
Stroly:
Total time: 85.2 μs
Time per transform: 0.36410256410256414 μs
ThinPlateSplineJS:
Total time: 69.2 μs
Analyzing time: 41.2 μs
Transforming time: 28.0 μs
Time per transform: 0.11965811965811966 μs

234回の変換にかかるトータルの時間は、ちずぶらり85.2μ秒、ThinPlateSplineJSは69.2μ秒でした。
これだけですとThinPlateSplineJSの方が少し速いだけですが、ThinPlateSplineJSはトータル時間中に、個々の変換処理に加えて最初に一回だけ変換テーブル作成処理が存在します。
これを除いた純粋な変換時間は28.0 μ秒で、ちずぶらりの3倍近い速度があるので、変換回数を増やせば増やすほど、最初のテーブル作成時間が隠蔽されて、ThinPlateSplineJSの優位性が上がります。

ThinPlateSplineJSの変換テーブル作成時間ですが、今回はこれを入れても速かったものの、あまり楽観視もできず、マッピングポイントが1000を越えるようなものだと今までで最高、変換テーブル作成に40秒費やす地図データに出会った事があります。
しかしその時間を、ThinPlateSplineJSは展開済み変換テーブルを直接やり取りできるインタフェースを設ける事で短縮しています。
変換テーブルは作るのには時間かかりますが、一度作ってしまうと変換はすばやく行う事が可能なので、サーバサイドでnode.JS等であらかじめマッピングポイントから変換テーブルを作っておき、それをダウンロードする形で直接解析するよりは高速に変換テーブルを展開する事が可能です。
ThinPlateSplineJSが解析に40秒もかかるようなデータでは、ちずぶらり側も、毎回変換の度に全マッピングポイントとの距離計算行ってる分、相当変換速度が遅くなるはずですので、それを考えると大きなデータでも十分な優位性はあるものと考えております。

ポジショントーク

ちずぶらりの中にいた頃、私は絵地図を扱うベストの技術としてちずぶらりを宣伝してきましたし、また歪んだ地図ではないある程度正確な地図においても、災害時に高速に配信する基盤としてちずぶらりを活用してはどうか、といった提言をしてきました。
が、現プロデューサに騙し討ちで解雇されて外に追い出された途端、ちずぶらりはダメだ、欠陥のある技術だ、等と言い出すのはポジショントークだと思われるかもしれません。
しかし、技術は普通進歩するものであって、中にいた頃はその進歩も見越して、ちずぶらりを宣伝していたのであって、正確な地図が扱いづらい、正単射変換ではない、といった問題も、TMSと連携させたりといった形でいずれ解決する目論みがあったからこそ、宣伝していたのです。
が、私が開発から外れ、TMS等のGISとの連携は現プロデューサにより明確に否定され、事実として2年間技術としての発展が止まり、問題は問題のまま永久に解決されなくなった今、ちずぶらりを薦めるべき理由は何一つありません。
ちずぶらり的なソリューションが必要なのであれば、ちずぶらりの持つ問題を解決し、また今ある問題も継続して解決していく意思のある、ThinPlateSplineJSの方を使うべきでしょう。

もちろん、ThinPlateSplineJSには、ちずぶらりにはある機能のうち、

  1. 現在地座標だけではなく、縮尺や方角も合わせて変換する処理
  2. 同じ画像中に複数の地図がある場合の、前後の重ね合わせも考慮した選択処理

等はまだ定義できていません。
が、ちずぶらり側でもそれらの機能を発想、定義し実装したのは私であって、同じ機能はThinPlateSplineJS側でもできますし、後はどれだけの労力がかけられるか、ひいてはどれだけの支援が得られるかの問題です。
同じ事が実現でき、その先の発展も見込めるのに対し、ちずぶらり側は完全に進化が止まっています。

2年前までは、絵地図や古地図を歪ませずに扱う技術はちずぶらりしかなく、故にそれを薦めるしかありませんでした。
が、今はThinPlateSplineJSが発展しようとしています。
絵地図や古地図を扱う技術が残念ながらニーズがないのであれば、ThinPlateSplineJSもちずぶらりも共に沈んでいけばいいし、ニーズがあるのであれば、2年前ならばともかく今や、ちずぶらりにコミットする意味は、今日明日すぐにアプリを出したいとかというレベルでなければ全くありません。

技術の愛称募集中

記事書いてきてて思いましたが、今他に適切な呼び名がないので技術全体をさす言葉としてThinPlateSplineJSに代行させましたが、ThinPlateSplineJSというのは飽くまでライブラリの名前であって、別にJavaScriptでしか使えない技術にするつもりはないし、Xamarin使ってiOSアプリもAndroidアプリも作るつもりでおります。
が、やっぱりJavaScriptだけ?的な誤解を与えないためにも、「ちずぶらり」的な技術セット全体の愛称があった方がいいなと思いました。
というわけで、それを募集いたします。

とりあえず既に候補はいくつかあるのですが、どれもしっくりこないので、この候補でいいんじゃないの、から、新しい愛称案含め募集します。
現状の案:

  1. 歴史国土

国土地理院旧版地形図をみんなでTMS化マッピングするサービスのサービス名として考えたもの。現在絶賛開発停止中。古地図を扱う技術セット全体の命名と考えれば、ちずぶらり対抗技術も含むと考えられなくもない。

  1. OpenTileMap

世に存在するTMSサービスのURLをみんなで共有しましょう、というサービスのサービス名として、id:tmizu23 が考えたもの。Web版は現在絶賛開発停止中だが、アプリ版を細々と開発中。非TMS地図であっても、ちずぶらり等も基本タイル地図なので、タイル画像化した地図を扱う技術セット全体の命名と考えれば、ちずぶらり対抗技術も含むと考えられなくもない。

  1. ぷらっとまっぷ

「ちずぶらり」っぽい命名をしようと考えて絶賛自爆したもの。

候補が選ばれる事になっても、新愛称になっても、とりあえず一番貢献してくれたと思った意見に対し、少ないですが1万円の商品券(まだ買ってないので何がいいかはご指定いただけます)をお送りしたいと思います。
連絡方法は、FacebookTwitter等は利用を一時停止しておりますので、はてブ、その他のはてなサービスによるidコール、Qiita、kochizufanアカウントのメールアドレス等宛にお願いします。

== 追記 ==

締め切り書くの忘れてた。
急いでるわけでもないので別に何時でもいいんだけどとりあえず 2/15 (土)くらいで。

*1:私が開発していたiOS版のちずぶらりでは、こうしたちずぶらりの欠点のうち、非連続な変換が発生する問題等は解決するためのロジックを入れていました。が、minifyされているコードで解析が難しいですがおそらく、JavaScript版には反映されていないようです

© Code for History