vuecli3使用cesium

563 阅读4分钟

一 vuecli3引入cesium

1.新建项目后首先安装依赖

npm install cesium -s

2.修改main.js 文件 在里面添加

var cesium = require('cesium/Cesium');
var widgets= require('cesium/Widgets/widgets.css');

Vue.prototype.cesium = cesium
Vue.prototype.widgets = widgets

3.项目文件夹下新建文件:vue.config.js

const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const path = require('path')

let cesiumSource = './node_modules/cesium/Source'
let cesiumWorkers = '../Build/Cesium/Workers'



module.exports = {
    // 基本路径  3.6之前的版本时 baseUrl
    publicPath: "./",
    // 输出文件目录
    outputDir: "dist",
    // eslint-loader 是否在保存的时候检查
    lintOnSave: false,
    // webpack-dev-server 相关配置
    devServer: {
        proxy: {
            '/try': {
                target: 'https://www.runoob.com',
                ws: true,
                changeOrigin: true
            },
            '/yuxi_DEM': {
                target: 'http://yxgis2sim.hdec.com',
                ws: true,
                changeOrigin: true
            },
            '/iserver': {
                target: 'http://yxgis2sim.hdec.com',
                ws: true,
                changeOrigin: true
            },
            '/testt': {
                target: 'http://localhost:8081',
                ws: true,
                changeOrigin: true
            },
            // '/ismap-mvt-ShenSeDiTu1231erver': {
            //   target: 'http://gisct.ecidi.com/iserver/services',
            //   ws: true,
            //   changeOrigin: true
            // },
            '/map-mvt-ShenSeDiTu1231': {
                target: 'http://gisct.ecidi.com/iserver/services',
                ws: true,
                changeOrigin: true
            },
            '/yuxiBasemap': {
                target: 'http://yxgis2.hdec.com',
                ws: true,
                changeOrigin: true
            },
            '/geoserver': {
                target: 'http://localhost:8088',
                ws: true,
                changeOrigin: true
            },
            '/UserController': {
                target: 'http://localhost:8080',
                ws: true,
                changeOrigin: true
            }
            // '/foo': {
            //   target: '<other_url>'
            // }
        }
    },
    configureWebpack: {
        output: {
            sourcePrefix: ' '
        },
        amd: {
            toUrlUndefined: true
        },
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.esm.js',
                '@': path.resolve('src'),
                'cesium': path.resolve(__dirname, cesiumSource)
            }
        },
        plugins: [
            new CopyWebpackPlugin([{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }]),
            new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }]),
            new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }]),
            new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers' }]),
            new webpack.DefinePlugin({
                CESIUM_BASE_URL: JSON.stringify('./')
            })
        ],
        module: {
            unknownContextCritical: /^.\/.*$/,
            unknownContextCritical: false,
            rules: [
                {
                    test: /\.js$/,
                    use: {
                        loader: '@open-wc/webpack-import-meta-loader',
                    },
                },
            ]
        }

    }
}

4.在views文件夹下新建组件Cesium.vue

<template>
   <div id="cesium">
   </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  name: "",
  components: {},
  mounted() {
    this.init();
  },
  methods: {
    init() {
      let Cesium = this.cesium;
      this.viewer = new Cesium.Viewer("cesium", {
        animation: false, //是否创建动画小器件,左下角仪表
        baseLayerPicker: false, //是否显示图层选择器
        fullscreenButton: false, //是否显示全屏按钮
        geocoder: false, //是否显示geocoder小器件,右上角查询按钮
        homeButton: false, //是否显示Home按钮
        infoBox: false, //是否显示信息框
        sceneModePicker: false, //是否显示3D/2D选择器
        selectionIndicator: false, //是否显示选取指示器组件
        timeline: false, //是否显示时间轴
        navigationHelpButton: false, //是否显示右上角的帮助按钮
      });
      this.viewer._cesiumWidget._creditContainer.style.display = "none"; //去掉版权信息
      this.viewer.scene.sun.show = false; //关闭显示太阳和月亮,不关闭会影响展示
      this.viewer.scene.moon.show = false;
      this.viewer.scene.skyAtmosphere.show = false; //隐藏大气圈
      this.viewer.scene.skyBox.show = false; //天空盒的显影
      this.viewer.scene.globe.show = false; //地球的显示
      this.viewer.scene.globe.enableLighting = false; // 开启全球光照
      this.viewer.shadows = false;//阴影
    },
   },
};
</script>

<style scoped>
#cesium {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
</style>

5.运行项目报错后安装@open-wc/webpack-import-meta-loader

npm install @open-wc/webpack-import-meta-loader

二,cesium地球背景的设置

1.星空背景

this.viewer.scene.skyBox.show = true; //天空盒的显影
  this.viewer.scene.skyBox = new Cesium.SkyBox({
        sources: {
          positiveX:
            "http://81.68.73.55/group1/M00/00/05/rBEAA1-ksPKAcNylACNu1lQm8u8356.png",
          negativeX:
            "http://81.68.73.55/group1/M00/00/05/rBEAA1-ksK6AZXxwABvSzSIL87Y975.png",
          positiveY:
            "http://81.68.73.55/group1/M00/00/05/rBEAA1-ksF-AKN6uAB0nITX6ytY508.png",
          negativeY:
            "http://81.68.73.55/group1/M00/00/05/rBEAA1-ksWWATYKJACsujon32-c647.png",
          positiveZ:
            "http://81.68.73.55/group1/M00/00/05/rBEAA1-ksH-ACw_hABhT2WaTM2Q296.png",
          negativeZ:
            "http://81.68.73.55/group1/M00/00/05/rBEAA1-ksCGAAkQ3AB26d_3SVig888.png",
        },
      });

2.纯色背景

  this.viewer.scene.backgroundColor = new Cesium.Color(105/255,152/255,192/255,0.3);//背景颜色

3.透明背景

   this.viewer = new Cesium.Viewer("textContainer", {

        orderIndependentTranslucency: false, // 透明背景设置
        contextOptions: {
          webgl: {
            alpha: true,
          },
        },
      });
this.viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 0.0); //设置背景透明

三,去除时间原因影响模型颜色

this.viewer.scene.light = new Cesium.DirectionalLight({
        direction: new Cesium.Cartesian3(
          0.35492591601301104,
          -0.0909182691839401,
          -0.2833588392420772
        ),
      });

四,3dtiles模型

1,加载3dtiles模型

 var viewer = this.viewer;
      var tileset = viewer.scene.primitives.add(
        new Cesium.Cesium3DTileset({
          url: "static/212-4/tileset.json",//模型的地址
        })
      );
      this.viewer.zoomTo(tileset);// 定位到模型的位置

2,加载时,改变模型的位置

var params = {
        tx: 118.80659, //模型中心X轴坐标(经度,单位:十进制度)
        ty: 36.71809, //模型中心Y轴坐标(纬度,单位:十进制度)
        tz: 1000, //模型中心Z轴坐标(高程,单位:米)
        rx: 120, //X轴(经度)方向旋转角度(单位:度)
        ry: 180, //Y轴(纬度)方向旋转角度(单位:度)
        rz: 0, //Z轴(高程)方向旋转角度(单位:度)
      };
      tileset.readyPromise.then(function (tileset) {
        update3dtilesMaxtrix(tileset);
      });
      function update3dtilesMaxtrix(tileset) {
        //旋转
        var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
        var my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
        var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
        var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
        var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
        var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz); //平移
        var position = Cesium.Cartesian3.fromDegrees(
          params.tx,
          params.ty,
          params.tz
        );
        var m = Cesium.Transforms.eastNorthUpToFixedFrame(position); //旋转、平移矩阵相乘
        Cesium.Matrix4.multiply(m, rotationX, m);
        Cesium.Matrix4.multiply(m, rotationY, m);
        Cesium.Matrix4.multiply(m, rotationZ, m);
        //赋值给tileset
        tileset._root.transform = m;
        var scale = Cesium.Matrix4.fromUniformScale(0.6);// 模型的比例
        Cesium.Matrix4.multiply(m, scale, m);
      }

3,给模型设置高亮

var handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
      //高亮显示代码
      var previousPickedEntity = {
        feature: undefined,
        originalColor: undefined,
      };
      previousPickedEntity.feature = {
        color: undefined,
      };
      // 鼠标移入事件
      handler.setInputAction((movement) => {
        if (this.viewer.scene.mode !== Cesium.SceneMode.MORPHING) {
          var pickingEntity = this.viewer.scene.pick(movement.endPosition);// 移入的模型
          if (
            this.viewer.scene.pickPositionSupported &&
            Cesium.defined(pickingEntity)
          ) {
            // 模型高亮
            if (pickingEntity instanceof Cesium.Cesium3DTileFeature) {
              //判断以前是否选择要素
              if (pickingEntity != previousPickedEntity.feature) {
                if (previousPickedEntity.feature != undefined) {
                  //还原前选择要素的本颜色
                  previousPickedEntity.feature.color =
                    previousPickedEntity.originalColor;
                  //将当前选择要素及其颜色添加到previousPickedEntity
                  previousPickedEntity.feature = pickingEntity;
                  previousPickedEntity.originalColor = pickingEntity.color;
                }
                //将当前选择要素及其颜色添加到previousPickedEntity
                previousPickedEntity.feature = pickingEntity;
                previousPickedEntity.originalColor = pickingEntity.color;
              }
              //将模型变为高亮
              pickingEntity.color = new Cesium.Color(
                101 / 255,
                139 / 255,
                219 / 255,
                0.9
              );
              document.getElementById("bubble").style.display = "block"; //显示信息框
              // document.getElementById("name").innerText = pickingEntity._batchId;//显示信息框,(_batchId模型的唯一标识)
              // 信息框的位置
              document.getElementById("bubble").style.marginTop =
                movement.endPosition.y -
                document.getElementById("bubble").offsetHeight +
                30 +
                "px";
              document.getElementById("bubble").style.marginLeft =
                movement.endPosition.x + "px";
              document.getElementById("textContainer").style.cursor = "pointer";// 移入模型鼠标变小手
            }
          } else {
            previousPickedEntity.feature.color =
              previousPickedEntity.originalColor;
            document.getElementById("bubble").style.display = "none";// 隐藏信息框
            document.getElementById("textContainer").style.cursor = "default";// 小手变回箭头
          }
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

4,在模型上创造点位

var handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
     // 增加点位
      var screenPoints = [];		//屏幕坐标
      var cesiumPoints = [];
      // 鼠标点击放置点位获得坐标
         handler.setInputAction((e) => {
        screenPoints.push({ x: e.position.x, y: e.position.y });
        console.log("屏幕坐标:", "[" + e.position.x + ", " + e.position.y + "]");
        var position = this.viewer.scene.pickPosition(e.position);
        //将笛卡尔坐标转化为经纬度坐标
        var cartographic = Cesium.Cartographic.fromCartesian(position);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude);//经度
        var latitude = Cesium.Math.toDegrees(cartographic.latitude);// 纬度
        var height = cartographic.height;// 高度
        console.log("Cartesian3: ", "["+ longitude + ", " + latitude + ", " + height + "]")
        cesiumPoints.push({ x: longitude, y: latitude, z: height });
        
        this.viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
          billboard: {
            image: "https://s3.bmp.ovh/imgs/2022/03/49269aae09a4143f.png", // 点位图片
            show: true, 
            pixelOffset: new Cesium.Cartesian2(0, -14), // default: (0, 0)
            eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0), 
            scale: 1.0, 
            width: 20, 
            height: 30, 
          },
        });
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
     console.log("cartesian3: ", cesiumPoints)

5,鼠标点击事件

      // 鼠标点击事件
      handler.setInputAction((click) => {
        var pick = this.viewer.scene.pick(click.position);
           console.log('左键单击事件:',pick);
       }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

6,加载广告牌

6.1加载

var Entity = viewer.entities.add({
                id:"billboard"
                name: "billboard",
                position: Cesium.Cartesian3.fromDegrees(109.44, 32.11,30.0),
                point: { //点
                    pixelSize: 0,
                    HeightReference: 1000
                },
                label: { //文字标签
                    text: "文字标签",
                    font: '500 30px Helvetica',// 15pt monospace
                    scale: 0.5,
                    style: Cesium.LabelStyle.FILL,
                    fillColor: Cesium.Color.WHITE,
                    pixelOffset: new Cesium.Cartesian2(-8, -35),   //偏移量
                    showBackground: true,
                    backgroundColor: new Cesium.Color(0.5, 0.6, 1, 1.0)
                },
                billboard: { //图标
                    image: 'static/image/billboard.png',// 图标地址
                    width: 50,
                    height: 50
                },
            });

6.2销毁广告牌

this.viewer.entities.remove({ id: "billboard" });

7,相机定位

   // 相机定位
    cameraView(lon, lat, alt, heading, pitch, roll) {
      let Cesium = this.cesium;
      this.viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(lon, lat, alt), // 经纬度,高度
        orientation: {
          heading: Cesium.Math.toRadians(heading),// 0°平视,-90°俯视,90°仰视
          pitch: Cesium.Math.toRadians(pitch),// 左右旋转
          roll: roll,// 旋转角,一般不用
        },
      });
    },

8,开启抗锯齿

this.viewer.scene.fxaa = true;
this.viewer.scene.postProcessStages.fxaa.enabled = true;

9,鼠标改变视角的控制

      // 禁止左键按下视角平移
      this.viewer.scene.screenSpaceCameraController.enableRotate = false;
      // 禁止中键缩放视角
      this.viewer.scene.screenSpaceCameraController.enableZoom = false;
      // 禁止控制视角旋转
      this.viewer.scene.screenSpaceCameraController.enableTilt = false;

五,加载Geojson模型和gltf模型

1,加载Geojson

this.viewer.dataSources.add(Cesium.GeoJsonDataSource.load('http://localhost:8080/static/json/school.json', {
        stroke: Cesium.Color.HOTPINK,
        fill: Cesium.Color.PINK.withAlpha(0.5),
        strokeWidth: 3
      })).then((res) => {
        // console.log("res", res);
        let entities = res.entities.values;
        let colorHash = {};
        for (var i = 0; i < entities.length; i++) {
          var entity = entities[i];
          var name = entity.name;
          // console.log(name);
          var color = colorHash[name];
          // console.log(name, " : ", color);
          if (!color) {
            color = Cesium.Color.fromRandom({
              alpha: 1.0
            });
            colorHash[name] = color;
          }
          entity.polygon.material = color;
          entity.polygon.outline = false;
          entity.polygon.extrudedHeight = entity.properties.childrenNum; //高度扩大5000倍,便于观察
          // console.log("height: ", entity.properties.childrenNum);
        }
      })

2,销毁Geojson

this.viewer.dataSources.removeAll();//全部销毁

3,加载gltf模型

	var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(114.596396, 36.655077, 0));

      var model = this.viewer.scene.primitives.add(Cesium.Model.fromGltf({
        url: 'static/gltf/kkkkkk_0.gltf',
        modelMatrix: modelMatrix,
        scale: 1.15
      }));
      // 设置模型旋转90度
      model.readyPromise.then((argument) => {
        var position = Cesium.Cartesian3.fromDegrees(114.5847, 36.665107, 0);
        var mat = Cesium.Transforms.eastNorthUpToFixedFrame(position);
        var rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(-90)));
        Cesium.Matrix4.multiply(mat, rotationX, mat);
        model.modelMatrix = mat;
      })

4,销毁gltf模型

 this.model.destroy();//老版本
 
  this.viewer.scene.primitives.remove(this.model);
  this.model = "";//新版本