任一存 1 tahun lalu
induk
melakukan
3278fa3d8f
2 mengubah file dengan 218 tambahan dan 39 penghapusan
  1. TEMPAT SAMPAH
      src/assets/images/tower.png
  2. 218 39
      src/views/HomeView.vue

TEMPAT SAMPAH
src/assets/images/tower.png


+ 218 - 39
src/views/HomeView.vue

@@ -5,37 +5,75 @@
     <div id="map" />
 
     <div class="panel">
-      <el-select
-        v-model="timeInDay"
-        placeholder="Select"
-        size="large"
-      >
-        <el-option
-          v-for="item in timeOptions"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value"
-        />
-      </el-select>
+      <div class="time-selection">
+        <h3>select time: </h3>
+        <el-select
+          v-model="timeInDay"
+          placeholder="Select"
+          size="large"
+          :disabled="!isMapLoaded"
+        >
+          <el-option
+            v-for="item in timeOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </div>
       <el-checkbox
         v-model="isShowLabels"
         label="show labels"
         size="large"
+        :disabled="!isMapLoaded"
       />
       <el-checkbox
         v-model="isShowTerrain"
         label="show terrain"
         size="large"
+        :disabled="!isMapLoaded"
+      />
+      <el-checkbox
+        v-model="isShowContours"
+        label="show contours"
+        size="large"
+        :disabled="!isMapLoaded"
+      />
+      <el-checkbox
+        v-model="isShowBridges"
+        label="highlight recommended bridges"
+        size="large"
+        :disabled="!isMapLoaded"
+      />
+      <el-checkbox
+        v-model="isShowPlayground"
+        label="highlight recommended playground"
+        size="large"
+        :disabled="!isMapLoaded"
+      />
+      <el-checkbox
+        v-model="isShowRoads"
+        label="highlight Roads"
+        size="large"
+        :disabled="!isMapLoaded"
+      />
+      <el-checkbox
+        v-model="checkSandlotUssage"
+        label="(click to) check sandlot ussage"
+        size="large"
+        :disabled="!isMapLoaded"
       />
       <el-checkbox
         v-model="isShowFog"
         label="show fog"
         size="large"
+        :disabled="!isMapLoaded"
       />
       <el-checkbox
         v-model="isAutoRotate"
         label="auto rotate"
         size="large"
+        :disabled="!isMapLoaded"
       />
     </div>
   </div>
@@ -54,13 +92,14 @@ const store = useStore()
 mapboxgl.accessToken = 'pk.eyJ1IjoiamlidmFnIiwiYSI6ImNsdDVibmxvZDAwbjcyanAzNmpzOHpoeHUifQ.KKYv3iK0IiL37rNDYkb-dQ'
 
 let map = null
-
+const isMapLoaded = ref(false)
 onMounted(() => {
   map = new mapboxgl.Map({
     container: 'map', // container ID
     center: [2.294444, 48.858056], // starting position [lng, lat]
     zoom: 15.6, // starting zoom
     pitch: 72,
+    antialias: true,
   })
   map.on('style.load', () => {
     // 隐藏标签。
@@ -68,7 +107,9 @@ onMounted(() => {
     map.setConfigProperty('basemap', 'showRoadLabels', false)
     map.setConfigProperty('basemap', 'showPointOfInterestLabels', false)
     map.setConfigProperty('basemap', 'showTransitLabels', false)
+  })
 
+  map.on('load', () => {
     // 准备 3D terrain source
     map.addSource('mapbox-dem', {
       'type': 'raster-dem',
@@ -76,14 +117,28 @@ onMounted(() => {
       'tileSize': 512,
       'maxzoom': 14
     })
-  })
 
-  map.on('click', (e) => {
-    console.log(e.lngLat.wrap())
-  })
+    // 等高线
+    map.addSource('contours', {
+      type: 'vector',
+      url: 'mapbox://mapbox.mapbox-terrain-v2'
+    })
+    map.addLayer({
+      'id': 'contours',
+      'type': 'line',
+      'source': 'contours',
+      'source-layer': 'contour',
+      'layout': {
+        'visibility': 'none',
+        'line-join': 'round',
+        'line-cap': 'round'
+      },
+      'paint': {
+        'line-color': '#877b59',
+        'line-width': 1
+      }
+    })
 
-  map.on('load', () => {
-    // todo: 操控
     // 桥梁高亮
     map.addSource('bridge-demo-1', {
       'type': 'geojson',
@@ -151,7 +206,8 @@ onMounted(() => {
       'source': 'bridge-demo-1',
       'layout': {
         'line-join': 'round',
-        'line-cap': 'round'
+        'line-cap': 'round',
+        'visibility': 'none',
       },
       'paint': {
         'line-color': 'rgba(244, 208, 133, 0.8)',
@@ -164,7 +220,8 @@ onMounted(() => {
       'source': 'bridge-demo-2',
       'layout': {
         'line-join': 'round',
-        'line-cap': 'round'
+        'line-cap': 'round',
+        'visibility': 'none',
       },
       'paint': {
         'line-color': 'rgba(244, 208, 133, 0.8)',
@@ -177,7 +234,8 @@ onMounted(() => {
       'source': 'bridge-demo-3',
       'layout': {
         'line-join': 'round',
-        'line-cap': 'round'
+        'line-cap': 'round',
+        'visibility': 'none',
       },
       'paint': {
         'line-color': 'rgba(244, 208, 133, 0.8)',
@@ -185,7 +243,6 @@ onMounted(() => {
       }
     })
 
-    // todo:操控
     // 操场高亮
     // Add a data source containing GeoJSON data.
     map.addSource('playground', {
@@ -214,12 +271,77 @@ onMounted(() => {
       'id': 'playground',
       'type': 'fill',
       'source': 'playground', // reference the data source
-      'layout': {},
+      'layout': {
+        'visibility': 'none',
+      },
       'paint': {
         'fill-color': '#0080ff', // blue color fill
         'fill-opacity': 0.5
       }
     })
+
+    // 道路、landuse(透明)
+    map.addSource('streets', {
+      type: 'vector',
+      url: 'mapbox://mapbox.mapbox-streets-v8'
+    })
+    map.addLayer({
+      'id': 'roads',
+      'type': 'fill',
+      'slot': 'middle',
+      'source': 'streets',
+      'source-layer': 'road',
+      'layout': {
+        'visibility': 'none',
+      },
+      'paint': {
+        'fill-color': '#639FE0',
+        'fill-opacity': 0.4
+      }
+    })
+    map.addLayer({
+      'id': 'landuse',
+      'type': 'fill',
+      // 'slot': 'top',
+      'source': 'streets',
+      'source-layer': 'landuse',
+      'layout': {
+      },
+      'paint': {
+        'fill-color': '#639FE0',
+        'fill-opacity': 0
+      }
+    })
+
+    // create the popup
+    const el = document.createElement('div')
+    el.id = 'marker'
+    const popup = new mapboxgl.Popup({ offset: 25 }).setText(
+      'The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France. It is named after the engineer Gustave Eiffel, whose company designed and built the tower from 1887 to 1889.'
+    )
+    // create the marker
+    new mapboxgl.Marker(el)
+      .setLngLat([2.294444, 48.858056])
+      .setPopup(popup) // sets a popup on this marker
+      .addTo(map)
+  })
+
+  map.on('idle', () => {
+    isMapLoaded.value = true
+  })
+
+  map.on('click', (e) => {
+    console.log(e.lngLat.wrap())
+    if (checkSandlotUssage.value) {
+      const features = map.queryRenderedFeatures(e.point)
+      if (features?.length && features[features.length - 1].properties.type) {
+        console.log(features)
+        new mapboxgl.Popup()
+          .setLngLat(e.lngLat)
+          .setHTML(`<div style="padding-top: 5px; padding-right: 5px;">${features[features.length - 1].properties.type}</div>`)
+          .addTo(map)
+      }
+    }
   })
 })
 
@@ -300,6 +422,53 @@ watch(isShowTerrain, (v) => {
   }
 })
 
+// 等高线开关
+const isShowContours = ref(false)
+watch(isShowContours, (v) => {
+  if (v) {
+    map.setLayoutProperty('contours', 'visibility', 'visible')
+  } else {
+    map.setLayoutProperty('contours', 'visibility', 'none')
+  }
+})
+
+// 桥梁开关
+const isShowBridges = ref(false)
+watch(isShowBridges, (v) => {
+  if (v) {
+    map.setLayoutProperty('bridge-demo-1', 'visibility', 'visible')
+    map.setLayoutProperty('bridge-demo-2', 'visibility', 'visible')
+    map.setLayoutProperty('bridge-demo-3', 'visibility', 'visible')
+  } else {
+    map.setLayoutProperty('bridge-demo-1', 'visibility', 'none')
+    map.setLayoutProperty('bridge-demo-2', 'visibility', 'none')
+    map.setLayoutProperty('bridge-demo-3', 'visibility', 'none')
+  }
+})
+
+// 运动场开关
+const isShowPlayground = ref(false)
+watch(isShowPlayground, (v) => {
+  if (v) {
+    map.setLayoutProperty('playground', 'visibility', 'visible')
+  } else {
+    map.setLayoutProperty('playground', 'visibility', 'none')
+  }
+})
+
+// 道路开关
+const isShowRoads = ref(false)
+watch(isShowRoads, (v) => {
+  if (v) {
+    map.setLayoutProperty('roads', 'visibility', 'visible')
+  } else {
+    map.setLayoutProperty('roads', 'visibility', 'none')
+  }
+})
+
+// 查看空地用途功能开关
+const checkSandlotUssage = ref(false)
+
 // 雾开关
 const isShowFog = ref(false)
 watch(isShowFog, (v) => {
@@ -366,21 +535,6 @@ watch(isAutoRotate, (v) => {
 
 
 
-
-// 一种style可有多个layer,每个layer有对应的source。
-
-// todo: 日照控件
-
-// todo: 道路显隐控件
-// map.setPaintProperty('route', 'line-opacity', 0.9);
-
-// 添加自定义图层。同一个slot内的各个图层用beforeId参数指定顺序。
-// map.addLayer({ type: 'line', slot: 'middle' /* ... */ });
-
-
-
-// 移除图层
-//
 </script>
 
 <style lang="less" scoped>
@@ -405,6 +559,31 @@ watch(isAutoRotate, (v) => {
     display: flex;
     flex-direction: column;
     background-color: rgba(255, 255, 255, 0.5);
+    >.time-selection {
+      display: flex;
+      align-items: center;
+      >h3 {
+        flex: 0 0 auto;
+        margin-right: 10px;
+      }
+    }
   }
 }
+</style>
+
+<style lang="less">
+.mapboxgl-popup-close-button{
+  transform: scale(1.5);
+  margin: 5px;
+}
+
+#marker {
+    position: relative;
+    background-image: url('@/assets/images/tower.png');
+    background-size: cover;
+    width: 50px;
+    height: 50px;
+    border-radius: 50%;
+    cursor: pointer;
+}
 </style>