123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- <template>
- <div
- class="home"
- >
- <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>
- <el-checkbox
- v-model="isShowLabels"
- label="show labels"
- size="large"
- />
- <el-checkbox
- v-model="isShowTerrain"
- label="show terrain"
- size="large"
- />
- <el-checkbox
- v-model="isShowFog"
- label="show fog"
- size="large"
- />
- <el-checkbox
- v-model="isAutoRotate"
- label="auto rotate"
- size="large"
- />
- </div>
- </div>
- </template>
- <script setup>
- import { ref, computed, watch, onMounted } from "vue"
- import { useRoute, useRouter } from "vue-router"
- import { useStore } from "vuex"
- import mapboxgl from 'mapbox-gl'
- const route = useRoute()
- const router = useRouter()
- const store = useStore()
- mapboxgl.accessToken = 'pk.eyJ1IjoiamlidmFnIiwiYSI6ImNsdDVibmxvZDAwbjcyanAzNmpzOHpoeHUifQ.KKYv3iK0IiL37rNDYkb-dQ'
- let map = null
- 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,
- })
- map.on('style.load', () => {
- // 隐藏标签。
- map.setConfigProperty('basemap', 'showPlaceLabels', false)
- map.setConfigProperty('basemap', 'showRoadLabels', false)
- map.setConfigProperty('basemap', 'showPointOfInterestLabels', false)
- map.setConfigProperty('basemap', 'showTransitLabels', false)
- // 准备 3D terrain source
- map.addSource('mapbox-dem', {
- 'type': 'raster-dem',
- 'url': 'mapbox://mapbox.terrain-rgb',
- 'tileSize': 512,
- 'maxzoom': 14
- })
- })
- map.on('click', (e) => {
- console.log(e.lngLat.wrap())
- })
- map.on('load', () => {
- // todo: 操控
- // 桥梁高亮
- map.addSource('bridge-demo-1', {
- 'type': 'geojson',
- 'data': {
- 'type': 'Feature',
- 'properties': {},
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [
- [
- 2.291370903863708,
- 48.860291730262816
- ],
- [
- 2.2926683589130334,
- 48.85941742662925
- ],
- ]
- }
- }
- })
- map.addSource('bridge-demo-2', {
- 'type': 'geojson',
- 'data': {
- 'type': 'Feature',
- 'properties': {},
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [
- [
- 2.2867527694825185,
- 48.85655006915218
- ],
- [
- 2.28846012300869,
- 48.85483140541177
- ],
- ]
- }
- }
- })
- map.addSource('bridge-demo-3', {
- 'type': 'geojson',
- 'data': {
- 'type': 'Feature',
- 'properties': {},
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [
- [
- 2.3016957824563633,
- 48.86404969411541
- ],
- [
- 2.3018487764027213,
- 48.862882778017564
- ],
- ]
- }
- }
- })
- map.addLayer({
- 'id': 'bridge-demo-1',
- 'type': 'line',
- 'source': 'bridge-demo-1',
- 'layout': {
- 'line-join': 'round',
- 'line-cap': 'round'
- },
- 'paint': {
- 'line-color': 'rgba(244, 208, 133, 0.8)',
- 'line-width': 40,
- }
- })
- map.addLayer({
- 'id': 'bridge-demo-2',
- 'type': 'line',
- 'source': 'bridge-demo-2',
- 'layout': {
- 'line-join': 'round',
- 'line-cap': 'round'
- },
- 'paint': {
- 'line-color': 'rgba(244, 208, 133, 0.8)',
- 'line-width': 40,
- }
- })
- map.addLayer({
- 'id': 'bridge-demo-3',
- 'type': 'line',
- 'source': 'bridge-demo-3',
- 'layout': {
- 'line-join': 'round',
- 'line-cap': 'round'
- },
- 'paint': {
- 'line-color': 'rgba(244, 208, 133, 0.8)',
- 'line-width': 40,
- }
- })
- // todo:操控
- // 操场高亮
- // Add a data source containing GeoJSON data.
- map.addSource('playground', {
- 'type': 'geojson',
- 'data': {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- // These coordinates outline playground.
- 'coordinates': [
- [
- [2.290685454637469, 48.85648212786501],
- [2.290678167471242, 48.85674317251818],
- [2.2909987705963886, 48.856988869994325],
- [2.2913584104396705, 48.85706691648497],
- [2.2926340590652217, 48.856240774123734],
- [2.2926899302722177, 48.85607261804398],
- [2.291903329216666, 48.85567435087097],
- [2.2916458346767286, 48.855731990701315],
- ]
- ]
- }
- }
- })
- map.addLayer({
- 'id': 'playground',
- 'type': 'fill',
- 'source': 'playground', // reference the data source
- 'layout': {},
- 'paint': {
- 'fill-color': '#0080ff', // blue color fill
- 'fill-opacity': 0.5
- }
- })
- })
- })
- // 时间选择
- const timeOptions = [
- {
- label: 'dusk',
- value: 'dusk',
- },
- {
- label: 'day',
- value: 'day',
- },
- {
- label: 'dawn',
- value: 'dawn',
- },
- {
- label: 'night',
- value: 'night',
- },
- ]
- const timeInDay = ref(timeOptions[1].value)
- watch(timeInDay, (v) => {
- map.setConfigProperty('basemap', 'lightPreset', v) // dusk, dawn, day, and night
- if (isShowFog.value) {
- if (timeInDay.value === 'day') {
- map.setFog({
- 'range': [-1, 2],
- 'horizon-blend': 0.3,
- 'color': 'white',
- 'high-color': '#add8e6',
- 'space-color': '#d8f2ff',
- 'star-intensity': 0.0
- })
- } else if (timeInDay.value === 'dusk' || timeInDay.value === 'dawn') {
- map.setFog({
- 'range': [-1, 2],
- 'horizon-blend': 0.3,
- 'color': '#999',
- 'high-color': '#add8e6',
- 'space-color': '#d8f2ff',
- 'star-intensity': 0.4
- })
- } else {
- map.setFog({
- 'range': [-1, 2],
- 'horizon-blend': 0.3,
- 'color': '#242B4B',
- 'high-color': '#161B36',
- 'space-color': '#0B1026',
- 'star-intensity': 0.8
- })
- }
- }
- })
- // 标签开关
- const isShowLabels = ref(false)
- watch(isShowLabels, (v) => {
- map.setConfigProperty('basemap', 'showPlaceLabels', v)
- map.setConfigProperty('basemap', 'showRoadLabels', v)
- map.setConfigProperty('basemap', 'showPointOfInterestLabels', v)
- map.setConfigProperty('basemap', 'showTransitLabels', v)
- })
- // 地形开关
- const isShowTerrain = ref(false)
- watch(isShowTerrain, (v) => {
- if (v) {
- map.setTerrain({
- 'source': 'mapbox-dem',
- 'exaggeration': 1
- })
- } else {
- map.setTerrain(null)
- }
- })
- // 雾开关
- const isShowFog = ref(false)
- watch(isShowFog, (v) => {
- if (v) {
- if (timeInDay.value === 'day') {
- map.setFog({
- 'range': [-1, 2],
- 'horizon-blend': 0.3,
- 'color': 'white',
- 'high-color': '#add8e6',
- 'space-color': '#d8f2ff',
- 'star-intensity': 0.0
- })
- } else if (timeInDay.value === 'dusk' || timeInDay.value === 'dawn') {
- map.setFog({
- 'range': [-1, 2],
- 'horizon-blend': 0.3,
- 'color': '#999',
- 'high-color': '#add8e6',
- 'space-color': '#d8f2ff',
- 'star-intensity': 0.4
- })
- } else {
- map.setFog({
- 'range': [-1, 2],
- 'horizon-blend': 0.3,
- 'color': '#242B4B',
- 'high-color': '#161B36',
- 'space-color': '#0B1026',
- 'star-intensity': 0.8
- })
- }
- } else {
- map.setFog(null)
- }
- })
- // 自动旋转开关
- const isAutoRotate = ref(false)
- let lastFrameTime = 0.0
- let animationTotalTime = 0.0
- let initialBearing = null
- function frameTask(timeStamp) {
- if (isAutoRotate.value) {
- animationTotalTime += ((timeStamp - lastFrameTime) / 1000.0)
- const rotation = initialBearing + animationTotalTime * 2.0
- map.setBearing(rotation % 360)
- lastFrameTime = timeStamp
- window.requestAnimationFrame(frameTask)
- }
- }
- watch(isAutoRotate, (v) => {
- if (v) {
- lastFrameTime = 0.0
- animationTotalTime = 0.0
- initialBearing = map.getBearing()
- window.requestAnimationFrame(frameTask)
- }
- })
- // 一种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>
- .home {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- #map{
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- }
- .panel{
- position: absolute;
- top: 0;
- left: 0;
- padding: 10px;
- display: flex;
- flex-direction: column;
- background-color: rgba(255, 255, 255, 0.5);
- }
- }
- </style>
|