GeoParquetをlonboardで綺麗にサクサク可視化する

## こんな地図を爆速で描画できるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222502/8f5bc46a-0ae8-dabe-187c-1899a05c714e.png)

## こんな辛さを共有する皆さんのための記事です
- 環境省の植生図とか環境省のREPOSの再エネポテンシャルとか、日本全国を対象とした重めのベクターデータをたくさんプレゼントされてしまった・・・
- 描画が毎回遅いせいでコーヒーを飲みすぎてしまった・・・

## キーメッセージ: lonboardを試そう！！！
lonboardはdeck.glから派生したPythonの地理空間情報の可視化ライブラリです。
> A Python library for fast, interactive geospatial vector data visualization in Jupyter.
> Building on cutting-edge technologies like GeoArrow and GeoParquet in conjunction with GPU-based map rendering, lonboard aims to enable visualizing large geospatial datasets interactively through a simple interface.
> https://developmentseed.org/lonboard/latest/

とのことで、
1. jupyter notebook上で分析の途中で気楽に可視化できる
1. kepler.glなどのようにgeojsonを経由しないため、GeoParquetを直接扱えるので超早い (!!)

の2点が特筆すべき利点です。

はじめてlonboardに出会ったのはこのツイートで、2023/10/18にv0.1.0が公開されてから、あっという間に現在v0.5.0になりました。
<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="en" dir="ltr">a lil sneak peak... rendering 3.2 million points from GeoPandas in 1 second 🚀 <a href="https://t.co/u7Det65wb8">pic.twitter.com/u7Det65wb8</a></p>&mdash; Kyle Barron @kylebarron@mapstodon.space (@kylebarron2) <a href="https://twitter.com/kylebarron2/status/1706477652796703049?ref_src=twsrc%5Etfw">September 26, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

ウェブサイトでは、lonboardとipyleaflet・pydeck・kepler.gl-jupyter・datashaderを比較しているので、すでにこれらをお使いの方は、まずはこちら (https://developmentseed.org/lonboard/latest/alternatives/#lonboard-vs-ipyleaflet) をご覧いただくと良いかもしれません。



## 使い方
以下、MacBook Pro / Apple M1 Max / 32 GB / Ventura 13.4.1 / Python==3.9.1での実行例です。

インストールでは以下の1行でした。
```bash
pip install lonboard
```

適当なjupyter notebookを開き、まずはライブラリを読み込みます。
```python
# gis
import geopandas as gpd
# lonboard
from lonboard import viz, Map, SolidPolygonLayer
from lonboard.colormap import apply_continuous_cmap
from lonboard import basemap
# visualization
import palettable
import mapclassify
```

次に早速データを読み込みます。今回は、環境省が公開中の「太陽光発電導入ポテンシャル（500mメッシュ）」を使います (https://www.renewable-energy-potential.env.go.jp/RenewableEnergy/42.html) 。シェープファイル形式で公開されており、日本全国500mメッシュ別の太陽光発電の導入ポテンシャルが格納された200MBほどのデータです。ダウンロードしたzipを解凍して、お好きな方法で.shp --> geoparquetに変換してから使いましょう。

今回は、500mメッシュ内の設備容量のポテンシャルの合計 (MW) が格納された PV_99999_2 列を可視化することにします。あらかじめ、ポテンシャルが0以上のメッシュだけを選択しましょう。

```python
repos_gdf = gpd.read_parquet('path/to/PV_GRID500_R03.parquet').query('PV_99999_2 > 0')
```

では可視化しましょう。
```python
viz(repos_gdf)
```
手元の環境では8秒ほど(!!!)で以下の図が表示されました。QGISやmatplotlib、Rのggplotで可視化した際には数分〜十数分ほどかかっていたので劇的なスピードアップです（ベンチマークはお許しを・・・）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222502/16c1fcde-df7e-43c2-069e-a631721b2ec5.png)

viz()は手っ取り早く可視化することを最優先しているので、特に色付け等はせず、データの空間分布のみを確認することができます。


今回は設備容量のポテンシャルの合計で色分けをしたいため、以下のようにします。ちょっと手間なのは、可視化したい列の数値を0-1にスケーリングしておく必要があるところです。

```python
# SolidPolygonLayerを作成する
layer_repos = SolidPolygonLayer.from_geopandas(repos_gdf)
# repos_gdfの塗り分けをする列を、0-1に変換する。min-max scalingなど色々試すと良さそう。
normalized_fill_values = mapclassify.NaturalBreaks(repos_gdf['PV_99999_2'].values, k=4)
normalized_fill_values = normalized_fill_values.yb / normalized_fill_values.yb.max()
# 0-1に変換されたnormalized_fill_valuesにpalettableのカラーパレットを紐づける
layer_repos.get_fill_color = apply_continuous_cmap(normalized_fill_values, palettable.cartocolors.sequential.Emrld_4_r, alpha=0.9)
# スタイルを調整する
# basemapのスタイルは、carto basemapに対応しています。https://developmentseed.org/lonboard/latest/api/basemap/
map_ = Map(layers=[layer_repos], _height=800, 
           basemap_style = basemap.CartoBasemap.DarkMatterNoLabels)
# 可視化！えいや！
map_
```
環境省のREPOSの太陽光は、建物の屋根や農地でのソーラーシェアリング、ため池への設置を想定しているデータセットのため、人口の分布と似た空間分布になっていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222502/09bd1553-5ba2-bbb5-d61f-39b6a043b9c5.png)

GPUの性能次第ではありますが、ズーム・パン・回転等もスムースです。以下のようにぐりぐり動かしながら確認できるので、データを見ながら議論したいときや、Python側でデータを集計しつつ可視化する際にも大活躍の予感です。（大切なことですが、ぐりぐりと軽快に動かせるのはとても楽しいです！)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222502/8fe3e530-0c84-2f62-c994-12ace618e121.png)

3次元に立ち上げてみたくなりますよね？もちろんできちゃいます。
```python
layer_repos_3d = SolidPolygonLayer.from_geopandas(repos_gdf)
normalized_fill_values = mapclassify.NaturalBreaks(repos_gdf['PV_99999_2'].values, k=100)
normalized_fill_values = normalized_fill_values.yb / normalized_fill_values.yb.max() 
layer_repos_3d.get_fill_color = apply_continuous_cmap(normalized_fill_values, palettable.cartocolors.sequential.Emrld_7_r, alpha=0.9)
# 3次元方向の高さの設定。自分が慣れていないだけで、多分もっといいやり方があるかも。
layer_repos_3d.get_elevation = normalized_fill_values * 2*10**4
layer_repos_3d.extruded = True # これをTrueにしないと3次元にならない
map_3d_ = Map(layers=[layer_repos_3d], _height=800, 
           basemap_style = basemap.CartoBasemap.DarkMatterNoLabels)
map_3d_
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222502/8f5bc46a-0ae8-dabe-187c-1899a05c714e.png)

## ちょっと気をつけたいところ
lonboardのWebサイトのalternativesページでは、以下のような説明が書かれています。
https://developmentseed.org/lonboard/latest/alternatives/

> Datashader is a truly scalable rendering library. Datashader will re-render your data from scratch when panning around in a map. This allows datashader to aggregate the source data before rendering. Datashader minimizes the amount of data being rendered and thus, in theory, Datashader should perform well for datasets as large as your computer's memory.

> Lonboard is not scalable in the same sense. It doesn't minimize the amount of data being rendered. If you ask to plot a GeoDataFrame with 3 million points, every single one of those points is transferred to the GPU and drawn to your screen. In contrast to Datashader, Lonboard should perform well for datasets whose geometries fit in your computer's GPU memory, which is usually much smaller than your computer's total memory.

lonboardは全部GPU上に載せるため、あまりに巨大・複雑な形状のデータでは特に注意が必要です。手元のデータセット・マシンでは幸いなことにクラッシュしたりはしませんでしたが、場合によってはデータをフィルタリングしてから可視化したり、潔くDatashaderに頼ったほうが良いこともあるかもしれません。

## その他注目点
今対応しているレイヤーは、
1. Heatmap https://developmentseed.org/lonboard/latest/api/layers/heatmap-layer/
1. PathLayer https://developmentseed.org/lonboard/latest/api/layers/path-layer/
1. ScatterplotLayer https://developmentseed.org/lonboard/latest/api/layers/scatterplot-layer/
1. SolidPolygonLayer https://developmentseed.org/lonboard/latest/api/layers/solid-polygon-layer/

の4種類で、まだpydeckと比較すると機能は限定的です。しかし、ExperimentalでArc layerやText layerが実装されるなど、頻繁に機能が追加されているため、今後もできることが増えそうです。

今年10月に突如現れたパワフルなlonboard、皆さんも使ってみませんか？
Enjoy!