この記事は、 North Detail Advent Calendar 2019 の4日目の記事です。
2020/04/02 追記
本記事は、NorthDetail ブログにも投稿しています。
https://www.northdetail.co.jp/blog/441/
弊社は最近地図を扱う業務が増えたので、ここ数ヶ月ほど学習がてらに "Leaflet" を使ってみてます。
もともと "Vue.js" でのサイト構築も多いので、両方を合わせるとどうなるか、というのを試してみたいと思います。
デモサイト: https://sample-leaflet-tacck.netlify.com/
ソースコード: https://github.com/tacck/sample-leaflet
画面でみると
初回は "位置情報提供の許可" が求められるので、 "許可" の方を選択してください。
「現在地」のボタンをクリックすると、ブラウザ経由で取得した位置情報の地点を地図上で表示します。(ここは弊社)
解説
Vue.js や Leaflet.js それぞれの詳しい扱い方は専用のサイトにお任せします。
ここでは、少し工夫したところを。
情報の更新
現在地取得と反映
Mainコンポーネントの中に、 Tabコンポーネント(ボタンのある領域) と Mapコンポーネント(地図のある領域) を持つ形にしています。
Mapコンポーネントは、Mainコンポーネントから与えられた緯度経度を中心に地図を表示する(変更があれば更新する)だけ、という作りです。
緯度経度の変更されるタイミングは、次の二つになります。
- ボタンが押された場合
- ボタンが「現在地」の時にブラウザから与えられた位置情報が
navigator.geolocation.watchPosition()
経由で更新された場合
ボタンが押された場合
Tabコンポーネント の中には TabButtonコンポーネント が二つ並んでいます。
TabButtonコンポーネント は、クリックされたら "クリックされたよ" というイベントを Tabコンポーネントに返すだけです。
どちらのボタンがクリックされたかは、 Tabコンポーネント の責任範囲として、ここからさらに Mainコンポーネント へイベントを投げます。
Mainコンポーネントへは "どちらのボタンが押されたか" がわかるものを引数として渡しています。
Mainコンポーネントは、受け取った値を使って緯度経度を更新し、 Mapコンポーネントへ(props経由で)情報を渡します。
(snip)
<b-button @click="$emit('click')" size="lg" :variant="status">
(snip)
<TabButton
@click="clickStation"
id="sation"
:status="stationVariant"
label="札幌駅"
></TabButton>
(snip)
clickStation() {
this.stationVariant = "info";
this.hereVariant = "";
this.$emit("changeActive", "static");
},
(snip)
<Tab @changeActive="setActive"></Tab>
(snip)
setActive: function(location) {
console.log("active:" + location);
this.lat = this.geosObject[location][0];
this.lon = this.geosObject[location][1];
},
(snip)
地図へ反映
Mapコンポーネントでは、緯度経度の情報が更新されたこと(正確にはpropsで持つ 'lat' の値が更新されたこと)がわかるように、 watch
を使っています。
(snip)
<Map :lat="lat" :lon="lon"></Map>
(snip)
(snip)
methods: {
updateCurrentPosition: async function() {
if (this.map) {
this.map.panTo([this.lat, this.lon]);
}
if (this.currentCircle) {
this.currentCircle.setLatLng([this.lat, this.lon]);
}
if (this.currentPoint) {
this.currentPoint.setLatLng([this.lat, this.lon]);
}
}
},
watch: {
lat: function() {
this.updateCurrentPosition();
}
}
(snip)
まとめ
Vue.js のコンポーネントの一つとして、 Leaflet を使った地図を使うことが簡単にできました。
Mapコンポーネントの外から位置情報を与えられるので、各種サービスと連携して地図表示することも気軽にできそうです。