Cesium模型设置

一、外部模型

1、GLTF文件
createModel() {  
  //设置模型经纬度和高度,参数依次为经度、纬度、高度
  const position = Cesium.Cartesian3.fromDegrees(110, 30, 100000);
  //模型朝向
  const heading = Cesium.Math.toRadians(135);
  const pitch = 0;
  const roll = 0;
  const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  const orientation = Cesium.Transforms.headingPitchRollQuaternion(
    position,
    hpr
  );

  const entity = viewer.entities.add({
    name: "model", // 模型名称
    position: position, // 模型位置,高度
    orientation: orientation,
    model: {
      uri: "model.GLTF", // 模型文件路径
      minimumPixelSize: 128, // 模型最小像素大小
      maximumScale: 20000, // 模型最大像素大小
    },
  });

  // 相机定位到模型位置
  viewer.trackedEntity = entity;
},

二、绘制模型

1、绘制点位
createPoint() {
  viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(100,30,,1000),
    point: {
      pixelSize: 5,
      // 点位颜色,fromCssColorString 可以直接使用CSS颜色
      color: Cesium.Color.fromCssColorString("#ee0000"),
      // 边框颜色
      outlineColor: Cesium.Color.fromCssColorString("#fff"),
      // 边框宽度(像素)
      outlineWidth: 2,
      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        0,
        15000000
      ),
    },
  });
},

2、绘制线条
(1)绘制实线
createLine() {
  // 绘制实线
  viewer.entities.add({
    polyline: {
      // fromDegrees返回给定的经度和纬度值数组(以度为单位),该数组由Cartesian3位置组成。
      // 参数依次为[经度1, 纬度1, 经度2, 纬度2]
      // Cesium.Cartesian3.fromDegreesArray
      // 参数依次为[经度1, 纬度1, 高度1, 经度2, 纬度2, 高度2]
      positions: Cesium.Cartesian3.fromDegreesArrayHeights([110,30,100000,111,34,100000]),
      // 注:线条起止,可以获取鼠标点击位置的经纬度进行线条绘制
      // 宽度
      width: 5,
      // 线的颜色
      material: Cesium.Color.fromCssColorString("#ee0000"),
      // 线的顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
      zIndex: 999,
      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        0,
        15000000
      ),
      // 是否显示
      show: true,
   },
  });
},

(2)绘制虚线
createLine() {
  //绘制虚线
  viewer.entities.add({
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArrayHeights([110,30,100000,111,34,100000]),
      // 宽度
      width: 3,
      // 虚线短划线长度
      material: new Cesium.PolylineDashMaterialProperty({
        color: Cesium.Color.YELLOW,
        dashLength: 20, //短划线长度
      }),
      // 线的顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
      zIndex: 999,
      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        0,
        15000000
      ),
      // 是否显示
      show: true,
    },
  });
},

(3)绘制其他样式线条
// 直线
function lineA(){
  var polylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );

  polylines.add({
    positions: Cesium.PolylinePipeline.generateCartesianArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        103.0, 30.0, 103.5, 30.0,
      ]),
    }),
    material: Cesium.Material.fromType("Color", {
      color: new Cesium.Color(5.0, 0, 0, 1.0),
    }),
  });
}


// z字形线条
function lineB(){
  var polylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );
  
  polylines.add({
    positions: Cesium.PolylinePipeline.generateCartesianArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        -105.0, 40.0, -100.0, 38.0, -105.0, 35.0, -100.0, 32.0,
      ]),
    }),
    material: Cesium.Material.fromType(
      Cesium.Material.PolylineOutlineType,
      {
        outlineWidth: 5.0,
      }
    ),
    width: 10.0,
  });
}


// 荧光线条-由粗变细
function lineC(){
  var polylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );

  polylines.add({
    positions: Cesium.PolylinePipeline.generateCartesianArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        103.0, 30.0, 103.5, 30.0,
      ]),
    }),
    material: Cesium.Material.fromType(Cesium.Material.PolylineGlowType, {
      glowPower: 0.2,
      taperPower: 0.2,
      color: new Cesium.Color(1.0, 0.5, 0.0, 1.0),
    }),
    width: 10.0,
  });
}


// 菱形
function lineD(){
  var polylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );

  polylines.add({
    positions: Cesium.PolylinePipeline.generateCartesianArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        -105.0, 30.0, -105.0, 25.0, -100.0, 22.0, -100.0, 28.0,
      ]),
    }),
    width: 3.0,
    loop: true,
  });
}


//线的末尾有箭头效果
function lineEOne(){
  var localPolylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );
  
  localPolylines.add({
    material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
      color: Cesium.Color.CYAN,
    }),
  
    //Rhumb同向线,弧线切线方向都是一致的;若拿着罗盘针的话,航线都是一致的
    positions: Cesium.PolylinePipeline.generateCartesianRhumbArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        103.962, 30.737, 103.963, 30.738,
      ]),
    }),
    width: 20.0,
  });
}

//线的末尾有箭头效果
function lineETwo(){
  var entity = viewer.entities.add({
    polyline: {
        positions: [
          Cesium.Cartesian3.fromDegrees(103.962, 30.737),
          Cesium.Cartesian3.fromDegrees(103.962, 30.738),
        ],
        width: 20,
        material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.CYAN),
        vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
      },
  });
}


// 有高度的荧光拖尾线条
function lineF(){
  var polylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );
  
  polylines.add({
    positions: Cesium.PolylinePipeline.generateCartesianArc({
      positions: Cesium.Cartesian3.fromDegreesArrayHeights([
        103.0, 30.0, 100, 103.5, 30.0, 100,
      ]),
    }),
    width: 5,
    material: Cesium.Material.fromType(Cesium.Material.FadeType, {
      repeat: false,
      fadeInColor: Cesium.Color.CYAN,
      fadeOutColor: Cesium.Color.CYAN.withAlpha(0),
      time: new Cesium.Cartesian2(0.0, 0.0),
      fadeDirection: {
        x: true,
        y: false,
      },
    }),
  });
}


// 直线
function lineG(){
  var polylines = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
  );
  
  polylines.add({
    positions: Cesium.PolylinePipeline.generateCartesianRhumbArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        103.0, 30.0, 103.5, 30.0,
      ]),
    }),
    width: 5,
    material: Cesium.Material.fromType("Color", {
      color: new Cesium.Color(0.0, 1.0, 0.0, 1.0),
    }),
  });
}

(4)设置箭头线条方向
// npm i @turf/turf
// import * as turf from "@turf/turf";


// 添加箭头
addArrow() {
  let arr = [0, 45, 90, 135, 180, -135, -90, -45];
  var pixelOffset, endPs, entity, labelEntity;
  arr.forEach((item) => {
    // 计算箭头结束点
    endPs = this.calcArrowEndPosition([103.9621, 30.7368], 0.1, item);

    entity = viewer.entities.add({
      polyline: {
        name: "arrow",
        positions: [
          Cesium.Cartesian3.fromDegrees(103.9621, 30.7368),
          Cesium.Cartesian3.fromDegrees(endPs.lon, endPs.lat),
        ],
        width: 10,
        material: new Cesium.PolylineArrowMaterialProperty(
          Cesium.Color.CYAN
        ),
        vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
      },
      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        0,
        15000000
      ),
    });

    // 调整label偏移位置
    if (item == 45 || item == -45 || item == 0) {
      pixelOffset = new Cesium.Cartesian2(0, -10);
    } else if (item == 135 || item == -135 || item == 180) {
      pixelOffset = new Cesium.Cartesian2(0, 10);
    } else if (item == 90) {
      pixelOffset = new Cesium.Cartesian2(20, 0);
    } else if (item == -90) {
      pixelOffset = new Cesium.Cartesian2(-20, 0);
    }

    // 创建标签实体
    labelEntity = viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(endPs.lon, endPs.lat), // 点位坐标
      point: {
        pixelSize: 0, // 点位大小
        color: Cesium.Color.WHITE.withAlpha(0), // 点位颜色,透明
      },
      label: {
        text: `${item}度`, // 文本内容
        font: "18px monospace", // 字体样式
        style: Cesium.LabelStyle.FILL_AND_OUTLINE, // label样式
        outlineWidth: 2, // 外边框宽度
        verticalOrigin: Cesium.VerticalOrigin.CENTER, // 文字对齐方式BOTTOM,TOP,CENTER
        pixelOffset: pixelOffset, // (0:经度偏移,0:纬度偏移)
      },
    });
    labelEntity.label.fillColor = Cesium.Color.WHITE; // 设置填充颜色为白色
    labelEntity.label.outlineColor = Cesium.Color.RED; // 设置轮廓颜色为红色
  });
},


// 计算箭头结束点
calcArrowEndPosition(ps, range, angel) {
  var pt = turf.point(ps, { "marker-color": "F00" }); // 起始点
  var distance = range; // 距离
  var bearing = angel; // 角度
  var options = { units: "miles" }; // 英里
  var destination = turf.rhumbDestination(pt, distance, bearing, options);

  return {
    lon: destination.geometry.coordinates[0],
    lat: destination.geometry.coordinates[1],
  };
},

三、删除模型

1、根据ID删除
viewer.entities.removeById(id);

2、根据实体删除
// 根据id获取实体
let entities = viewer.entities.getById(id);

// 删除实体
viewer.entities.remove(entities);

3、删除所有
viewer.entities.removeAll();

四、模型设置

1、模型运动
function update() {
    // var time = Date.now();
    
    // 计算模型当前的经度、纬度和高度
    var longitude = ...; // 经度
    var latitude = ...; // 纬度
    var height = ...; // 高度
    
    // 将经度、纬度和高度转换成Cesium的Cartesian3类型
    var cartesianPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
    
    // 更新模型的位置属性
    entity.position = cartesianPosition;
}
 
// 开始动画循环
setInterval(update, 1000 / 60); // 每秒调用60次update函数

2、选中模型选中样式
clickModel(id){
  // 获取模型的实体
  let entities = viewer.entities.getById(id);
  // 修改模型颜色
  entities.model.color = Cesium.Color.RED;
}

3、模拟飞行
(1)飞行数据
data() {
    return {
      // ----------------------<<地图>>----------------------
      // cesium相机初始位置
      ps: {
        lon: 103,
        lat: 30,
        height: 1000,
      },
      // 飞行时间
      flyTime: 0,
      // 点位数组
      pointArr: [
        {
          lon: 103.957787,
          lat: 30.739748,
          height: 100,
          time: 0,
        },
        {
          lon: 103.959787,
          lat: 30.739748,
          height: 100,
          time: 5,
        },
        {
          lon: 103.961787,
          lat: 30.739748,
          height: 100,
          time: 10,
        },
        {
          lon: 103.963787,
          lat: 30.739748,
          height: 100,
          time: 15,
        },
        {
          lon: 103.965787,
          lat: 30.739748,
          height: 100,
          time: 20,
        },
        {
          lon: 103.965787,
          lat: 30.737748,
          height: 100,
          time: 15,
        },
        {
          lon: 103.965787,
          lat: 30.735748,
          height: 100,
          time: 25,
        },
        {
          lon: 103.965787,
          lat: 30.733748,
          height: 100,
          time: 30,
        },
        {
          lon: 103.963787,
          lat: 30.733748,
          height: 100,
          time: 35,
        },
        {
          lon: 103.961787,
          lat: 30.733748,
          height: 100,
          time: 35,
        },
        {
          lon: 103.959787,
          lat: 30.733748,
          height: 100,
          time: 35,
        },
        {
          lon: 103.957787,
          lat: 30.733748,
          height: 100,
          time: 35,
        },
        {
          lon: 103.957787,
          lat: 30.735748,
          height: 100,
          time: 35,
        },
        {
          lon: 103.957787,
          lat: 30.737748,
          height: 100,
          time: 35,
        },
        {
          lon: 103.957787,
          lat: 30.739748,
          height: 100,
          time: 35,
        },
      ],
      // 线条数组
      lineArr: [],
      // 起始时间
      start: "",
      // 结束时间
      stop: "",
    };
},

(2)绘制坐标点
addPoint(ps) {
  // 添加点位
  viewer.entities.add({
    name: "point", // 所属的父级id
    position: Cesium.Cartesian3.fromDegrees(
      ps.lon,
      ps.lat,
      ps.height // 高度可以自己定义,也可以根据传进来的高度进行绘制
    ),
    point: {
      pixelSize: 5,
      // 点位颜色,fromCssColorString 可以直接使用CSS颜色
      color: Cesium.Color.fromCssColorString("tomato"),
      // 边框颜色
      outlineColor: Cesium.Color.fromCssColorString("#fff"),
      // 边框宽度(像素)
      outlineWidth: 2,
      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        0,
        15000000
      ),

      // 是否开启深度监测
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
    },
  });
},

(3)绘制航线
addLine() {
  if (this.lineArr.length == 0) {
    return;
  }

  // 航迹线id
  let id = `line`;

  viewer.entities.add({
    id, //  模型id
    name: "line", // 所属的父级id
    // polyline 折线
    polyline: {
      // 参数依次为[经度1, 纬度1, 高度1, 经度2, 纬度2, 高度2]
      positions: Cesium.Cartesian3.fromDegreesArrayHeights(this.lineArr),
      // 注:线条起止,可以获取鼠标点击位置的经纬度进行线条绘制

      // 宽度
      width: 2,

      // 线的颜色
      material: Cesium.Color.fromCssColorString("tomato"), //  "tomato"

      clampToGround: false, // 不紧贴地面

      // 线的顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
      zIndex: 999,

      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        0,
        15000000
      ),

      // 是否显示
      show: true,
    },
  });
},

(4)生成航迹
addTrack() {
  // 创建航迹点
  for (let i = 0; i < this.pointArr.length; i++) {
    // 绘制点位
    this.addPoint({
      lon: this.pointArr[i].lon,
      lat: this.pointArr[i].lat,
      height: this.pointArr[i].height,
    });

    // 存储点位绘制航迹
    this.lineArr.push(
      this.pointArr[i].lon,
      this.pointArr[i].lat,
      this.pointArr[i].height
    );
  }

  // 绘制航迹
  this.addLine();
},

(5)创建模型
addModels() {
  this.isCreate = true;
  // 计算时间飞行数据
  let property = this.computeFlight(this.pointArr);

  // ++++++++++<<创建模型>>++++++++++
  const entity = viewer.entities.add({
    id: `testModel`, //模型id
    name: "model", // 模型名称,这里用作模型类型,方便场景模型增删改查
    // 和时间轴关联
    availability: new Cesium.TimeIntervalCollection([
      new Cesium.TimeInterval({
        start: this.start,
        stop: this.stop,
      }),
    ]),
    position: property, //模型位置,高度
    orientation: new Cesium.VelocityOrientationProperty(property),
    model: {
      uri: "./Cesium/model/air/test1.gltf", //模型文件
      minimumPixelSize: 80, //模型最小像素大小
      maximumScale: 100, //模型最大像素大小
    },
  });
},

(6)移动模型
modelMove() {
  if (this.lineArr.length == 0) {
    return;
  }

  for (let i = 0; i < this.pointArr.length; i++) {
    this.pointArr[i].time = this.flyTime;

    this.flyTime += 3;
  }

  // 起始时间
  this.start = Cesium.JulianDate.fromDate(new Date());
  // 结束时间
  this.stop = Cesium.JulianDate.addSeconds(
    this.start,
    this.pointArr[this.pointArr.length - 1].time,
    new Cesium.JulianDate()
  );

  // 设置始时钟始时间
  viewer.clock.startTime = this.start.clone();
  // 设置时钟当前时间
  viewer.clock.currentTime = this.start.clone();
  // 设置始终停止时间
  viewer.clock.stopTime = this.stop.clone();
  // 时间速率,数字越大时间过的越快
  viewer.clock.multiplier = 1;
  // 时间轴
  viewer.timeline.zoomTo(this.start, this.stop);
  // 循环执行,即为2,到达终止时间,重新从起点时间开始LOOP_STOP
  // viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
  viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;

  // 创建模型
  this.addModels();
},

(7)计算飞行
computeFlight(source) {
  // 取样位置 相当于一个集合
  let property = new Cesium.SampledPositionProperty();
  for (let i = 0; i < source.length; i++) {
    let time = Cesium.JulianDate.addSeconds(
      this.start,
      source[i].time,
      new Cesium.JulianDate()
    );
    let position = Cesium.Cartesian3.fromDegrees(
      source[i].lon,
      source[i].lat,
      source[i].height
    );
    // 添加位置,和时间对应
    property.addSample(time, position);
  }
  return property;
},

(8)方法执行顺序
mounted() {
  // 绘制航迹
  this.addTrack();
  // 飞机飞行
  this.modelMove();
},

4、模型添加弹框
(1)地图组件代码
<template>
  <div id="cesiumContainer">
    <!-- 模型信息弹窗 -->
    <Popup
      ref="Popup"
      :popupInfo="popupInfo"
      :popupPs="popupPs"
      @message="popupMsg"></Popup>
  </div>
</template>

(2)添加模型
addModel(info) {
  if (viewer.entities.getById(info.desc.id)) {
    return;
  }

  // 转换笛卡尔空间直角坐标
  const position = new Cesium.Cartesian3.fromDegrees(
    info.desc.position.lon,
    info.desc.position.lat,
    info.desc.position.height
  );

  //模型朝向
  const heading = Cesium.Math.toRadians(0);
  const pitch = 0;
  const roll = 0;
  const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  const orientation = Cesium.Transforms.headingPitchRollQuaternion(
    position,
    hpr
  );

  // ++++++++++<<创建模型>>++++++++++
  const entity = viewer.entities.add({
    id: info.desc.id, //模型id
    name: info.type, // 模型名称,这里用作模型类型,方便场景模型增删改查
    position: position, //模型位置,高度
    orientation: orientation,
    model: {
      uri: info.desc.path, //模型文件
      minimumPixelSize: 80, //模型最小像素大小
      maximumScale: 100, //模型最大像素大小
    },
    color: Cesium.Color.WHITE,
    description: info.desc, // 模型详情数据可以添加到description属性上
  });
},

(3)添加左键点击事件
leftClick() {
  // 添加用户输入监听范围(element)
  let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  // 处理用户输入事件
  handler.setInputAction((event) => {
    let pick = viewer.scene.pick(event.position);

    if (Cesium.defined(pick)) {
      // 选中模型id
      this.selModelId = pick.id._id;

      // 获取模型信息
      this.popupInfo = JSON.parse(
        JSON.stringify(pick.id._description._value)
      );

      // 获取cartesian3坐标
      const cartesian3 = pick.id._position._value;

      // cartesian3转换为cartesian2坐标(屏幕坐标)
      this.popupPs = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
        viewer.scene,
        cartesian3
      );
    } else {
      this.cancelPopup();
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
},

(4)popup组件代码
<template>
  <div
    class="cesiumPopup"
    :style="{ top: popupPs.y + 'px', left: popupPs.x + 'px' }"
    v-if="show">
    <!-- 头部 -->
    <ul class="head">
      <li>
        <span>模型信息</span>
      </li>
      <li>
        <span class="el-icon-close" @click="closePopup"></span>
      </li>
    </ul>

    <!-- 模型内容 -->
    <ul class="content">
      <li>
        <span class="subTitle">模型标识</span>
        <span class="subValue">{{ popupInfo.id }}</span>
      </li>
      <li>
        <span class="subTitle">模型名称</span>
        <span class="subValue">{{ popupInfo.name }}</span>
      </li>
      <li>
        <span class="subTitle">模型地址</span>
        <span class="subValue">{{ popupInfo.ip }}</span>
      </li>
      <li>
        <span class="subTitle">模型端口</span>
        <span class="subValue">{{ popupInfo.port }}</span>
      </li>
      <li>
        <span class="subTitle">模型位置</span>
        <span class="subValue">{{
          `${filterNumber(popupInfo.position.lon, 6)},${filterNumber(
            popupInfo.position.lat,
            6
          )},${popupInfo.position.height}`
        }}</span>
      </li>
      <li>
        <span class="subTitle">模型状态</span>
        <span
          class="subValue"
          :style="popupInfo.status == 1 ? 'color:#04F44C' : 'color:#F52E2E'"
          >{{ popupInfo.status == 1 ? "正常" : "异常" }}</span
        >
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "Popup",
  components: {},
  props: {
    popupInfo: {
      type: Object,
      default: () => {
        return {
          id: "",
          position: {
            lon: "",
            lat: "",
            alt: "",
          },
          status: "",
          ip: "",
          isSelect: "",
          name: "",
          port: "",
        };
      },
    },
    popupPs: {
      type: Object,
      default: () => {
        return {
          x: 0,
          y: 0,
        };
      },
    },
  },
  data() {
    return {
      show: false,
    };
  },
  computed: {},
  created() {},
  mounted() {},
  methods: {
    // 打开弹框
    openPopup() {
      this.show = true;
    },

    // 关闭弹框
    closePopup() {
      this.show = false;
    },

    // 过滤数据
    filterNumber(val, digit) {
      return val.toFixed(digit);
    },
  },
};
</script>

<style lang="less" scoped>
.cesiumPopup {
  min-width: 300px;
  position: absolute;
  transform: translate(-50%, -130%);
  z-index: 1;
  background-color: rgba(#001c22, 0.8);
  color: #fff;
  font-size: 12px;
  box-sizing: border-box;

  .head {
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: #048197;
    padding: 0px 10px;
    box-sizing: border-box;
    box-shadow: inset -2px 0px 2px rgba(#333, 0.5),
      inset 2px 2px 2px rgba(#fff, 0.5);

    .el-icon-close {
      font-size: 16px;
      cursor: pointer;

      &:hover {
        color: tomato;
      }
    }
  }

  .content {
    height: 85%;
    padding: 10px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    box-shadow: inset -2px -2px 2px rgba(#333, 0.5),
      inset 2px 0px 2px rgba(#5696a2, 0.7);

    li {
      margin: 5px 0px;
      display: flex;
      align-items: center;

      .subTitle {
        width: 20%;
        display: inline-block;
        background-color: #013946;
        border: 1px solid #119ea0;
        margin-right: 5px;
        padding: 1px 5px;
      }
      .subValue {
        width: 80%;
        display: inline-block;
        border: 1px solid #119ea0;
        box-sizing: border-box;
        padding: 1px 5px;
      }
    }
  }
}
</style>

(5)弹框跟随模型移动
// 更新信息弹框位置
updatePopup() {
  // 获取选中模型
  if (!this.selModelId) {
    return;
  }

  let entities = viewer.entities.getById(this.selModelId);

  this.popupPs = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
    viewer.scene,
    entities._position._value
  );
},



// 地图缩放事件
setWheelEvent() {
  let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  // 处理用户输入事件
  handler.setInputAction((event) => {
    // 更新弹框位置
    this.updatePopup();
  }, Cesium.ScreenSpaceEventType.WHEEL);
},


// 地图拖拽
setMouseEvent() {
  let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  // *****注册鼠标右键按下事件*****
  handler.setInputAction((event) => {
    let pick = viewer.scene.pick(event.position);

    // *****注册鼠标移动事件*****
    viewer.screenSpaceEventHandler.setInputAction((arg) => {
      // 更新弹框位置
      this.updatePopup();
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    // *****注册鼠标抬起事件*****
    viewer.screenSpaceEventHandler.setInputAction(({ position }) => {
      // *****解除viewer的MOUSE_MOVE事件监听器*****
      viewer.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.MOUSE_MOVE
      );

      // 解除相机锁定
      viewer.scene.screenSpaceCameraController.enableZoom = true;
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
  }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
},



// ***在初始化地图的时候加上如下配置***
// 相机移动事件
viewer.scene.camera.moveEnd.addEventListener(this.updatePopup);
// 注册地图缩放事件
this.setWheelEvent();
// 注册地图拖拽事件
this.setMouseEvent();

5、添加图片
(1)billboard添加图片
添加图片
viewer.entities.add({
  // name: "point", // 所属的父级id
  position: Cesium.Cartesian3.fromDegrees(
    103.962,
    30.737,
    100 // 高度可以自己定义,也可以根据传进来的高度进行绘制
  ),
  billboard: {
    image: Arrow, // 图片路径
    width: 50.0, // 图片宽度,可选
    height: 500.0, // 图片高度,可选
    // 设置方位(相对北方) 0表示东,90表示北,180表示西,270表示南
    horizontalOrigin: 0,
    // 设置俯仰角度(相对地面),0表示垂直向上,-90表示垂直向下
    verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直居中
    // 可选属性:调整俯仰角度
    pitch: Cesium.Math.toRadians(-90.0), // 将俯仰角度设置为-90度
  },
});

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值