一、Cesium基础
作为对cesium不熟悉的新人,本笔记将从各种细节,记录自己学习过程中的收获和问题,以便于对相关知识的积累和学习。
1、Cesium是什么:
2、支持的格式:
3、Cesium能做什么:
4、Cesium下载地址
二、Vue调用Cesium测试
1、基础环境搭建
- 安装cesium插件,本次测试通过vui ui安装 cesium v1.112.0
- 配置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
}
})
- 配置对应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>
- 查看效果
2、基本结构和api目录
- 隐藏相关组件 (也可以用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、加载服务
遥感影像服务调用示例
// 调用天地图
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']