cesium开发常用方法总结(拾取坐标,弹框信息跟随,地图视角切换,水面波浪效果,获取当前相机视角信息,绘制轨迹路线...)

cesium 使用方法总结(持续更新)

cesiumNavigation使用(导航控件,比例尺等)
资源文件: 链接:https://pan.baidu.com/s/1jBDZdDTyaTU1LooO7LgJcA

提取码:uf37

全局:
    <script src="<%= BASE_URL %>CesiumNavigation/CesiumNavigation.umd.js"></script>
    <link href="<%= BASE_URL %>CesiumNavigation/cesium-navigation.css" rel="stylesheet">
或者
npm install cesium-navigation-es6
import CesiumNavigation from 'cesium-navigation-es6'
 initCesiumNavigation(viewer: any) {
    const options: any = {}
    // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
    options.defaultResetView = new Cesium.Rectangle.fromDegrees(80, 22, 130, 50) // new Cesium.Rectangle.fromDegrees(113.8980, 22.4899, 113.9686, 22.5438)
    // 用于启用或禁用罗盘。true是启用罗盘,false是禁用罗盘。默认值为true。如果将选项设置为false,则罗盘将不会添加到地图中。
    options.enableCompass = true
    // 用于启用或禁用缩放控件。true是启用,false是禁用。默认值为true。如果将选项设置为false,则缩放控件将不会添加到地图中。
    options.enableZoomControls = true
    // 用于启用或禁用距离图例。true是启用,false是禁用。默认值为true。如果将选项设置为false,距离图例将不会添加到地图中。
    options.enableDistanceLegend = true
    // 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。
    options.enableCompassOuterRing = true
    CesiumNavigation(viewer, options)
  }
消除锯齿
// 消除锯齿
  removeJagged(viewer: any) {
    viewer.scene.postProcessStages.fxaa.enabled = false
    viewer.scene.fxaa = false
    const supportsImageRenderingPixelated =
      viewer.cesiumWidget._supportsImageRenderingPixelated
    if (supportsImageRenderingPixelated) {
      let vtxf_dpr = window.devicePixelRatio
      while (vtxf_dpr >= 2.0) {
        vtxf_dpr /= 2.0
      }
      viewer.resolutionScale = vtxf_dpr
    }
  }
坐标拾取,打印经纬度
eventMap(viewer) {

                var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
                    //拾取坐标
                handler.setInputAction((event) => {

                    var earthPosition = viewer.camera.pickEllipsoid(event.position, viewer.scene.globe.ellipsoid);
                    var cartographic = Cesium.Cartographic.fromCartesian(earthPosition, viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
                    var lat = Cesium.Math.toDegrees(cartographic.latitude);
                    var lng = Cesium.Math.toDegrees(cartographic.longitude);
                    var height = cartographic.height;
					console.log('经度'+lng+'纬度'+lat)
                }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            },
弹框标记跟随点击的位置

cesiumView:cesium的viewer对象
htmlOverlay:要操作的弹框对象(document.getElementbyId)
lng:经度值
lat:纬度值


            htmlFixed(cesiumView, htmlOverlay, lng, lat) {
                const domHeight = htmlOverlay.offsetHeight; // DOM的高度
                const domWidth = htmlOverlay.offsetWidth; // DOM的宽度
                const heightOffset = 20; // Y轴偏移量
                const widthOffset = -9; // X轴偏移量

                const scratch = new Cesium.Cartesian2();
                cesiumView.scene.preRender.addEventListener(function() {
                    var las = lat - 0.0009;
                    let position = Cesium.Cartesian3.fromDegrees(
                        lng, las, 2);
                    let canvasPosition = cesiumView.scene
                        .cartesianToCanvasCoordinates(position,
                            scratch);
                    if (Cesium.defined(canvasPosition)) {
                        htmlOverlay.style.top = canvasPosition.y -
                            domHeight -
                            heightOffset + 'px';
                        htmlOverlay.style.left = canvasPosition.x -
                            domWidth / 2 -
                            widthOffset + 'px';
                    }
                });
            },
地球视角切换

            mapFlyTo(viewer, lng, lat, height) {
                        viewer.camera.flyTo({
                            destination: new Cesium.Cartesian3.fromDegrees(lng, lat, height),
                            duration: 3 //飞行时间
                        })
            }
水面波浪效果
 // 湖面效果                     睡眠区域的坐标  cesium实例对象
                init_xianRiver(coordinates, viewer) {
                    let coordinateArray = [];

                    for (let index = 0; index < coordinates.length; index++) {
                        for (let i = 0; i < coordinates[index].length; i++) {
                            coordinateArray.push(coordinates[index][i][0]);
                            coordinateArray.push(coordinates[index][i][1]);
                        }

                    }
                    let outLinePositionArray = Cesium.Cartesian3.fromDegreesArray(coordinateArray);

                    let riverPolygon = viewer.scene.primitives.add(new Cesium.Primitive({
                        geometryInstances: new Cesium.GeometryInstance({
                            geometry: new Cesium.PolygonGeometry({
                                polygonHierarchy: new Cesium.PolygonHierarchy(outLinePositionArray),
                                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
                                height: 0,
                                extrudedHeight: 0
                            })
                        }),
                        appearance: new Cesium.EllipsoidSurfaceAppearance({
                            aboveGround: true
                        }),
                        show: true
                    }));
//增加水面效果
                    riverPolygon.appearance.material = new Cesium.Material({
                        fabric: {
                            type: 'Water',
                            uniforms: {
                                normalMap: '../water.jpg',
                                frequency: 1000.0,
                                animationSpeed: 0.01,
                                amplitude: 10.0
                            }
                        }
                    });

                },
旋转平移缩放模型
//声明3Dtiles实例
 selFloorModel = new Cesium.Cesium3DTileset({
            url: floorInfo[7],
            maximumScreenSpaceError: 1,
            preferLeaves: true,
          });
          selFloorModel.readyPromise
            .then(() => {
            //创建xyz旋转矩阵
              var mx = Cesium.Matrix3.fromRotationX(
                Cesium.Math.toRadians(floorInfo[3])
              );
              var my = Cesium.Matrix3.fromRotationY(
                Cesium.Math.toRadians(floorInfo[4])
              );
              var mz = Cesium.Matrix3.fromRotationZ(
                Cesium.Math.toRadians(floorInfo[5])
              );
              //计算上述旋矩阵的结果
              var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
              var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
              var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
              //平移 修改经纬度
              var position = Cesium.Cartesian3.fromDegrees(
                floorInfo[0],
                floorInfo[1],
                selFloorNum * 2.9
              );
              var m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
              //旋转、平移矩阵相乘
              Cesium.Matrix4.multiply(m, rotationX, m);
              Cesium.Matrix4.multiply(m, rotationY, m);
              Cesium.Matrix4.multiply(m, rotationZ, m);
              //缩放 修改缩放比例
              var pscale = Cesium.Matrix4.fromUniformScale(floorInfo[6]);
              Cesium.Matrix4.multiply(m, pscale, m);
              //赋值给tileset
              selFloorModel._root.transform = m;
              //最后添加到实体中
              cesiumScene.primitives.add(selFloorModel);
            })
            
获取当前视角信息

    getNowCamera: function () {
      //相机姿态
      var d = cesiumScene.camera;
      var heading = Cesium.Math.toDegrees(d.heading);
      var pitch = Cesium.Math.toDegrees(d.pitch);
      var roll = Cesium.Math.toDegrees(d.roll);

      let i = cesiumScene.camera.positionCartographic;
      let lat = Cesium.Math.toDegrees(i.latitude);
      let lng = Cesium.Math.toDegrees(i.longitude);
      return {
        heading: heading,
        pitch: pitch,
        roll: roll,
        centerx: lng,
        centery: lat,
        height: i.height,
      };
    },
绘制路线动态绘制,就是可以看到路线一点点画出
/******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description: 绘制轨迹路线
   */
  drawRoadLine(roadPosition) {
    let id = new Date().getTime();
    let arr = handlerRoadPath(roadPosition)
    // console.log(arr);
    let line = lineString(arr);
    /**计算规划的路径长度 */
    let roadLength = length(line, { units: 'meters' });
    /** 每秒100米的速度所需时间 */
    let time = Math.floor(roadLength / 100)
    if (time < 10) {
      time = "0" + time
    }
    let cartographicDegrees = handlerRoadPathTime(arr, time, 5 + 4)
    console.log(cartographicDegrees);
    let czml = [
      {
        id: "document",
        name: "CML Path" + id,
        version: "1.0",
        clock: {
          interval: `2012-08-04T10:00:00Z/2012-08-04T10:00:${time}Z`,
          currentTime: "2012-08-04T10:00:00Z",
          multiplier: 5,
          range: 'CLAMPED',
        },
      },
      {
        id: "path",
        name: "path wth GPS flight data" + id,
        availability: `2012-08-04T10:00:00Z/2012-08-04T10:00:${time}Z`,
        path: {
          material: {
            polylineOutline: {
              color: {
                rgba: [13, 188, 121, 255],
              },
              outlineColor: {
                rgba: [0, 255, 255, 255],
              },
              outlineWidth: 5,
            },
          },
          width: 10,
          leadTime: 0,
          resolution: 5,
        },
        billboard: {
          image: require('../../assets/images/billboardsImg/end.png'),
          eyeOffset: {
            cartesian: [0.0, 0.0, 0.0],
          },
          scale: 1.0
        },
        position: {
          epoch: "2012-08-04T10:00:00Z",
          cartographicDegrees: cartographicDegrees
        },
      },
    ];

    if (window.removeEntities) {
      viewer.dataSources.remove(window.removeEntities, true)
    }
    window.removeEntities = Cesium.CzmlDataSource.load(czml);
    viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)).then(function (ds) {
      window.removeEntities = ds;
      // 灵感记录
      // 如果要求不清除上一条路线,在czml加载完之后添加实体线 再清除czml
    });
  }
下面内容是为了方便作者本人日后开发copy使用,即项目初始化的一些操作封装
//
//Author: xingkang
//Date: 2022-11-14 14:25:53
//Description: 地图服务相关方法
//
/* eslint-disable */

import Vue from 'vue'
import { lineString, length } from '@turf/turf'
import './skyBox/skyBoxGround'
import { handlerRoadPath, handlerRoadPathTime } from '../../utils/data-handler/dataChange.js';
/******* 
 * @function: Class
 * @return {*}
 * @author: xk
 * @description: 初始化相关地图类
 */
export class InitMap {
  
  constructor(container, camera, imageryProvider) {
    // /**轨迹坐标 */
    // this.track=null;
    this.container = container;
    this.camera = camera;
    this.imageryProvider = imageryProvider;
    // console.log(viewer);
    
    // this.mapEvent();
  }
  /******* 
     * @function: function
     * @return {*}
     * @author: xk
     * @description: 初始化地图服务
     */
  initMap() {
    const viewer = new Cesium.Viewer(this.container, {
      animation: false, //是否显示动画控件
      shouldAnimate: true,
      homeButton: false, //是否显示Home按钮
      fullscreenButton: false, //是否显示全屏按钮
      baseLayerPicker: false, //是否显示图层选择控件
      geocoder: false, //是否显示地名查找控件
      timeline: false, //是否显示时间线控件
      sceneModePicker: false, //是否显示投影方式控件
      navigationHelpButton: false, //是否显示帮助信息控件
      infoBox: false, //是否显示点击要素之后显示的信息
      requestRenderMode: false, //启用请求渲染模式
      scene3DOnly: true, //每个几何实例将只能以3D渲染以节省GPU内存
      sceneMode: 3, //初始场景模式 1 2.5D模式 2 2D循环模式 3 3D模式  
      selectionIndicator: false,
      // imageryProvider: this.imageryProvider,
    });
    viewer.scene.imageryLayers.removeAll(); //清除所有底图,此时地球是黑色
    viewer.scene.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({ //添加自己要的底图
      // url: `${Vue.prototype.$MapURL}/{z}/{x}/{y}.png`,
      // url: `${Vue.prototype.$MapURL}/binzhou-tiandimap/{z}/{x}/{y}.png`,
      url:  Cesium.buildModuleUrl("binzhou-tiandimap/{z}/{x}/{y}.png"),
      // url:  "assets/binzhou-tiandimap/{z}/{x}/{y}.png",
      // url: "http://106.15.228.37:8016/mapAndModel/map/{z}/{x}/{y}.png",
      maximumLevel: 18,
      rectangle: new Cesium.Rectangle( //当用的是自己裁剪的部分地图瓦片时,cesium报错确实瓦片的解决办法,坐标是裁剪的瓦片右上角左下角
        Cesium.Math.toRadians(118.085747845851),
        Cesium.Math.toRadians(38.279797333631315),
        Cesium.Math.toRadians(118.16425201890883),
        Cesium.Math.toRadians(38.31052094315904),
      )
    }))


    viewer.scene.globe.baseColor=Cesium.Color.BLACK; //场景基础颜色

    viewer.scene.moon.show = false; //月亮显示
    viewer.scene.sun.show = false; //太阳显示
    viewer.scene.skyAtmosphere.show=false; //大气
    viewer.scene.light = new Cesium.DirectionalLight({ //平行光
      direction: new Cesium.Cartesian3(0.354925, -0.890918, -0.283358)
    })
    viewer.scene.skyBox = new Cesium.GroundSkyBox({ //近地天空盒,这里用的封装插件,cesium自带的,近地会有倾斜,博客有详解自行翻
      sources: {
        positiveX: require('./skyBox/Right.jpg'),
        negativeX: require('./skyBox/Left.jpg'),
        positiveY: require('./skyBox/Front.jpg'),
        negativeY: require('./skyBox/Back.jpg'),
        positiveZ: require('./skyBox/Up.jpg'),
        negativeZ: require('./skyBox/Down.jpg')
      }
    })

    // 启用地形遮挡
    viewer.scene.globe.depthTestAgainstTerrain = true;
    viewer._cesiumWidget._creditContainer.style.display = 'none';
    // 是否支持图像渲染像素化处理
    if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
      viewer.resolutionScale = window.devicePixelRatio;
    }
    //限制地图缩放级别
    // viewer.scene.screenSpaceCameraController.minimumZoomDistance = 10;
    // viewer.scene.screenSpaceCameraController.maximumZoomDistance = 10000;

    // 鼠标右键调整地图视角
    viewer.scene.screenSpaceCameraController.tiltEventTypes = [Cesium.CameraEventType.PINCH, Cesium.CameraEventType.RIGHT_DRAG];
    // 屏蔽Cesium的默认双击追踪选中entity行为
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

    // 开启抗锯齿
    viewer.scene.postProcessStages.fxaa.enabled = true;

    return viewer;
  }

  
/* 初始化相机视角 */
  setCameraView() {
    const { lng, lat, height, heading, pitch, roll } = this.camera;
    viewer.scene.camera.setView({
      destination: new Cesium.Cartesian3.fromDegrees(lng, lat, height),
      orientation: new Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll)
    });
  }

   // 湖面效果
  async init_xianRiver(coordinates) {
    let coordinateArray = [];

    for (let index = 0; index < coordinates.length; index++) {
        for (let i = 0; i < coordinates[index].length; i++) {
            coordinateArray.push(coordinates[index][i][0]);
            coordinateArray.push(coordinates[index][i][1]);
        }

    }
    let outLinePositionArray = Cesium.Cartesian3.fromDegreesArray(coordinateArray);

    let riverPolygon = viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: new Cesium.GeometryInstance({
            geometry: new Cesium.PolygonGeometry({
                polygonHierarchy: new Cesium.PolygonHierarchy(outLinePositionArray),
                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
                height: 1,
                extrudedHeight: 0
            })
        }),
        appearance: new Cesium.EllipsoidSurfaceAppearance({
            aboveGround: true
        }),
        show: true
    }));

    riverPolygon.appearance.material = new Cesium.Material({
        fabric: {
            type: 'Water',
            uniforms: {
              baseWaterColor: Cesium.Color.fromCssColorString("#57aabc"),
                normalMap: require('./water.jpg'),
                frequency: 1000.0,
                animationSpeed: 0.01,
                amplitude: 10.0
            }
        }
    });

}



  /******* 
     * @function: function
     * @return {*}
     * @author: xk
     * @description: 获取当前窗口地图的视角信息
     */
  getNowCamera() {
    //相机姿态
    const d = viewer.scene.camera;
    const heading = Cesium.Math.toDegrees(d.heading);
    const pitch = Cesium.Math.toDegrees(d.pitch);
    const roll = Cesium.Math.toDegrees(d.roll);

    const i = viewer.scene.camera.positionCartographic;
    const lat = Cesium.Math.toDegrees(i.latitude);
    const lng = Cesium.Math.toDegrees(i.longitude);
    return {
      heading: heading,
      pitch: pitch,
      roll: roll,
      centerx: lng,
      centery: lat,
      height: i.height
    };
  }

  /******* 
   * @function: function
   * @return {*}customDataSource
   * @author: xk
   * @description: 添加广告牌和标签
   */
  addBillOrLabel(imgUrl, position, cardId, type) {
    let a = viewer.entities.add({
      position: new Cesium.Cartesian3.fromDegrees(...position),
      cardId: cardId,
      type: type,
      billboard: {
        show: true,
        image: require("../../assets/images/billboardsImg/" + imgUrl),
        scale: 1.0,
        pixelOffset: new Cesium.Cartesian2(-86, -50),
        sizeInMeters: false,//控制以米为单位,缩放地图图片跟着缩放
        eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0),
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
      }
    });
    return a
  }
  /**
   * @description: 
   * @param {*} ent 实体
   * @param {*} options 可选 {
      duration: 3,	// 以秒为单位的飞行持续时间。
      maximumHeight: 2000,	// 飞行高峰时(切换视角时)的最大高度。
        offset : {
            heading : Cesium.Math.toRadians(0.0),	// 以弧度为单位的航向角。
            pitch : Cesium.Math.toRadians(-90),		// 以弧度为单位的俯仰角。
            range : 0								// 到中心的距离,以米为单位。
        }
    }
   * @return {*}
   */
  flyToEntity(ent,options = {duration: 3, maximumHeight: 2000}){
    viewer.flyTo(ent,options);
  }
  /******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description: 撒点方法
   */
  addBillboard(billboards) {
    /**存放实例对象*/
    let billboardArr = []
    billboards.forEach((item, index) => {
      /**每个撒点的实例对象 */
      let billEntits = viewer.entities.add({
        // position: new Cesium.Cartesian3.fromDegrees(item.longitude,item.latitude, 5),
        position: new Cesium.Cartesian3.fromDegrees(...item.position, 5),
        dangerInfo: item.dangerInfo || '',
        cardId: item.id,
        type: item.type || '',
        name: item.name || '',
        sonType: item.equipmentType || item.alarmType || '',
        dataDetail: item.type=="油气浓度监测"?item:'',
        selfItem: item,
        billboard: {
          show: true,
          image: require(`../../assets/images/billboardsImg/${item.imgUrl}`),
          scale: 1.0,
          // rotation:Cesium.Math.toRadians(90),
          pixelOffset: new Cesium.Cartesian2(-32, -60),
          sizeInMeters: false,//控制以米为单位,缩放地图图片跟着缩放
          eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0),
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
        },
      })
      billboardArr.push(billEntits)
    })
    viewer.zoomTo(billboardArr[0])
    return billboardArr;
  }
  /******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description: 应急资源显示名称和数量
   */
  addBillAndLabel(item) {
    let ent = viewer.entities.add({
      // position: new Cesium.Cartesian3.fromDegrees(118.12409366132542, 38.295807227591624, 5),
      position: new Cesium.Cartesian3.fromDegrees(...item.position, 5),
      // sonType: item.equipmentType || item.alarmType || '',
      
      billboard: {
        show: true,
        width: `${item.name}${item.number}(数量)`.length * 18,
        image: require("../../assets/images/infoBoxIcon/ssmalbox_blue.png"),
        scale: 1.0,
        // rotation:Cesium.Math.toRadians(90),
        pixelOffset: new Cesium.Cartesian2(-(`${item.name}${item.number}(数量)`.length * 18 / 2), -150),
        sizeInMeters: false,//控制以米为单位,缩放地图图片跟着缩放
        eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0),
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
      },
      label: {
        show: true,
        text: `${item.name}${item.number} (数量)`,
        font: "16px Helvetica",
        fillColor: Cesium.Color.WHITE,
        // showBackground: true,
        // backgroundColor: Cesium.Color.BLACK.withAlpha(1),
        pixelOffset: new Cesium.Cartesian2(0, -152),
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
      }
    })
    return ent;

  }
  /******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description:添加建筑标签 
   */
  addLabel() {
    viewer.entities.add({
      position: new Cesium.Cartesian3.fromDegrees(...position),
      type: 'building',
      label: {
        show: true,
        text: text,
        font: "14px Helvetica",
        fillColor: Cesium.Color.WHITE,
        showBackground: true,
        backgroundColor: Cesium.Color.BLACK
      }
    })

  }

  /******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description: 展示应急路线
   */
  addline(config) {
    const entities = []
    config.forEach(item => {
      let ent = viewer.entities.add({
        cardId: item.id,
        type: item.type,
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights(item.positions),
          width: 20,
          material: new Cesium.PolylineArrowMaterialProperty(
            Cesium.Color.RED
          )
        }
      })
      entities.push(ent)
    })
    return entities;
  }
  /*******  118.12613093609299,38.29631968546674
   * @function: function
   * @return {*}nodelurl 模型地址
   * @author: xk
   * @description: 添加模型
   */
  async addModel(modelInfo,viewer) {
    let { position, heading, modelUrl, pitch, roll, scale = 1.0 } = modelInfo;
    let area = new Cesium.Cartesian3.fromDegrees(...position);
    let hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(heading), Cesium.Math.toRadians(pitch), Cesium.Math.toRadians(roll));
    let orientation = Cesium.Transforms.headingPitchRollToFixedFrame(area, hpr);
    let modelMatrix = orientation
    let model = Cesium.Model.fromGltf({
      url:  modelUrl,
      // url: `${Vue.prototype.$ModelURL}${modelUrl}`,
      modelMatrix: modelMatrix,
      scale: scale
    });
    const modelObj = viewer.scene.primitives.add(model);
    return modelObj
  }
  /******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description: 绘制轨迹路线
   */
  drawRoadLine(roadPosition) {
    let id = new Date().getTime();
    let arr = handlerRoadPath(roadPosition)
    // console.log(arr);
    let line = lineString(arr);
    /**计算规划的路径长度 */
    let roadLength = length(line, { units: 'meters' });
    /** 每秒100米的速度所需时间 */
    let time = Math.floor(roadLength / 100)
    if (time < 10) {
      time = "0" + time
    }
    let cartographicDegrees = handlerRoadPathTime(arr, time, 5 + 4)
    // console.log(cartographicDegrees);
    let czml = [
      {
        id: "document",
        name: "CML Path" + id,
        version: "1.0",
        clock: {
          interval: `2012-08-04T10:00:00Z/2012-08-04T10:00:${time}Z`,
          currentTime: "2012-08-04T10:00:00Z",
          multiplier: 5,
          range: 'CLAMPED',
        },
      },
      {
        id: "path",
        name: "path wth GPS flight data" + id,
        availability: `2012-08-04T10:00:00Z/2012-08-04T10:00:${time}Z`,
        path: {
          material: {
            polylineOutline: {
              color: {
                rgba: [13, 188, 121, 255],
              },
              outlineColor: {
                rgba: [0, 255, 255, 255],
              },
              outlineWidth: 5,
            },
          },
          width: 10,
          leadTime: 0,
          resolution: 5,
        },
        billboard: {
          image: require('../../assets/images/billboardsImg/end.png'),
          eyeOffset: {
            cartesian: [0.0, 0.0, 0.0],
          },
          scale: 1.0
        },
        position: {
          epoch: "2012-08-04T10:00:00Z",
          cartographicDegrees: cartographicDegrees
        },
      },
    ];

    if (window.removeEntities) {
      viewer.dataSources.remove(window.removeEntities, true)
    }
    window.removeEntities = Cesium.CzmlDataSource.load(czml);
    viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)).then((ds)=> {
      window.removeEntities = ds;
      this.setCameraView()
      // viewer.trackedEntity = ds.entities.getById("path");
      // 获取当前地图瓦片级别
      // setTimeout(() => {
      //   console.log(time);
      //   viewer.camera.zoomOut(1000);
      // }, 3000);
      // 灵感记录
      // 如果要求不清除上一条路线,在czml加载完之后添加实体线 再清除czml
    });
  }
  /******* 
   * @function: function
   * @return {*}
   * @author: xk
   * @description: 周界线 
   */
  boundaryAround(positions) {
    let flog = true;
    let x = 1;
    let entities = []
    positions.forEach(item => {

      let ent = viewer.entities.add({
        type: item.type,
        cardId: item.id,
        corridor: {
          positions: new Cesium.Cartesian3.fromDegreesArray(item.positions),
          width: 7,
          height: 1,
          extrudedHeight: 20,
          material: Cesium.Color.RED.withAlpha(0.5)
          // new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(function () {
          //   if (flog) {
          //     x = x - 0.05;
          //     if (x <= 0) {
          //       flog = false;
          //     }
          //   } else {
          //     x = x + 0.05;
          //     if (x >= 1) {
          //       flog = true;
          //     }
          //   }
          //   return Cesium.Color.RED.withAlpha(x);
          // }, false))
        },
      });
      entities.push(ent)
    })
    return entities;
  }



}
绘制渐变色线条
//typescript 自行修改为js
getColorRamp(elevationRamp:Array<number>, isVertical:boolean = true) {
    const ramp = document.createElement('canvas');
    ramp.width = isVertical ? 1 : 100;
    ramp.height = isVertical ? 100 : 1;
    const ctx = ramp.getContext('2d');

    const values = elevationRamp;
    if (ctx) {

      const grd = isVertical ? ctx.createLinearGradient(0, 0, 0, 100) : ctx.createLinearGradient(0, 0, 100, 0);
      grd.addColorStop(values[0], '#ffff00');
      grd.addColorStop(values[1], '#ff0000');
      grd.addColorStop(values[2], '#00FF7E');
      ctx.globalAlpha = 0.3;
      ctx.fillStyle = grd;
      if (isVertical)
        ctx.fillRect(0, 0, 1, 100);
      else
        ctx.fillRect(0, 0, 100, 1);
      return ramp;
    }
  }
  addline(lineInfo: LineInfo) {
    const { position, width, color } = lineInfo;
    let lineColor = Cesium.Color.WHITE;
    const entities = this.viewer.entities.add({
      polyline: {
        // fromDegrees返回给定的经度和纬度值数组(以度为单位),该数组由Cartesian3位置组成。
        // Cesium.Cartesian3.fromDegreesArray([经度1, 纬度1, 经度2, 纬度2,])
        // Cesium.Cartesian3.fromDegreesArrayHeights([经度1, 纬度1, 高度1, 经度2, 纬度2, 高度2])
        positions: new Cesium.Cartesian3.fromDegreesArray(position),
        // 宽度
        width: width,
        // 线的颜色
        material: new Cesium.ImageMaterialProperty({
          image: this.getColorRamp([0.1, 0.5, 1.0], false),
          repeat: new Cesium.Cartesian2(1.0, 1),
          transparent: false,
        }),
        // material: lineColor,
        // 线的顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
        // zIndex: 10,
        // 显示在距相机的距离处的属性,多少区间内是可以显示的
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        // 是否显示
        show: true
      }
    })
    return entities;
  }

在这里插入图片描述

cesium 防止billboard label被模型覆盖问题

为防止billboard被3dtiles模型覆盖,可在billboard参数中设置disableDepthTestDistance参数,来禁止billboard的深度检测,如下:

disableDepthTestDistance: Number.POSITIVE_INFINITY

Number.POSITIVE_INFINITY:代表无穷大,即一直禁用深度检测

cesium 聚合方法封装
const dataSourcePromise = this.viewer.dataSources.add(dataSource);

//聚合方法 culsterImage:聚合图标
culsterDatasource(dataSourcePromise,culsterImage){
    
    dataSourcePromise.then(function (dataSource) {
      const pixelRange =30;  //聚合范围
      const minimumClusterSize = 3;  //3个开始聚合
      const enabled = true; 
     
      dataSource.clustering.enabled = enabled; //聚合开启
      dataSource.clustering.pixelRange = pixelRange; //设置像素范围,以扩展显示边框
      dataSource.clustering.minimumClusterSize = minimumClusterSize; //设置最小的聚合点数目,超过此数目才能聚合
     
      let removeListener;
     
      customStyle();
      
      function customStyle() {
        if (Cesium.defined(removeListener)) {
          removeListener();
          removeListener = undefined;
        } else {
          removeListener = dataSource.clustering.clusterEvent.addEventListener(
            function (clusteredEntities, cluster) {
              cluster.label.show = true;
              cluster.billboard.show = true;
              cluster.billboard.id = cluster.label.id;
              cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
              cluster.billboard.image = culsterImage;
              cluster.label.showBackground=true;//背景颜色开关
              // cluster.label.backgroundColor=Cesium.Color.RED;//背景颜色设置
              cluster.label.verticalOrigin = Cesium.VerticalOrigin.CENTER;//垂直位置
              cluster.label.horizontalOrigin = Cesium.HorizontalOrigin.CENTER//水平位置
              cluster.label.eyeOffset = new Cesium.Cartesian3(0.0, 0.0, 100);
              cluster.label.pixelOffset = new Cesium.Cartesian2(15, -100),
              cluster.label.fillColor = Cesium.Color.WHITE
              cluster.label.font = "20px Helvetica"
              if (clusteredEntities.length >= 50) {
                cluster.label.text = '50+'
              } else if (clusteredEntities.length >= 40) {
                cluster.label.text = '40+'
              } else if (clusteredEntities.length >= 30) {
                cluster.label.text = '30+'
              } else {
                cluster.label.text = String(clusteredEntities.length);
              }
            }
          );
        }
     
        // force a re-cluster with the new styling
        const pixelRange = dataSource.clustering.pixelRange;
        dataSource.clustering.pixelRange = 0;
        dataSource.clustering.pixelRange = pixelRange;
      }
    })
  }
雾天效果

官方案例 :https://sandcastle.cesium.com/?src=Fog%20Post%20Process.html

改成白色即可 fogColor: Cesium.Color.WHITE,
在这里插入图片描述

  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LBY_XK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值