MapboxでaddSource is not a functionと表示される

実現したいこと

Mapboxでポリゴンを作成したら、v-ifでボタンを表示・非表示させたい。
エラーが一定の条件下のようなのでエラーを解消したい

発生している問題・分からないこと

MapboxでMapbox-gl-drawをimportして利用してます。
このdrawを利用して、クリックしてポリゴンを作成できるようにしています。

その際にMapboxにあるaddLayerやaddSourceなどMapboxのメソッドで追加するのですが、通常は問題なく利用できます。

ただtemplete内にボタンがあり、表示・非表示などをするために「v-if」などの処理を追加して、ポリゴンを追加しようとすると「そんなメソッドはありません」といったエラーがでます。

ソースコードにテスト用にトグルボタンを追加して試してみました。

エラーメッセージ

error

1mapObj.value.addSource is not a function 2 at checkPolygon (NavigationMap.vue:214:30) 3 at chunk-ESTIRR4N.js?v=09147ab3:10265:60 4 at callWithErrorHandling (chunk-ESTIRR4N.js?v=09147ab3:1650:18) 5 at callWithAsyncErrorHandling (chunk-ESTIRR4N.js?v=09147ab3:1658:17) 6 at callWithAsyncErrorHandling (chunk-ESTIRR4N.js?v=09147ab3:1668:17) 7 at HTMLButtonElement.invoker (chunk-ESTIRR4N.js?v=09147ab3:10247:5) 8checkPolygon @ NavigationMap.vue:214 9(匿名) @ chunk-ESTIRR4N.js?v=09147ab3:10265 10callWithErrorHandling @ chunk-ESTIRR4N.js?v=09147ab3:1650 11callWithAsyncErrorHandling @ chunk-ESTIRR4N.js?v=09147ab3:1658 12callWithAsyncErrorHandling @ chunk-ESTIRR4N.js?v=09147ab3:1668 13invoker @ chunk-ESTIRR4N.js?v=09147ab3:10247 14

該当のソースコード

JavaScript

1<script setup>2import { onMounted, ref} from 'vue';3import mapboxgl from 'mapbox-gl'4import 'mapbox-gl/dist/mapbox-gl.css'5import MapboxDraw from "@mapbox/mapbox-gl-draw";6 7let mapObj = ref(null);8let fillColor = ref('green');9let draw = null;10 11const isShowDeleteBtn = ref(true)12 13onMounted(() => {14 initialMapBox();15});16 17const initialMapBox = () => {18 mapObj.value = new mapboxgl.Map({19 container: 'map_wrapper',20 style: 'mapbox://styles/mapbox/streets-v12',21 center: [139.714590, 35.678184],22 zoom: 9,23 preserveDrawingBuffer: true24 });25 26 mapObj.value.on("load", () => {27 // 拡大・縮小コントロールを作成し、マップに追加する28 const navControl = new mapboxgl.NavigationControl();29 draw = new MapboxDraw({30 displayControlsDefault: false,31 controls: {32 trash: true33 }34 });35 36 mapObj.value.addControl(navControl, 'top-right')37 mapObj.value.addControl(draw);38 39 mapObj.value.on("draw.create", createDrawData);40 41 });42 43 44}45 46const toggleTest = () => {47 isShowDeleteBtn.value = !isShowDeleteBtn.value48}49 50const changeFillColor = (color) => {51 fillColor.value = color;52 draw.changeMode('draw_polygon');53}54 55 56const createDrawData = (e) => {57 if (mapObj.value) {58 const features = e.features;59 features.forEach(function (feature) {60 61 const id = feature.id;62 const geometry = feature.geometry;63 64 feature.properties = {65 type: fillColor.value66 };67 // ポリゴンを追加するレイヤーを地図のスタイルに追加する68 mapObj.value.addLayer({69 id: id,70 type: 'fill',71 source: {72 type: 'geojson',73 data: {74 type: 'Feature',75 geometry: geometry,76 properties: feature.properties // カスタムプロパティをセット77 }78 },79 paint: {80 'fill-color': fillColor.value,81 'fill-opacity': 0.4,82 'line-width': 183 }84 });85 86 });87 }88}89</script>

html

1<template>2<v-row>3 <v-col cols="12">4 <div ref="mapObj" id="map_wrapper"></div>5 <div class="btn_wrapper">6 <v-btn @click="changeFillColor('red')" color="red">赤のポリゴン</v-btn>7 <v-btn @click="changeFillColor('green')" color="green">緑のポリゴン</v-btn>8 </div>9 <div v-if="isShowDeleteBtn">10 <p>これはテスト</p>11 </div>12 <button @click="toggleTest">v-ifテスト</button>13 </v-col>14</v-row>15</template>

試したこと・調べたこと

上記の詳細・結果

template側にv-ifで表示・非表示のトグルボタンを追加して試してみました。
エラーがでる状況は以下のようです。

  • トグルボタンをクリックしないで、ポリゴンを作成すると問題なく作成される。
  • トグルボタンをクリックして1度でもv-ifなどの処理を実行した後にポリゴンを作成するとエラーがでる。

そのため、mapObjをconsole.logで確認しました。
エラーが出ない場合はMapオブジェクトが確認できました。

txt

1boxZoom 2: 3xS {_map: Map, _el: div.mapboxgl-canvas-container.mapboxgl-interactive.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-p…, _container: div#map_wrapper.mapboxgl-map.mode-draw_polygon.mouse-none, _clickTolerance: 3, _enabled: false, …} 4doubleClickZoom 5: 6GS {_clickZoom: qS, _tapZoom: TS} 7dragPan 8: 9$S {_el: div.mapboxgl-canvas-container.mapboxgl-interactive.m

ただトグルボタンでv-ifを実行すると以下のようにhtmlの要素になってました。

html

1<div data-v-cebdade8="" id="map_wrapper" class="mapboxgl-map mode-draw_polygon mouse-add"><div class="mapboxgl-canary" style="visibility: hidden;"></div><div class="mapboxgl-canvas-container mapboxgl-interactive mapboxgl-touch-zoom-rotate mapboxgl-touch-drag-pan"><canvas class="mapboxgl-canvas" tabindex="0" aria-label="Map" role="region" width="1736" height="900" style="width: 868px; height: 450px;"></canvas></div><div class="mapboxgl-control-container"><div class="mapboxgl-ctrl-top-left"></div><div class="mapboxgl-ctrl-top-right"><div class="mapboxgl-ctrl mapboxgl-ctrl-group"><button class="mapboxgl-ctrl-zoom-in" type="button" aria-label="Zoom in" aria-disabled="false"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Zoom in"></span></button><button class="mapboxgl-ctrl-zoom-out" type="button" aria-label="Zoom out" aria-disabled="false"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Zoom out"></span></button><button class="mapboxgl-ctrl-compass" type="button" aria-label="Reset bearing to north"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Reset bearing to north" style="transform: rotate(0deg);"></span></button></div><div class="mapboxgl-ctrl-group mapboxgl-ctrl"><button class="mapbox-gl-draw_ctrl-draw-btn mapbox-gl-draw_trash" title="Delete"></button></div></div><div class="mapboxgl-ctrl-bottom-left"><div class="mapboxgl-ctrl" style="display: block;"><a class="mapboxgl-ctrl-logo" target="_blank" rel="noopener nofollow" href="https://www.mapbox.com/" aria-label="Mapbox logo"></a></div></div><div class="mapboxgl-ctrl-bottom-right"><div class="mapboxgl-ctrl mapboxgl-ctrl-attrib"><button class="mapboxgl-ctrl-attrib-button" type="button"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Toggle attribution"></span></button><div class="mapboxgl-ctrl-attrib-inner"><a href="https://www.mapbox.com/about/maps/" target="_blank" title="Mapbox" aria-label="Mapbox">© Mapbox</a> <a href="https://www.openstreetmap.org/about/" target="_blank" title="OpenStreetMap" aria-label="OpenStreetMap">© OpenStreetMap</a> <a class="mapbox-improve-map" href="https://apps.mapbox.com/feedback/?owner=mapbox&amp;id=streets-v12&amp;access_token=p" target="_blank" aria-label="Improve this map" rel="noopener nofollow">Improve this map</a></div></div></div></div></div>

補足

Vue3 コンポジットAPIで script setupの書き方で処理しています。

コメントを投稿

0 コメント