はじめに
Vue.jsとMapbox GL JSを使って、このような機能を実装していきます。
- 地名検索
- 国名・地名の日本語化
- 位置情報表示
VueMapbox といったラッパーライブラリもありますが、
Mapbox GL JSの機能を知る編ということで、使わずに進めていきたいと思います。
結果として、Vue.jsの機能は全く使っていませんが・・・
次のステップとして、プラグイン化などしていけたらと思います
mapboxとは
mapboxは、地図を使用したアプリ開発者向けのプラットフォームです。 そのなかでMapbox GL JSは、Web GLを使用して地図を表示するJavaScriptライブラリです。 その他の地図サービス・APIに比べて、カスタマイズ性が高いとされています。環境構築
Vue.jsのプロジェクト作成とMapbox GL JSのインストールを行います。
Vue CLIでプロジェクト作成
vue create mapbox-vue
今回はMapbox GL JSの機能を試したいので、
Vue RouterもVuexもなしのシンプルなプロジェクトにしています。
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save, Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
Vue CLI Installation
Vue CLI Creating a Project
Mapbox GL JSのインストール
-
npmでMapbox GL JSをインストール
npm install mapbox-gl @types/mapbox-gl --save
※TypeScriptを使用しているため、typesもインストールしています。
-
/public/index.html
へ以下を追加し、CSSを読み込む/public/index.html(抜粋)<link href="https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.css" rel="stylesheet" />
mapboxアカウント作成
Access Tokenを取得するため、
Create your Mapbox accountからアカウントを作成します。
SignUpするとAccountページにAccess Tokenが表示されます。
料金体系は、Webの場合50,000回までのマップ読み込みは無料となっています。
詳細は、Mapbox pricingへ。
マップを表示する
まずは、マップを表示してみましょう。
/src/components/MyMap.vue
を追加します。
これからこのファイルを編集して機能を追加していきます。
Your Access Token
の箇所は、先ほど取得したAccess Tokenに変更してください。
<template>
<div id="app">
<my-map />
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import MyMap from './components/MyMap.vue'
@Component({
components: {
'my-map': MyMap
}
})
export default class App extends Vue {}
</script>
<style>
body {
padding: 0;
margin: 0;
}
#app {
height: 100vh;
}
</style>
<template>
<div id="map"></div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import mapboxgl, { MapboxOptions, Map } from 'mapbox-gl'
@Component({})
export default class extends Vue {
map: Map = {} as Map
option: MapboxOptions = {
accessToken: 'Your Access Token',
container: 'map',
style: 'mapbox://styles/mapbox/streets-v8',
center: [143.767125, 38.681236],
zoom: 4
}
mounted() {
this.map = new mapboxgl.Map(this.option)
}
}
</script>
<style scoped>
#map {
width: 100%;
height: 100%;
}
</style>
仕組み
-
mapbox-gl
を読み込む/src/components/MyMap.vueimport mapboxgl, { MapboxOptions, Map } from 'mapbox-gl'
-
mapboxのオプションを設定する
/src/components/MyMap.vue(抜粋)option: MapboxOptions = { accessToken: 'Your Access Token', container: 'map', style: 'mapbox://styles/mapbox/streets-v8', center: [143.767125, 38.681236], zoom: 4 }
設定できるオプションの詳細は、Mapbox GL JS API reference Map へ。
accessToken
、container
は必須になります。
container
には、マップをバインドするタグのid
を指定します。
-
マップをバインドするタグを作成し、高さを指定する
/src/App.vue(抜粋)<style> body { padding: 0; margin: 0; } #app { height: 100vh; } </style>
/src/components/MyMap.vue(抜粋)<template> <div id="map"></div> </template> <style scoped> #map { width: 100%; height: 100%; } </style>
-
Mapオブジェクトを生成する
/src/components/MyMap.vue(抜粋)mounted() { this.map = new mapboxgl.Map(this.option) }
DOM作成後である必要があるので、mounted
フックでMap
オブジェクトを生成します。
このMap
オブジェクトに、マップを操作するファンクションやイベントが定義されています。
検索機能を追加する
次に、検索機能を追加してみましょう。
検索機能は、mapbox-gl-geocoder
プラグインから提供されています。
-
npmで
mapbox-gl-geocoder
をインストールnpm install @mapbox/mapbox-gl-geocoder --save
-
/public/index.html
へ以下を追加し、CSSを読み込む/public/index.html(抜粋)<link href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.4.2/mapbox-gl-geocoder.css" rel="stylesheet" />
-
Map
オブジェクトにコントロールを追加/src/components/MyMap.vue(抜粋)<script lang="ts"> // 省略 const MapboxGeocoder = require('@mapbox/mapbox-gl-geocoder') @Component({}) export default class extends Vue { // 省略 mounted() { this.map = new mapboxgl.Map(this.option) this.map.addControl( new MapboxGeocoder({ accessToken: this.option.accessToken, mapboxgl: mapboxgl }) ) } } </script>
仕組み
検索時には、Geocoding API が呼ばれています。
GET https://api.mapbox.com/geocoding/v5/{endpoint}/{search_text}.json
Mapbox GL JSから、このような Control
などのUIも提供されていますし、APIとしても提供されていますので、UIを自作することもできます。
その他のAPIの詳細は、mapbox API Documentation へ。
地名を日本語化する
英語のままでは見づらいので、日本語化してみましょう。
日本語化は、mapbox-gl-language
プラグインから提供されています。
-
npmで
mapbox-gl-language
をインストールnpm install @mapbox/mapbox-gl-language --save
-
Map
オブジェクトにコントロールを追加/src/components/MyMap.vue(抜粋)<script lang="ts"> // 省略 const MapboxLanguage = require('@mapbox/mapbox-gl-language') @Component({}) export default class extends Vue { // 省略 mounted() { this.map = new mapboxgl.Map(this.option) // 省略 this.map.addControl( new MapboxLanguage({ defaultLanguage: 'ja' }) ) } } </script>
マップのスタイルを作成する
Mapbox Studioでは、Web上で好きなスタイルを作成することができます。
Mapbox Studio での編集
ここで様々な編集ができます。
詳しい使い方は、Mapbox Studio Manual へ。
今回は、日本語のSatellite Streetsを作成しました。
作成したスタイルの適用
-
option
のstyle
を変更/src/components/MyMap.vue(抜粋)<script lang="ts"> // 省略 @Component({}) export default class extends Vue { // 省略 option: MapboxOptions = { accessToken: 'Your Access Token', container: 'map', style: 'Copied Style URL', center: [143.767125, 38.681236], zoom: 4 } // 省略 } </script>
位置情報を表示する
最後に、位置情報を表示してみましょう。
今回は私の好きな美術館を表示してみたいと思います。
-
レイヤーを追加
/src/components/MyMap.vue(抜粋)<script lang="ts"> // 省略 @Component({}) export default class extends Vue { // 省略 mounted() { // 省略 this.map.on('load', () => { this.map.addLayer({ id: 'points', type: 'symbol', source: { type: 'geojson', data: { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [139.775792, 35.715622] }, properties: { title: '国立西洋美術館', icon: 'museum' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [139.630669, 35.457194] }, properties: { title: '横浜美術館', icon: 'museum' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [139.051066, 35.2454] }, properties: { title: '彫刻の森美術館', icon: 'museum' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [139.021225, 35.256709] }, properties: { title: 'ポーラ美術館', icon: 'museum' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [139.726423, 35.665322] }, properties: { title: '国立新美術館', icon: 'museum' } } ] } }, layout: { 'icon-image': ['concat', ['get', 'icon'], '-15'], 'text-field': ['get', 'title'], 'text-font': ['ヒラギノ角ゴ Pro W3', 'メイリオ', 'sans-serif'], 'text-offset': [0, 0.6], 'text-anchor': 'top' } }) }) } } </script>
仕組み
様々なレイヤーを組み合わせることでマップを表示しています。
Layerには主に type
、sorce
、 layout
、 paint
が設定できます。
詳しい仕様は、mapbox Style Specification Layers へ。
今回は 座標
を アイコン表示
するので、
type
は symbol
、source
は geojson
にしています。
GeoJSON とは
地理空間を表現するためのJSONフォーマットです。
詳しい仕様は、GeoJSON へ。
おわりに
ここまでMapbox GL JSの主要な機能を見てきました。
mapboxのSolutionsには、様々なユースケースが紹介されていますので、こちらもぜひ!
業務ではラッパーライブラリを使用していますが、もう少し自由度がほしいと思うこともしばしば・・・。
次は、ここからVue.jsのアプリとしてもっと使いやすくしていきたいと思います