発電量予測機能のためのヒートマップ実装
発電量予測機能を実装するにあたり、まず必要だったのが「どの建物に、どの程度の日射量があるのか」を可視化する仕組みでした。
ユーザーが地図上で建物をクリックすると、その建物に対応したヒートマップが表示される。
今回実装したのは、そんな機能です。
最終的には Google Maps 上にヒートマップをオーバーレイ表示できるようになったのですが、実装当初はかなり苦戦しました。
最初は「画像を重ねれば終わり」だと思っていた
生成した TIFF 画像を、クリックした建物にオーバーレイする
という内容でした。
当初はかなりシンプルに考えていました。さらにapi自体は実装済みときた
「取得したTIFF画像をreact-google-maps の GroundOverlay に渡せばいいんじゃん」
しかし実際に触ってみると、全くそう簡単ではありませんでした。
TIFF は“普通の画像”ではなかった
調べていくうちに分かったのが、単なる画像ではなく、
- 地理座標情報
- ピクセルごとの物理量データ
- GeoTIFF形式のメタデータ
を含んだ「地理空間データ」だったということです。
?わからん
つまり、PNGやJPEGのようにそのまま表示するものではなく、
- TIFFを解析
- 座標情報を解釈
- 日射量データをヒートマップ化
する必要がありました。
ここはかなり専門性が高く、実際の解析ロジックは ちゃっぴーに書いてもらいました。
ただヒートマップを描画するだけではダメだった
ヒートマップ自体は描画できるようになりましたが、次に問題になったのが「表示領域」です。
建物をクリックしているのに、ヒートマップが周囲まで広く表示されてしまう。
原因は、fluxImg のデータ範囲が広く、建物単位で綺麗に切り出されていなかったことでした。
maskImg を使ったマスク処理
そこで利用したのが maskImg です。
maskImg は建物形状を示すためのデータで、この情報を使えば不要部分をマスクできると考えました。
しかし、ここも単純ではありませんでした。
実際には、
- マスク画像の座標合わせ
- ピクセル単位での判定
- Google Maps 上の位置調整
などが必要で、マスク処理自体がかなり複雑になりました。
さらに maskImg は「建物っぽい形状」を持っているものの、実際には範囲が広く、周辺領域まで含まれていました。
こんな感じ。ぴえん
boundingBox でさらに範囲を絞り込む
そこで追加で利用したのが、boundingBox です。
boundingBox を使って、
- 描画対象エリアを制限
- マスク対象をさらに縮小
- 建物周辺だけにヒートマップを表示
するよう改善しました。
この調整によって、ようやく
「クリックした建物に対してヒートマップが表示される」
という体験に近づけることができました。
やったー
まとめ
今回の実装では、
「画像を地図に重ねるだけ」
だと思っていた処理が、実際には
- GeoTIFF解析
- 地理座標変換
- ヒートマップ生成
- マスク処理
- boundingBox による範囲制御
など、多くの地理空間処理を含む実装だったことが分かりました。
特に、データをそのまま扱うのではなく、
「どう地図上で意味のある形に変換するか」
が最大のポイントだったと思います。
この後の実装では、さらにより正確な建物輪郭ベースの描画へ進化していくことになります。