首页 > 其他分享 >如何使用mapbox实现楼层分层,即所谓的单体化;以及如何在vue3中使用mapbox

如何使用mapbox实现楼层分层,即所谓的单体化;以及如何在vue3中使用mapbox

时间:2024-11-06 11:50:19浏览次数:6  
标签:map style extrusion mapbox height 楼层 vue3 type

我们在做webgis开发的过程中,应该经常会去加载一些类似白膜的数据,但是呢,如何实现对楼房分分层这个问题不知道大家有没有思考过,在cesium中是可以实现这个操作的,但是过程十分复杂繁琐;今天呢给大家介绍一种简单的,利用mapbox实现楼层分层单体化。

先展示一下效果图

初始状态

鼠标经过

顺便也跟大家讲一下vue3中引入mapbox库的简单过程。

一、创建项目

1、

2、

3、把创建完成的项目用vscode打开,提示一下,我这里使用的是vite脚手架,如果你用的是其他脚手架,就按照你熟悉的方式创建项目即可

4、同时按住 ctrl + ~键(就是esc下面的那个键)调出终端

ok,到这里项目创建完成,在终端输入pnpm dev再回车即可看到项目已经可以运行。

5、准备工作

清理不需要的文件

现在在运行一下项目,可以看见是一个空白的页面,很好,接下来就是引入mapbox

二、引入mapbox,这里我是利用CDN的形式引入的

找到项目中的index.html文件,将mapbox的CDN引入,就一个css文件和一个js文件,大家也可以去下载下来,放在src下面。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link
      rel="icon"
      href="/favicon.ico"
    />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js"></script>
    <link
      href="https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css"
      rel="stylesheet"
    />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script
      type="module"
      src="/src/main.js"
    ></script>
  </body>
</html>

然后到app.vue中初始化地图

<template>
  <!-- 设置地图容器 -->
  <div id="map"></div>
</template>

<script setup>
import { onMounted } from 'vue'
let map
// 在onmounted生命周期钩子中初始化地图
onMounted(() => {
  mapboxgl.accessToken = '你的token'
  map = new mapboxgl.Map({
    container: 'map', // container ID
    // style: 'mapbox://styles/mapbox/streets-v12', // style URL
    // 我这里使用的是高德地图的样式
    style: {
      version: 8,
      sources: {
        'raster-tiles': {
          type: 'raster',
          tiles: ['http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'],
          tileSize: 256
        }
      },
      layers: [
        {
          id: 'simple-tiles',
          type: 'raster',
          source: 'raster-tiles',
          minzoom: 16,
          maxzoom: 20
        }
      ]
    },
    center: [114.124064, 30.463405],
    zoom: 16,
    pitch: 45,
    projection: 'globe'
  })
})
</script>

<style scoped>
/* 一定记得给地图容器设置宽高,不然地图无法显示 */
#map {
  width: 100%;
  height: 100vh;
}
</style>

ok,到这里地图初始化完成,几个点注意一下,token大家自己去申请,地图容器记得给尺寸,在onmounted生命周期钩子中去挂在地图

三、准备数据

推荐使用L7 Editor - 基于 L7 的地理数据绘制工具

把准备好的数据在项目中存起来

然后这个数据我们需要修改一下,就是加几个字段,楼层索引floorIndex、楼层高度height、楼层颜色color,然后把它复制几份就ok了。具体示例如下

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "height": 5,
        "floorIndex": 1,
        "color": "#aa3542"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              114.122747,
              30.463958
            ],
            [
              114.123847,
              30.464461
            ],
            [
              114.124024,
              30.464168
            ],
            [
              114.122947,
              30.463627
            ],
            [
              114.122747,
              30.463958
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "height": 10,
        "floorIndex": 2,
        "color": "#00ff00"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              114.122747,
              30.463958
            ],
            [
              114.123847,
              30.464461
            ],
            [
              114.124024,
              30.464168
            ],
            [
              114.122947,
              30.463627
            ],
            [
              114.122747,
              30.463958
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "height": 15,
        "floorIndex": 3,
        "color": "#0000ff"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              114.122747,
              30.463958
            ],
            [
              114.123847,
              30.464461
            ],
            [
              114.124024,
              30.464168
            ],
            [
              114.122947,
              30.463627
            ],
            [
              114.122747,
              30.463958
            ]
          ]
        ]
      }
    }
  ]
}

四、实现楼栋分层,并且鼠标经过不同楼层,楼层变色

主要三件事

1、楼层分层显示

2、鼠标移入移出事件

3、鼠标移入楼层、对应楼层变色高亮

代码直接给大家,逻辑很清晰,看一下就知道了,如果不了解为什么这样写,可以去我的mapbox专辑中去看,我会进行讲解。目前对于mapbox我也在摸索中。希望大家多多点赞收藏。

<template>
  <div id="map"></div>
  <button @click="test"></button>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import buildJson from '../src/data/test.json'
let map
onMounted(() => {
  mapboxgl.accessToken = '你的token'
  map = new mapboxgl.Map({
    container: 'map', // container ID
    // style: 'mapbox://styles/mapbox/streets-v12', // style URL
    style: {
      version: 8,
      sources: {
        'raster-tiles': {
          type: 'raster',
          tiles: ['http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'],
          tileSize: 256
        }
      },
      layers: [
        {
          id: 'simple-tiles',
          type: 'raster',
          source: 'raster-tiles',
          minzoom: 16,
          maxzoom: 20
        }
      ]
    },
    center: [114.124064, 30.463405],
    zoom: 16,
    pitch: 45,
    projection: 'globe'
  })
  map.on('load', () => {
    map.addSource('buildings', {
      type: 'geojson',
      data: buildJson
    })
    map.addLayer({
      id: '3d-buildings',
      source: 'buildings',
      type: 'fill-extrusion',
      paint: {
        'fill-extrusion-color': ['get', 'color'],
        'fill-extrusion-height': ['get', 'height'],
        'fill-extrusion-base': ['-', ['*', ['get', 'floorIndex'], 5], 5],
        'fill-extrusion-opacity': 0.6
      }
    })
    // 临时高亮图层
    map.addLayer({
      id: 'highlight',
      source: 'buildings',
      type: 'fill-extrusion',
      paint: {
        'fill-extrusion-color': '#ff0000',
        'fill-extrusion-height': ['get', 'height'],
        'fill-extrusion-base': ['-', ['*', ['get', 'floorIndex'], 5], 5],
        'fill-extrusion-opacity': 0.6
      },
      filter: ['==', 'floorIndex', 0]
    })
    map.on('mouseenter', '3d-buildings', function (e) {
      map.getCanvas().style.cursor = 'pointer'
      let feature = e.features[0]
      // 高亮
      map.setFilter('highlight', ['==', 'floorIndex', feature.properties.floorIndex])
    })
    map.on('mouseleave', '3d-buildings', function () {
      map.getCanvas().style.cursor = ''
      map.setFilter('highlight', ['==', 'floorIndex', 0])
    })
  })
})
</script>

<style scoped>
#map {
  width: 100%;
  height: 100vh;
}
</style>

标签:map,style,extrusion,mapbox,height,楼层,vue3,type
From: https://blog.csdn.net/qq_45751819/article/details/143507584

相关文章