初识Cesium_vue (一)

78 阅读4分钟

一、Cesium基础

作为对cesium不熟悉的新人,本笔记将从各种细节,记录自己学习过程中的收获和问题,以便于对相关知识的积累和学习。

1、Cesium是什么:

image.png

2、支持的格式:

image.png

3、Cesium能做什么:

image.png

4、Cesium下载地址

cesium.com/downloads/

二、Vue调用Cesium测试

1、基础环境搭建

  1. 安装cesium插件,本次测试通过vui ui安装 cesium v1.112.0
  2. 配置vue.config.js
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
const path = require('path')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const cesiumSource = './node_modules/cesium/Source'
const cesiumWorkers = '../Build/Cesium/Workers'
// 头部引用
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: (config) => {
    const base = {
      output: {
        sourcePrefix: ' '
      },
      amd: {
        toUrlUndefined: true
      },
      resolve: {
        alias: {
          vue$: 'vue/dist/vue.esm.js',
          '@': path.resolve('./src'),
          cesium: path.resolve(__dirname, cesiumSource),
          '@com': path.resolve('./src/components')
        }
      },
      plugins: [
        new CopyWebpackPlugin({
          patterns: [
            { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }
          ]
        }),
        new CopyWebpackPlugin({
          patterns: [
            { from: path.join(cesiumSource, 'Assets'), to: 'Assets' }
          ]
        }),
        new CopyWebpackPlugin({
          patterns: [
            { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }
          ]
        }),
        new CopyWebpackPlugin({
          patterns: [
            {
              from: path.join(cesiumSource, 'ThirdParty/Workers'),
              to: 'ThirdParty/Workers'
            }
          ]
        }),
        new webpack.DefinePlugin({
          CESIUM_BASE_URL: JSON.stringify('./')
        }),
        new NodePolyfillPlugin()
      ],
      module: {
        unknownContextRegExp: /^.\/.*$/,
        unknownContextCritical: false,
        rules: [
          { test: /\.map$/, use: 'json-loader' },
          {
            test: /\.mjs$/,
            include: /node_modules/,
            type: 'javascript/auto'
          }
        ]
      }
    }
    return base
  }
})
  1. 配置对应vue组件
<template>
  <!-- 容器 -->
  <div id="container"></div>
</template>

<script>
import * as Cesium from 'cesium/Cesium' // api导入
import 'cesium/Widgets/widgets.css' // 样式导入
export default {
  mounted() {
    this.initModel()
  },
  data() {
    return {}
  },
  methods: {
    initModel() {
      // defaultAccessToken是访问的token,没有的要去官网注册账户
      Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwZDMzMWQzYi01NDcyLTQzZDYtYmNmNy1iNDdmYzJlNTZkNTEiLCJpZCI6MTY0MzEwLCJpYXQiOjE2OTM4MTM1NDl9.l2Mocdo0ZiRjzLC9INU7p_Y6wZuiRXJ3T1eW3s0aB7c'
      // 初始化球体
      /* eslint-disable no-new */
      new Cesium.Viewer('container')
    }
  }
}
</script>

<style scoped>
#container {
  width: 100vw;
  height: 100vh;
}
</style>

  1. 查看效果 image.png

2、基本结构和api目录

  1. 隐藏相关组件 (也可以用css来隐藏)
const viewer = new Cesium.Viewer('container', {
        animation: false, // 动画小组件
        baseLayerPicker: false, // 底图组件,选择三维数字地球的底图(imagery and terrain)。
        fullscreenButton: true, // 全屏组件
        vrButton: false, // VR模式
        geocoder: false, // 地理编码(搜索)组件
        homeButton: false, // 首页,点击之后将视图跳转到默认视角
        infoBox: false, // 信息框
        sceneModePicker: false, // 场景模式,切换2D、3D 和 Columbus View (CV) 模式。
        selectionIndicator: false, // 是否显示选取指示器组件
        timeline: false, // 时间轴
        navigationHelpButton: false, // 帮助提示,如何操作数字地球。
        // 如果最初应该看到导航说明,则为true;如果直到用户明确单击该按钮,则该提示不显示,否则为false。
        navigationInstructionsInitiallyVisible: false
      })

      // 隐藏logo
      viewer._cesiumWidget._creditContainer.style.display = 'none'

3、加载服务

image.png

image.png

遥感影像服务调用示例

// 调用天地图
      const tianditu = new Cesium.WebMapTileServiceImageryProvider({
        url: 'http://t1.tianditu.gov.cn/img_c/wmts?service=WMTS&version=1.0.0&request=GetTile&tilematrix={TileMatrix}&layer=img&style={style}&tilerow={TileRow}&tilecol={TileCol}&tilematrixset={TileMatrixSet}&format=tiles&tk=7f677a476ec5ffd4c4bf9945a1d044a1&tilesize=256',
        layer: 'img',
        style: 'default',
        format: 'tiles',
        tileMatrixSetID: 'c',
        credit: new Cesium.Credit('天地图全球影像服务'),
        subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], // 天地图8个服务器
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']
      })

// 调用吉威wmts服务
      const geoway_wmts = new Cesium.WebMapTileServiceImageryProvider({
        url: 'http://xxxxx/ime-cloud/rest/gebco_2022_sub_ice_topo_geotiff/wmts?tilematrix={TileMatrix}&layer=gebco_2022_sub_ice_topo_geotiff&style=default&tilerow={TileRow}&tilecol={TileCol}&tilematrixset=guobiao&format=image%2Fjpgpng&service=WMTS&version=1.0.0&request=GetTile&tilesize=256',
        layer: 'gebco_2022_sub_ice_topo_geotiff',
        style: 'default',
        tileMatrixSetID: 'c',
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14']
      })

      imageryLayers.addImageryProvider(tianditu)
      imageryLayers.addImageryProvider(geoway_wmts)

矢量瓦片服务调用示例(吉威公司的服务)

 const geoway_shp = new Cesium.UrlTemplateImageryProvider({
        url: 'http://xxxxx/mapserver/vmap/DLTB20191201/getMap?styleId=DLTB&tilesize=512&ratio=1&x={x}&y={y}&l={customZ}',
        // url: 'http://xxxxx/mapserver/vmap/jbxxm2021/getMap?styleId=jbxxm2021&tilesize=512&ratio=1&x={x}&y={y}&l={customZ}',
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'],
        // 自定义参数重新计算xyz的值,不知道公司为什么要手动改层级关系...
        customTags: {
          // customX: function (imageryProvider, x, y, level) {
          //   // 根据需要计算 x 的新值
          //   const newX = x / 4
          //   return newX
          // },
          // customY: function (imageryProvider, x, y, level) {
          //   // 根据需要计算 y 的新值
          //   const newY = y / 4
          //   return newY
          // },
          customZ: function (imageryProvider, x, y, level) {
            // 根据需要计算 y 的新值
            const newY = level + 2
            return newY
          }
        }
      })

4、鼠标事件

鼠标移动事件:

// 监听地图点击事件
      const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
      console.log(handler)
// 设置鼠标移动事件的处理函数,这里负责监听x,y坐标值变化
      const ellipsoid = this.viewer.scene.globe.ellipsoid
      handler.setInputAction(movement => {
        // 通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
        const cartesian = this.viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid)
        if (cartesian) {
          // 将笛卡尔坐标转换为地理坐标
          const cartographic = ellipsoid.cartesianToCartographic(cartesian)
          // 将弧度转为度的十进制度表示
          const longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4)
          const latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4)
          // 获取相机高度
          const height = Math.ceil(this.viewer.camera.positionCartographic.height)
          console.log(longitudeString, latitudeString, height)
          this.lon = longitudeString
          this.lat = latitudeString
          this.height = height
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

鼠标滚轮事件:

 // 滚轮事件
       handler.setInputAction(wheelment => {
         const height = Math.ceil(this.viewer.camera.positionCartographic.height)
         console.log(height)
       }, Cesium.ScreenSpaceEventType.WHEEL)

鼠标点击事件:

// 单击事件
      handler.setInputAction(click => {
        console.log('左键单击事件:', click.position)
        // 屏幕坐标转世界坐标——关键点
        const cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid)
        // 将笛卡尔坐标转换为地理坐标
        const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
        // 将弧度转为度的十进制度表示,保留5位小数
        const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5)
        const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5)
        console.log(lon, lat)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

鼠标中键和右键互换:

// 设置中键放大缩小
      this.viewer.scene.screenSpaceCameraController.zoomEventTypes = [Cesium.CameraEventType.WHEEL, Cesium.CameraEventType.MIDDLE_DRAG, Cesium.CameraEventType.PINCH]
      // 设置右键旋转
      this.viewer.scene.screenSpaceCameraController.tiltEventTypes = [
        Cesium.CameraEventType.RIGHT_DRAG,
        Cesium.CameraEventType.PINCH,
        {
          eventType: Cesium.CameraEventType.RIGHT_DRAG,
          modifier: Cesium.KeyboardEventModifier.CTRL
        },

        {
          eventType: Cesium.CameraEventType.MIDDLE_DRAG,
          modifier: Cesium.KeyboardEventModifier.CTRL
        }
      ]

问题记录:

1、配置vue.config.js后npm启动失败,报错什么@cesium\engine\Source\Core\Resource.js位置的错误,然后提示webpack版本超过5x会导致此问题,解决方式: 安装NodePolyfillPlugin插件,并在vue.config.js中新增plugins ----- new NodePolyfillPlugin()

2、wmts经纬度服务只在上半球上能展示,解决方案在添加的Provider对象内添加如下参数:

tilingScheme: new Cesium.GeographicTilingScheme(),
tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']

image.png