スムーズに動作する地図を作る
第3章では、巨⼤なデータである地理空間情報をスマートフォンでもスムーズに閲覧できる地図を作るためのテクニックについて紹介します。
全章を一括して購入されたい方はこちらの記事をご購入ください。
https://note.mu/nikkei_staff/n/n44623c9b9ab4
初めまして、⽇経ビジュアルデータでデータビジュアライゼーションや地図コンテンツの実装を担当している@_shimizu です。この章では、巨⼤なデータである地理空間情報をスマートフォンでもスムーズに閲覧できる地図を作るために、⽇経ビジュアルデータで試⾏錯誤したテクニックについて紹介します。
3.1 地図コンテンツの変遷
⽇経ビジュアルデータでは、さまざまなデータを分析し発⾒したニュースを写真や映像などのグラフィックスやインフォグラフィック、データビジュライゼーションを使って配信しています。地理空間情報を⽤いた地図コンテンツを作成することも多々あります。これまでにWeb で扱える地図として配信したコンテンツには次のようなものがあります。
• ⼈⼝減少地図*1
•「介護⼒」マップ*2
• 全国医療費マップ*3
• 1 ⼈当たり所得増減マップ*4
それぞれ市区町村単位の地理空間情報をコロプレス図(塗り分け地図)として視覚化したコンテンツですが、実は全て異なる技術で実装されています。この規模のデータ量になるとブラウザレンダリングの負荷が⾼く、よりスムーズに動作する地図を試⾏錯誤しながら毎回新たな技術を使って開発しているためです。
今回紹介するのは、最近配信された「1 ⼈当たり所得増減マップ」の作成に使っている、現時点でもっともスムーズに動作する地図です。
3.2 Leaflet とは何か
Leaflet*5は、シンプルで使いやすくカスタマイズしやすいオープンソースの地図クライアントライブラリです。Google Maps のように、シムーレスに拡⼤・縮⼩・移動を⾏う機能が簡単に実装できます(図3.1)。
また特定の背景地図に依存することがないためデザインのカスタマイズが容易におこなえるので⽇経ビジュアルデータで地図コンテンツを作る際に⽋かせないライブラリです。
3.3 Leaflet の視覚化機能の仕組み
Leaflet は、L.geoJSONメソッドを使うことで簡単に地図上にGeoJSON データを描画することができます。しかし、地図上にSVG 要素として描画されるため、地理空間情報のサイズに⽐例して追加される要素数も増えてしまいます。また、追加された要素はユーザーの操作によって地図の表⽰領域が変更されるたびに再描画されます。そのため、負荷が⾼く最悪の場合地図そのものが動作しなくなります(図3.2)。
都道府県単位のポリゴンデータなど、⼩規模なデータの視覚化ではとくに地図の動作に問題はありませんでした。しかし、データ量の多い市区町村単位の地図コンテンツを作る際、とくにスマートフォンで地図の動作が重くユーザー体験が損なわれてしまいました。
3.4 canvas を使った視覚化
都道府県であれば、約47 個のポリゴンで描画することができます。しかし、市区町村となると合計数だけを単純に⾒ても1,724 個、ほか細かな島や⾶び地なども含めるとさらに多くのポリゴンが必要となります。SVG 要素での描画には⾃ずと限界があるため、他の⽅法を考える必要がありました。
最初に試したのはSVG 要素ではなくcanvas 要素を使って描画することでした。Leaflet にはcanvas 要素を地図上にオーバーレイするL.canvasメソッドがあり、操作された地図と要素の位置調整をLeaflet のレイヤーが処理してくれます。位置調整を気にすることなくビジュアライゼーションをcanvas 要素に直接描画する処理の実装だけで済みます。
しかし、この⽅法は、実際に試してみたところ期待していたほどの効果がありませんでした。それはcanvas 要素を⽣成するL.canvasメソッドは、地図の描画領域と同じサイズのcanvas 要素を⽣成して地図にオーバーレイすることによります(図3.3)。
SVG 要素のようにデータ量に⽐例して要素数が増えることはなくなりましたが、ユーザーが地図を操作するたびにcanvas の全領域を再描画する必要があります。ブラウザへの負荷は⾼く、特にスマートフォンでは再描画が完了するまでにかなりのタイムラグがあったり、画⾯がちらつくなどの問題がありました。
3.5 地図タイル化して視覚化する
1枚の⼤きなcanvas 要素をオーバレイする⽅法では、再描画のコストが⾼く期待していたほどの軽量化がおこなえませんでした。そこで、データと描画領域を「地図タイル座標」を⽤いて分割し、再描画がおこなわれる範囲を最⼩限に留めることとしました(図3.4)。
256 ピクセル× 256 ピクセルのcanvas をタイル上に並べ、分割した地理空間情報をそれぞれのタイルにレンダリングします。ユーザーが地図を動かした際はまずタイルが移動します。画⾯外へ移動したタイルは破棄され、同時に新しいタイルが⽣成され新たにレンダリングされて追加されます。新たに⽣成されるタイルのみが再描画されるので、レンダリング処理のコストは最⼩限に抑えることができます。
3.5.1 地図タイル座標とは
地図タイル座標は、地理情報をズームレベルという概念を使って区分し、正⽅形のタイルに分割して配信する規格です(図3.5)。
• ズームレベル0では⼀枚のタイルの中に世界地図が収められています。
• ズームレベルが1上がる(ズームする)と、四当分され4枚のタイルに分割されます。
• ズームレベルが2になると、4枚のタイルがそれぞれ四当分されます。
このようにズームレベルに合わせてタイルを分割していくことで、地図が拡⼤されるに伴ってより密度の⾼いデータを低コストで配信することができます。これらのタイルを右上から数えたX 座標(横)とY 座標(縦)とズームレベルを合わせたものが地図タイル座標となります。
3.5.2 地理空間情報を分割する
描画領域であるcanvas 要素を分割するには、それぞれのcanvas が描画すべき地理空間情報を求める必要があります。ここではgeojson-vt*6というライブラリを使って、GeoJSON データを地図タイル座標単位のデータへ分割します(リスト3.1)。
戻り値であるtitleIndexオブジェクトには分割された地理空間情報が含まれ、タイル座標とズームレベルを指定することで該当するGeoJSON データを取得することができます(リスト3.2)。
tileData には、該当するタイル常に地図をレンタリングするためのGeoJSON データが戻り値として保存されます。
3.5.3 canvas 要素をタイル上に敷き詰めて描画する
L.gridLayerを使って地図上にカスタムグリッドを⽣成します。カスタムグリッドレイヤーは、レイヤー直下に⽣成されたDOM 要素をタイルとして管理し位置を調整してグリッド上に習べます。
タイル⽣成時にはcreateTileメソッドが実⾏され、その戻り値(要素)が配置されます。createTileメソッドの引数にはグリッド情報(地図タイル座標)が渡されるのでそれらの情報を元に、該当する地理空間情報を取得しています(リスト3.3)。
3.6 全サンプルコード
市区町村ごとの境界をポリゴンとした市区町村境界データ(GeoJSON)をgeojson-vtで分割し、L.gridLayerを利⽤してcanvas タイルに描画するサンプルコードは次のとおりです(リスト3.4)。
HTML ファイルではLeaflet ライブラリとgeojson-vt ライブラリを読み込みます。
以下、サンプルコードの主要な処理についての簡単な説明となります。
① geojson-vt を使ってGeoJSON を分割する際の設定になります。対応するズームレベルやデバッグモードの有効∕無効などを設定しています。ここでは最低限必要な設定を⾏なっています。各項⽬の詳細はgeojson-vt のヘルプ*7を参照してください。
② createTile は地図の初期表⽰時やユーザー操作によって新たなタイルが⽣成される際に実⾏されるコールバックです。引数には⽣成されるタイルの地図タイル座標などの情報が渡されます。
③ タイルとして配置するcanvas エレメントを⽣成し2D コンテキストを取得します。
④ tileIndex から取得した地物データを元にレンダリングループを回します
⑤ レンダリングするポリゴンの境界や塗りのカラーを設定しています。
⑥ GeoJSON データには、ポイント・ライン・ポリゴンの3種類のタイプがありそれぞれ描画処理を変える必要があります。ここではポイントの描画処理をおこなっています。ポイントはarc メソッドを使って円ポリゴンとして描画します。
⑦ ラインとポリゴンは同じ描画処理でレンダリングします。
⑧ ポリゴンの内部に空⽩がある場合に塗り別けを⾏うために偶奇規則Even ‒ odd rule*8 を有効にします。
⑨ 市区町村境界データを読み込んでいます。
3.7 まとめ
地理空間情報をフロントエンドで地図として実装するさまざまな技術があります。どの技術にも⼀⻑⼀短があり、「この技術さえ使えばどんな地理データでも視覚化できる」とった万能な⽅法はありません。今回紹介したテクニックも現時点での最適解でしかありませんが、この機会に地理情報の視覚化技術に興味をもっていただけたら幸いです。
著者:清⽔正⾏/ @shimizu
毎⽇データビジュアライゼーションを作ってます。仕事の6割は神Excel との戦いです。
140年の歴史ある会社が、AIやデータを駆使した開発を現場で実践しています。是非疑問や感想を #nikkei_dev_book をつけてツイートしてください!
全章を一括して購入されたい方はこちらの記事をご購入ください。
https://note.mu/nikkei_staff/n/n44623c9b9ab4
この記事を購入すると、この下に第3章だけのダウンロードリンクが表示されます。
ここから先は
¥ 100