|
@@ -5,37 +5,75 @@
|
|
<div id="map" />
|
|
<div id="map" />
|
|
|
|
|
|
<div class="panel">
|
|
<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
|
|
<el-checkbox
|
|
v-model="isShowLabels"
|
|
v-model="isShowLabels"
|
|
label="show labels"
|
|
label="show labels"
|
|
size="large"
|
|
size="large"
|
|
|
|
+ :disabled="!isMapLoaded"
|
|
/>
|
|
/>
|
|
<el-checkbox
|
|
<el-checkbox
|
|
v-model="isShowTerrain"
|
|
v-model="isShowTerrain"
|
|
label="show terrain"
|
|
label="show terrain"
|
|
size="large"
|
|
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
|
|
<el-checkbox
|
|
v-model="isShowFog"
|
|
v-model="isShowFog"
|
|
label="show fog"
|
|
label="show fog"
|
|
size="large"
|
|
size="large"
|
|
|
|
+ :disabled="!isMapLoaded"
|
|
/>
|
|
/>
|
|
<el-checkbox
|
|
<el-checkbox
|
|
v-model="isAutoRotate"
|
|
v-model="isAutoRotate"
|
|
label="auto rotate"
|
|
label="auto rotate"
|
|
size="large"
|
|
size="large"
|
|
|
|
+ :disabled="!isMapLoaded"
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -54,13 +92,14 @@ const store = useStore()
|
|
mapboxgl.accessToken = 'pk.eyJ1IjoiamlidmFnIiwiYSI6ImNsdDVibmxvZDAwbjcyanAzNmpzOHpoeHUifQ.KKYv3iK0IiL37rNDYkb-dQ'
|
|
mapboxgl.accessToken = 'pk.eyJ1IjoiamlidmFnIiwiYSI6ImNsdDVibmxvZDAwbjcyanAzNmpzOHpoeHUifQ.KKYv3iK0IiL37rNDYkb-dQ'
|
|
|
|
|
|
let map = null
|
|
let map = null
|
|
-
|
|
|
|
|
|
+const isMapLoaded = ref(false)
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
map = new mapboxgl.Map({
|
|
map = new mapboxgl.Map({
|
|
container: 'map', // container ID
|
|
container: 'map', // container ID
|
|
center: [2.294444, 48.858056], // starting position [lng, lat]
|
|
center: [2.294444, 48.858056], // starting position [lng, lat]
|
|
zoom: 15.6, // starting zoom
|
|
zoom: 15.6, // starting zoom
|
|
pitch: 72,
|
|
pitch: 72,
|
|
|
|
+ antialias: true,
|
|
})
|
|
})
|
|
map.on('style.load', () => {
|
|
map.on('style.load', () => {
|
|
// 隐藏标签。
|
|
// 隐藏标签。
|
|
@@ -68,7 +107,9 @@ onMounted(() => {
|
|
map.setConfigProperty('basemap', 'showRoadLabels', false)
|
|
map.setConfigProperty('basemap', 'showRoadLabels', false)
|
|
map.setConfigProperty('basemap', 'showPointOfInterestLabels', false)
|
|
map.setConfigProperty('basemap', 'showPointOfInterestLabels', false)
|
|
map.setConfigProperty('basemap', 'showTransitLabels', false)
|
|
map.setConfigProperty('basemap', 'showTransitLabels', false)
|
|
|
|
+ })
|
|
|
|
|
|
|
|
+ map.on('load', () => {
|
|
// 准备 3D terrain source
|
|
// 准备 3D terrain source
|
|
map.addSource('mapbox-dem', {
|
|
map.addSource('mapbox-dem', {
|
|
'type': 'raster-dem',
|
|
'type': 'raster-dem',
|
|
@@ -76,14 +117,28 @@ onMounted(() => {
|
|
'tileSize': 512,
|
|
'tileSize': 512,
|
|
'maxzoom': 14
|
|
'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', {
|
|
map.addSource('bridge-demo-1', {
|
|
'type': 'geojson',
|
|
'type': 'geojson',
|
|
@@ -151,7 +206,8 @@ onMounted(() => {
|
|
'source': 'bridge-demo-1',
|
|
'source': 'bridge-demo-1',
|
|
'layout': {
|
|
'layout': {
|
|
'line-join': 'round',
|
|
'line-join': 'round',
|
|
- 'line-cap': 'round'
|
|
|
|
|
|
+ 'line-cap': 'round',
|
|
|
|
+ 'visibility': 'none',
|
|
},
|
|
},
|
|
'paint': {
|
|
'paint': {
|
|
'line-color': 'rgba(244, 208, 133, 0.8)',
|
|
'line-color': 'rgba(244, 208, 133, 0.8)',
|
|
@@ -164,7 +220,8 @@ onMounted(() => {
|
|
'source': 'bridge-demo-2',
|
|
'source': 'bridge-demo-2',
|
|
'layout': {
|
|
'layout': {
|
|
'line-join': 'round',
|
|
'line-join': 'round',
|
|
- 'line-cap': 'round'
|
|
|
|
|
|
+ 'line-cap': 'round',
|
|
|
|
+ 'visibility': 'none',
|
|
},
|
|
},
|
|
'paint': {
|
|
'paint': {
|
|
'line-color': 'rgba(244, 208, 133, 0.8)',
|
|
'line-color': 'rgba(244, 208, 133, 0.8)',
|
|
@@ -177,7 +234,8 @@ onMounted(() => {
|
|
'source': 'bridge-demo-3',
|
|
'source': 'bridge-demo-3',
|
|
'layout': {
|
|
'layout': {
|
|
'line-join': 'round',
|
|
'line-join': 'round',
|
|
- 'line-cap': 'round'
|
|
|
|
|
|
+ 'line-cap': 'round',
|
|
|
|
+ 'visibility': 'none',
|
|
},
|
|
},
|
|
'paint': {
|
|
'paint': {
|
|
'line-color': 'rgba(244, 208, 133, 0.8)',
|
|
'line-color': 'rgba(244, 208, 133, 0.8)',
|
|
@@ -185,7 +243,6 @@ onMounted(() => {
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
|
|
- // todo:操控
|
|
|
|
// 操场高亮
|
|
// 操场高亮
|
|
// Add a data source containing GeoJSON data.
|
|
// Add a data source containing GeoJSON data.
|
|
map.addSource('playground', {
|
|
map.addSource('playground', {
|
|
@@ -214,12 +271,77 @@ onMounted(() => {
|
|
'id': 'playground',
|
|
'id': 'playground',
|
|
'type': 'fill',
|
|
'type': 'fill',
|
|
'source': 'playground', // reference the data source
|
|
'source': 'playground', // reference the data source
|
|
- 'layout': {},
|
|
|
|
|
|
+ 'layout': {
|
|
|
|
+ 'visibility': 'none',
|
|
|
|
+ },
|
|
'paint': {
|
|
'paint': {
|
|
'fill-color': '#0080ff', // blue color fill
|
|
'fill-color': '#0080ff', // blue color fill
|
|
'fill-opacity': 0.5
|
|
'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)
|
|
const isShowFog = ref(false)
|
|
watch(isShowFog, (v) => {
|
|
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>
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
<style lang="less" scoped>
|
|
@@ -405,6 +559,31 @@ watch(isAutoRotate, (v) => {
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
background-color: rgba(255, 255, 255, 0.5);
|
|
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>
|
|
</style>
|