お問い合わせ

ブログ

これまでに経験してきたプロジェクトで気になる技術の情報を紹介していきます。

Vue3でMapboxを使用する - マップ編 -

okuda Okuda 2 years

アカウントの作成とモジュールのインストール

アカウントの作成

mapboxのページを開き、右上の「sign up」ボタンをクリック

「Create your Mapbox account」のページが開くので必要事項を記入する

「Team Mapbox」から「Verify your email」のメールが届くので「Verify my email」をクリックする

アカウントにログイン

アクセストークンを取得

Mapboxを使用するには、アクセストークンが必要になる
アカウントページにアクセスし、「Default public token」を取得
新しくトークンを作成することも可能

npm でインストール

mapbox-gl と言語用の mapbox-gl-language 、Geoロケーション用の mapbox-gl-geocoder をインストール

https://docs.mapbox.com/mapbox-gl-js/guides/install/
https://www.npmjs.com/package/mapbox-gl
https://www.npmjs.com/package/@mapbox/mapbox-gl-language
https://www.npmjs.com/package/@mapbox/mapbox-gl-geocoder
https://www.npmjs.com/package/@mapbox/mapbox-gl-directions

npm i mapbox-gl
npm i @mapbox/mapbox-gl-language

# geocoder
npm i @mapbox/mapbox-gl-geocoder

# directions
npm i @mapbox/mapbox-gl-directions
# or
npm i @mapbox/mapbox-gl-directions --legacy-peer-deps

Vueに組み込む

https://docs.mapbox.com/mapbox-gl-js/api/ https://docs.mapbox.com/mapbox-gl-js/api/map/ https://docs.mapbox.com/mapbox-gl-js/example/
https://docs.mapbox.com/help/tutorials/
https://docs.mapbox.com/help/tutorials/custom-markers-gl-js/

mapの表示

必要なモジュールをインポートして onBeforeMount をつかいDOMがレンダリングされたあとにマップを表示

<script setup>
import mapboxgl from "mapbox-gl";
import "mapbox-gl/dist/mapbox-gl.css";
// language
import MapboxLanguage from "@mapbox/mapbox-gl-language";

// geocoder
import MapboxGeocoder from "@mapbox/mapbox-gl-geocoder";
import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";

// directions
import MapboxDirections from '@mapbox/mapbox-gl-directions';
<!-- or -->
import MapboxDirections from '@mapbox/mapbox-gl-directions/dist/mapbox-gl-directions';

import "@mapbox/mapbox-gl-directions/dist/mapbox-gl-directions.css";

import { ref, reactive, onMounted, onBeforeMount } from "vue";

// サポートしてるかチェック
if (!mapboxgl.supported()) {
    alert("Your browser does not support Mapbox GL");
} else {
    console.log("Your browser supported Mapbox GL");
}

// アクセストークン
const accessToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// Map インスタンス
let map = null;
// MapboxLanguage インスタンス
let mapLanguage = null;
// GeolocateControl インスタンス
let locate = null;

// 選択中のユニット
let selectedUnit = ref("imperial");
// 選択中の言語
let selectedLanguage = ref(null);

// マップに設定する情報
// ここを色々いじってみる
const mapInfo = reactive({
    style: "mapbox://styles/mapbox/light-v10",
    lng: 135.4262,
    lat: 34.8215,
    zoom: 14, // 0 - 22
    pitch: 80, // 0 - 85
    bearing: 0, // 0 - 360
    bounds: {
        west: null,
        south: null,
        east: null,
        north: null,
    },
});

// 必ず`onMounted`の中で
onMounted(() => {

    // トークンをセット
    mapboxgl.accessToken = accessToken;

    // マップ
    map = new mapboxgl.Map({
        // マップを表示するエレメントのID
        container: "map",
        // 表示するマップのタイプ
        style: mapInfo.style,
        // マップの中心
        center: [mapInfo.lng, mapInfo.lat], // lng, lat
        // どのぐらいの倍率で表示するか
        zoom: mapInfo.zoom, // default: 0
        // 範囲を指定して表示もできる、この場合`zoom`はいらない
        // bounds: [
        //    [mapInfo.bounds.west, mapInfo.bounds.south], // [west, south]
        //    [mapInfo.bounds.east, mapInfo.bounds.north], // [east, north]
        // ],
        // 傾き 0から85
        pitch: mapInfo.pitch,
        // 方位 北から反時計回りに0から360
        bearing: mapInfo.bearing,
        // アンチエイリアス
        antialias: true,
        // マップボックス情報
        attributionControl: false,
    });
});
</script>

<template>
    <!-- マップをここに表示 -->
    <div id="map" class="map" />
</template>

<style scoped>
/* マップの高さは必ず指定 */
.map {
    height: 100%;
}
</style>

言語を設定する

onMounted のなかに追加
ブラウザの言語を設定する

    // マップの言語を設定する
    mapLanguage = new MapboxLanguage(
        {} // Browser language
        // {defaultLanguage: "en"}
    );
    map.addControl(mapLanguage);

ナビゲーションボタンを追加

onMounted のなかに追加

    // ナビゲーションボタンを追加
    const nav = new mapboxgl.NavigationControl({
        // 傾きのコントロールを表示
        visualizePitch: true,
    });
    // マップの右上に表示
    map.addControl(nav, "top-right");

フルスクリーンボタンを追加

onMounted のなかに追加

    // フルスクリーンボタンを追加
    const full = new mapboxgl.FullscreenControl();
    map.addControl(full);

オリジナルの説明を追加

onMounted のなかに追加

    // add custom attr
    const attr = new mapboxgl.AttributionControl({
        customAttribution: "map design by xxx!",
    });
    map.addControl(attr);

現在地ボタンを追加

onMounted のなかに追加

   // add current place
    locate = new mapboxgl.GeolocateControl({
        positionOptions: {
            enableHighAccuracy: true,
        },
        // 誤差範囲の円を出す
        showAccuracyCircle: true, // default: true
        // 向き
        showUserHeading: true, // default: false
        // マーカーを出す
        showUserLocation: true, // default: true
        // トグルボタン
        trackUserLocation: true, // default: false
    });
    map.addControl(locate);

経路検索を追加

onMounted のなかに追加

    const direction = new MapboxDirections({
        accessToken: mapboxgl.accessToken,
    });
    map.addControl(direction, "top-left");

検索を追加

onMounted のなかに追加

    const geocoder = new MapboxGeocoder({
        accessToken: mapboxgl.accessToken,
        mapboxgl: mapboxgl,
        language: "ja", // How to change language???
        types: "poi",
        reverseGeocode: true,
        limit: 10,
        collapsed: true,
        marker: {
            color: "orange",
        },
    });
    map.addControl(geocoder, "top-left");

スケールを追加

これを使う

// 選択中のユニット
let selectedUnit = ref("imperial");

onMounted のなかに追加

    // add scale and change unit
    scale = new mapboxgl.ScaleControl({
        maxWidth: 80, // default: 100
        unit: selectedUnit.value, // default: "metric" '[imperial, metric, nautical]
    });
    map.addControl(scale);Control(scale);

スケールを変更できるようにする

トップレベルにメソッドを追加、 onMounted のなかに入れるとうごかない

// ユニットチェンジのメソッド
const changeUnit = () => {
    scale.setUnit(selectedUnit.value);
};

template 内にラジオボタンを追加

<!-- ユニットの変更 -->
    <label>
        <input type="radio" v-model="selectedUnit"value="imperial" @change="changeUnit" />
        imperial
    </label>
    <label>
        <input type="radio" v-model="selectedUnit" value="metric" @change="changeUnit" />
        metric
    </label>
    <label>
        <input type="radio" v-model="selectedUnit" value="nautical" @change="changeUnit" />
        nautical
    </label>

言語を変更できるようにする

トップレベルにメソッドを追加追加

https://stackoverflow.com/questions/58605220/how-to-change-language-in-mapbox

// ランゲージチェンジのメソッド
const changeLang = () => {
    map.setStyle(
        mapLanguage.setLanguage(map.getStyle(), selectedLanguage.value)
    );
};

template 内にセレクトボタンを追加

    <select v-model="selectedLanguage" @change="changeLang">
        <option value="ar">Arabic</option>
        <option value="zh-Hans">Chinese Simplified</option>
        <option value="zh-Hant">Chinese Traditional</option>
        <option value="en">English</option>
        <option value="fr">French</option>
        <option value="de">German</option>
        <option value="it">Italian</option>
        <option value="ja">Japanese</option>
        <option value="ko">Korean</option>
        <option value="mul">Multilingual</option>
        <option value="pt">Portuguese</option>
        <option value="ru">Russian</option>
        <option value="es">Spanish</option>
        <option value="vi">Vietnamese</option>
    </select>

マップを変更できるようにする

トップレベルにメソッドを追加追加

// マップスタイルチェンジのメソッド
const changeStyle = () => {
    map.setStyle(mapInfo.style);
};

template 内にセレクトボタンを追加

<select v-model="mapInfo.style" @change="changeStyle">
    <option value="mapbox://styles/mapbox/streets-v11">
        streets-v11 - lang support
    </option>
    <option value="mapbox://styles/mapbox/outdoors-v11">
        outdoors-v11 - lang support
    </option>
    <option value="mapbox://styles/mapbox/dark-v10">
        dark-v10 - lang support
    </option>
    <option value="mapbox://styles/mapbox/light-v10">
        light-v10 - lang support
    </option>
    <option value="mapbox://styles/mapbox/satellite-streets-v9">
        satellite-streets-v9 - lang support
    </option>
    <option value="mapbox://styles/mapbox/satellite-streets-v11">
        satellite-streets-v11
    </option>
    <option value="mapbox://styles/mapbox/navigation-day-v1">
        navigation-day-v1
    </option>
    <option value="mapbox://styles/mapbox/navigation-night-v1">
        navigation-night-v1
    </option>
    <option value="mapbox://styles/mapbox/traffic-day-v2">
        traffic-day-v2 - lang support
    </option>
    <option value="mapbox://styles/mapbox/traffic-night-v2">
        traffic-night-v2 - lang support
    </option>
    <option value="mapbox://styles/mapbox-map-design/ckhqrf2tz0dt119ny6azh975y">
        ckhqrf2tz0dt119ny6azh975y
    </option>
    <option value="mapbox://styles/kohei0728/ckzrv8nzc002i14quk4komtov">
        kohei0728
    </option>
</select>
Vue3でMapboxを使用する - マップ編 - 2022-03-05 18:25:37

コメントはありません。

4584

お気軽に
お問い合わせください。

お問い合わせ
gomibako@aska-ltd.jp