見出し画像

GoogleMapを呼び出すVue3ライブラリを実装した。

こんにちは。レスキューナウでシステム部の部長をしているadachi-koichiです。 
普段は各プロダクト開発チームの相談に乗ったり、組織づくり・設計の相談相手・技術検証などをしています💬
防災・危機管理関連のWebサービスを提供している弊社ですが、
時々Mapを描画することがあるため、Mapの描画をサクッと実装できるコンポーネントを自作しました。
https://github.com/adachi-koichi/googlemapvue
https://www.npmjs.com/package/@adachi-koichi/googlemapvue
私が触るGoogle Maps JavaScript APIにはたくさんの機能があり、様々な描画ができます。
ただ、機能がたくさんある分、前処理や使い終わった後の処理も色々必要になります。
毎回同じ内容を記述するのは面倒ですし、 記述ミスや使い方を忘れてバグが発生する と時間がもったいないですよね🙃
そんな背景もあり、簡単に呼び出せるライブラリがあったらプロトタイピングが楽だな〜という動機で作成しました。
また、公式ではサポートされてない

  1. GeoTIFF描画

  2. HTML描画

を実装。
GeoTIFF描画機能ではQGISなどで作成したGeoTIFFをコード1行で地図に表示できます。
HTML描画機能は任意のHTMLタグをMap上の任意の座標に埋め込むことができ、aタグを利用すれば画面遷移も実現できます。

使い方

  1. template内にGoogleMapVueのタグを記述

<GoogleMapVue ref="googleMapVueRef"
 :map-options="mapOptions"
 :on-init="onInit"
 :api-key="api_key"
 class="google_map_vue" />

2. Mapの初期化が終わった直後に何か処理をしたい場合はonInitを記述

const onInit = async (googleMapVue: InstanceType<typeof GoogleMapVue>) => { 
        console.log("initialized at onInit")
}

3.Markerなどを描画したい場合はgoogleMapVueに対してaddMarkerなどの描画functionを呼ぶ

googleMapVue.addMarker(markerOptions)

GoogleMapVueを使ってエリアを色塗りした例
googleMapVue.addPolygon({paths: polygonPath})

GoogleMapVueを使って日本全国の鉄道を色塗りした例
googleMapVue.addPolyline(path, {strokeColor: randomColor})


Google Map JS をVue.jsで使うときのハマりポイント

実装した時に混乱した箇所を書いておきます。
ハマりポイントを記憶しておくのは非効率なので(忘れちゃいますし)、今回作成したライブラリはそれらを意識せずに呼び出せるように心がけました。


setMapを複数回行うと、setMap(null)を1回呼んだだけではMVCObjectを継承したオブジェクト(マーカーなど)が地図から消えない。

setMapだけでなく、例えばmarkerOptionsにmapのオブジェクトを入れた場合も1カウントされるので、

const marker = new google.maps.Marker({map})
marker.setMap(map)

などとするだけでもアウト。
このmarkerを解放するにはsetMap(null)を2回呼ぶ必要があります。
知っていて気をつけていれば回避できそうな話ですが、MarkerOptionsとsetMapに呼び出し制限などないので、実装時にハマりました😇
今回作ったライブラリでMarkerオブジェクトの生成を行うようにしたので、今後は気にしないで実装できるようになりました。


import で import Marker = google.maps.Marker などと記述してもJSのロードに失敗する

GoogleMapの定義が読み込まれるのは @googlemaps/js-api-loader のロードが終わってからになるので、上記のようにimport文を書くことができません。今回はライブラリの中に記述したので上記のようなことも気にする必要がなくなりました。


Loaderのload()はonMounted()より前に行うとruntime error

これも定義の読み込みタイミングが原因ですが、Vueの場合onMountedの中で.load()しないと実行時に画面が描画されません。
ライブラリの中にこういった処理を閉じ込めることで、いつでも簡単にGoogleMapを使えるようになりました。


使い終わったオブジェクトの clickListenerを解放するには、google.maps.MapsEventListener を保持しておかなければならない。

何個もオブジェクトを描画する時にマーカーとlistenerの2つを両方保持しておかなければならないのは面倒です。
addしたものはきちんとremoveしておかないと未知のバグに遭遇しかねないですよね。
今回はライブラリの中で両方を保持するように変更したため、特に意識せずにオブジェクトの生成とクリックイベントを付与できるようになりました。


まとめ

同じアプリケーションの中でも地図は何回も出てくるので、その度に公式の手順を探して実装するのは面倒ですよね。
今回はVueのコンポーネントに入れてしまうことで、いつでも簡単にGoogle Mapを様々な画面で組み込めるようになりました🕺


お決まりのやつ

弊社ではWebフロントエンジニアを絶賛募集中です。
防災に関すること、ビジュアライゼーションに関すること、データ分析など、弊社には様々なテーマがあります。
技術について気軽にディスカッションできる雰囲気がある組織なので、興味のある方はお声がけください🙆‍♀️

最後に

現在、レスキューナウでは、災害情報の提供、災害情報を活用した安否確認サービスなどのWebサービスの開発エンジニアを募集しています!
社員・フリーランスに関わらず、参画後に安心してご活躍できることを目指し、応募された方の特性・ご希望にマッチしたチームをご紹介します。
ちょっと話を聞いてみたい、ぜひ応募したい、など、当社にご興味を持っていただけましたら、お気軽にエントリーください!!