これは FOSS4G Advent Calendar 2016 の記事です。
はじめに
CS立体図という地形図があります。地形がわかりやすくていいですね。
だれでも手軽に使えるように 国土地理院の標高タイル を使って直接ブラウザ上でCS立体図を生成してみました。
長野県型立体地形図(CS立体図) より引用
できあがり
こんなかんじで動作するものができあがりました。スマホのブラウザでも動きます。
解説
標高タイルの画像化
標高タイルを XMLHttpRequest で持ってきてパース、canvas に描画する手法です。先人がやってらっしゃいますね。地理院地図の標高タイル(CSV)を描画してみた など。
昔は context.fillRect
などを使って一ピクセルずつ矩形を描いて塗りつぶすしかなく、動作が重くて実用にならなかったと記憶しているのですが、最近(?)のブラウザでは context.createImageData
で作ったrgba配列を直接操作して、context.putImageData
で描画することができるようになったみたいですね。これを使うと結構軽快に画面が更新されます。
CS立体図
CS立体図自体は Curvature (曲率) と Slope (傾斜) を合成することで作成できます。計算式自体は以下を参考にしてなんとかなりました。詳しくはソースを参照してください、ちょこちょこ手を入れていくと思うので。
- 参考: 傾斜角 (Slope) の仕組み
- 参考: 曲率 (Curvature) の仕組み
ただ、スマホで動かす場合には計算量を少なくしないといけません。曲率は足し算・掛け算しか出てこないのであんまりやることはないのですが、傾斜角は atan
や sqrt
が出てくるので比較的負荷が高いです。上のソースでは事前に tan
の二乗を計算したものを用意しておいて、傾斜角の計算時には足し算・掛け算だけで済むように工夫しています。
Leaflet GridLayer
実装は Leaflet GridLayer を拡張して作っています。例題の CanvasLayer そのもの、といった感もありますが、オーバーズーミングに対応させたところが工夫です。実際の DEM は z=14 で打ち止めですが、z=15 でも z=16 でも z=14 の DEM を持ってきてCS立体図を合成してくれます。
Leaflet Control Swipe
画面下部の三角形を左右にスワイプすることで左右の地図の領域をコントロールできるようにしています。拙作のプラグインを使っています。
まとめ
G空間情報センターの 静岡県CS立体図 を教えてもらったとき、これって地理院標高タイルで作れそうだなー、と思ったのがきっかけでした。さっと実装して PC で動いたので満足していたのですが、トレイルランナーの友人に見せたところ「これ、山でも使いたい」ということだったのでスマホで動くようにチューンしてみました。もともと CS 立体図は林業なんかの業務向けを想定しているとは思うのですが、山で迷子にならないために使いたい、という需要もあるみたいです。思わぬ収穫でした。
標高タイル、こんな風に用途が広がるので、自治体が高精度の標高タイルをオープンデータとして出す、みたいな展開になるといいなーと思います。
追記 (2016/12/23)
国土地理院より 標高タイル(地球地図全球版標高第2版) がリリースされ、ズームレベル0〜8のレンジで全世界の標高タイルが入手できるようになりました。デモアプリもズームレベルに応じてDEMソースを切り替えるように 変更 したので、ズームレベル8以下であれば全世界のCS立体図をご覧いただけます。
https://frogcat.github.io/csmap/#5/16.762/469.402
追記 (2017/02/05)
2017-01-31「つくばFOSS4Gもくもく会・CS立体図勉強会」が開催されました。当日の模様が hackpad にまとめられています。CS立体図を実装してみたい開発者の方は必読です。