Cesium地图常用方法封装

1、创建mapFunction.js文件

export class mapFunction {
  constructor(viewer, Cesium) {
    this.viewer = viewer
    this.Cesium = Cesium
  }

  // 根据ID查询Entity模型
  /**
   * 函数用途:根据ID查询Entity模型
   * 参数注释:
   * @param {String} id - 模型ID
   * @returns Entity实体 - 返回查询结果
   */
  findEntityById(id) {
    let entity = this.viewer.entities.getById(id);
    return entity
  }

  /**
   * 函数用途:根据ID删除Entity模型
   * 参数注释:
   * @param {String} id - 模型ID
   */
  removeEntityById(id) {
    let entity = this.viewer.entities.getById(id);

    if (entity) {
      this.viewer.entities.remove(entity);
    }
  }

  /**
   * 函数用途:根据名称查询entity模型
   * 参数注释:
   * @param {String} name - 模型名称
   * @returns Array[Entity实体] - 返回查询结果
   */
  findEntityByName(name) {
    let entities = this.viewer.entities.values;

    let temp = [];

    for (let item of entities) {
      if (item._name == name) {
        temp.push(i);
      }
    }

    return temp;
  }

  /**
   * 函数用途:查询所有Entity模型
   * 参数注释:无参
   * @returns Array[Entity实体] - 返回查询结果
   */
  findAllEntity() {
    let entities = this.viewer.entities.values;
    return entities
  }

  /**
   * 函数用途:查询所有primitive模型
   * 参数注释:无参
   * @returns Array[primitive实体] - 返回查询结果
   */
  findAllPrimitive() {
    let primitives = this.viewer.scene.primitives._primitives
    return primitives
  }

  /**
 * 函数用途:删除所有Entity模型
 * 参数注释:无参
 */
  removeAllEntity() {
    this.viewer.entities.removeAll();
  }

  /**
   * 函数用途:删除所有Primitive模型
   * 参数注释:无参
   */
  removeAllPrimitive() {
    let primitives = this.viewer.scene.primitives._primitives;
    for (let i = 0; i < primitives.length; i++) {
      if (primitives[i].geometryInstances) {
        this.viewer.scene.primitives.remove(primitives[i]);
        i--;
      }
    }
  }

  /**
   * 函数用途:屏幕坐标转经纬坐标
   * 参数注释:
   * @param {Number} x - x轴坐标
   * @param {Number} y - y轴坐标
   * @param {Number} height - 高度
   * @returns Object{经度,纬度,高度} - 返回转换结果
   */
  convertScreen(x, y, height = 0) {
    // 屏幕坐标转换为二维笛卡尔坐标
    let cartesianCoordinate = new this.Cesium.Cartesian2(x, y);
    // 获取二维笛卡尔的对应椭球面位置
    let wordCoordinate = this.viewer.scene.camera.pickEllipsoid(
      cartesianCoordinate,
      this.viewer.scene.globe.ellipsoid
    );
    // 笛卡尔坐标转弧度
    let cartographic = this.Cesium.Cartographic.fromCartesian(
      wordCoordinate,
      this.viewer.scene.globe.ellipsoid,
      new this.Cesium.Cartographic()
    );
    // Cesium.Math.toDegrees 将弧度转换成经纬度
    let longitude = this.Cesium.Math.toDegrees(cartographic.longitude); // 经度
    let latitude = this.Cesium.Math.toDegrees(cartographic.latitude); // 纬度

    return {
      longitude,
      latitude,
      height,
    };
  }

  /**
   * 函数用途:世界坐标转经纬度
   * 参数注释:
   * @param {Number} x - x轴坐标
   * @param {Number} y - y轴坐标
   * @param {Number} z - z轴坐标
   * @returns Object{经度,纬度,高度} - 返回转换结果
   */
  convertWord(x, y, z) {
    let cartographic = this.Cesium.Ellipsoid.WGS84.cartesianToCartographic({
      x,
      y,
      z,
    });

    let longitude = this.Cesium.Math.toDegrees(cartographic.longitude); // 经度
    let latitude = this.Cesium.Math.toDegrees(cartographic.latitude); // 纬度
    let height = cartographic.height; // 高度

    return {
      longitude,
      latitude,
      height
    };
  }

  /**
   * 函数用途:使用Turf.js计算两点之间的距离
   * 参数注释:
   * @param {Object} turf - Turf.js库对象
   * @param {Number} lastDistance - 上一次计算结果
   * @param {Array<Number>} startPoint - 起始点:[经度,纬度]
   * @param {Array<Number>} endPoint - 结束点:[经度,纬度]
   * @param {String} units - 单位
   * @returns Number - 返回计算结果
   */
  countDistance(turf, lastDistance, startPoint, endPoint, units = "kilometers") {
    // 计算距离
    lastDistance += turf.distance(
      turf.point(startPoint),
      turf.point(endPoint),
      { units }
    );

    return lastDistance
  }

  /**
   * 函数用途:使用Turf.js计算区域中心点(最后一个点需要和第一个点相同)
   * @param {Object} turf - Turf.js库对象
   * @param {Array<Array<Number>>} points - 区域坐标集合:[[经度,纬度],[经度,纬度]......]
   * @returns Object{经度,纬度} - 返回计算结果
   */
  countCenter(turf, points) {
    // 计算中心点
    let pointArray = turf.polygon([points]);
    let center = turf.centerOfMass(pointArray);

    let longitude = center.geometry.coordinates[0];
    let latitude = center.geometry.coordinates[1];
    // 计算多边形的中心点
    return { longitude, latitude };
  }

  /**
   * 函数用途:使用Turf.js计算区域面积(最后一个点需要和第一个点相同)
   * @param {Object} turf - Turf.js库对象
   * @param {Array<Array<Number>>} points - 区域坐标集合:[[经度,纬度],[经度,纬度]......]
   * @param {Number} num - 默认保留6位小数
   * @returns Number - 返回计算结果
   */
  countArea(turf, points, num = 6) {
    let pointArray = turf.polygon([points]);
    // 计算多边形面积,默认为平方米,转换为平方公里(除以1000000)
    let area = Number((turf.area(pointArray) / 1000000).toFixed(num));
    return area
  }

  /**
   * 函数用途:计算以中间点为顶点的三个点形成的夹角角度
   * @param {Array<Object>} points - 参与计算的点:[{经度,纬度},{经度,纬度},{经度,纬度}]
   * @returns Number - 返回计算结果(0 - 180)
   */
  countAngle(points) {
    // 将经纬度转换为笛卡尔坐标
    const cartesian1 = this.Cesium.Cartesian3.fromDegrees(
      points[0].longitude, points[0].latitude
    );
    const cartesian2 = this.Cesium.Cartesian3.fromDegrees(
      points[1].longitude, points[1].latitude
    );
    const cartesian3 = this.Cesium.Cartesian3.fromDegrees(
      points[2].longitude, points[2].latitude
    );
    // 构造向量(从顶点point2指向point1和point3)
    const vec1 = this.Cesium.Cartesian3.subtract(
      cartesian1,
      cartesian2,
      new this.Cesium.Cartesian3()
    );
    const vec2 = this.Cesium.Cartesian3.subtract(
      cartesian3,
      cartesian2,
      new this.Cesium.Cartesian3()
    );
    // 归一化向量(单位向量)
    this.Cesium.Cartesian3.normalize(vec1, vec1);
    this.Cesium.Cartesian3.normalize(vec2, vec2);
    // 计算点积
    const dot = this.Cesium.Cartesian3.dot(vec1, vec2);
    // 处理浮点误差(确保值在[-1, 1]范围内)
    const clampedDot = Math.min(Math.max(dot, -1.0), 1.0);
    // 计算夹角(弧度转角度)
    const angleRad = Math.acos(clampedDot);
    return this.Cesium.Math.toDegrees(angleRad);
  }

  /**
   * 函数用途:计算起始点到结束点的方位角
   * @param {Object} turf - Turf.js库对象
   * @param {Object} startPoint - 起始点:{经度,纬度}
   * @param {Object} endPoint - 结束点:{经度,纬度}
   * @returns Number - 返回计算结果
   */
  countAzimuthAngle(turf, startPoint, endPoint) {
    // 计算方位角度
    let bearing = turf.rhumbBearing(
      [startPoint.longitude, startPoint.latitude],
      [endPoint.longitude, endPoint.latitude]
    );
    return bearing
  }

  /**
   * 函数用途:设置相机视角-瞬间定位
   * @param {Object} param0 - 相机坐标:{经度,纬度,高度}
   * @param {Object} param1 - 相机视角:{水平旋转角度,俯仰角度,翻滚角度}
   */
  cameraSetView({ longitude, latitude, height }, { heading = 0, pitch = -90, roll = 0 }) {
    this.viewer.scene.camera.setView({
      destination: this.Cesium.Cartesian3.fromDegrees(
        longitude,
        latitude,
        height
      ),
      orientation: {
        heading: this.Cesium.Math.toRadians(heading),
        pitch: this.Cesium.Math.toRadians(pitch),
        roll,
      },
    });
  }

  /**
   * 函数用途:设置相机视角-飞行过渡定位
   * @param {Object} param0 - 相机坐标:{经度,纬度,高度}
   * @param {Object} param1 - 相机视角:{水平旋转角度,俯仰角度,翻滚角度}
   * @param {Number} duration - 飞行时间
   * @param {Function} callback - 飞行完成的回到函数
   */
  cameraFlyTo({ longitude, latitude, height }, { heading = 0, pitch = -90, roll = 0 }, duration = 5, callback) {
    this.viewer.camera.flyTo({
      destination: this.Cesium.Cartesian3.fromDegrees(
        longitude,
        latitude,
        height
      ),
      orientation: {
        heading: this.Cesium.Math.toRadians(heading),
        pitch: this.Cesium.Math.toRadians(pitch),
        roll,
      },
      duration, // 飞行时间(秒)
      complete: callback ? callback : () => { console.log("到达") } // 回调函数
    });
  }

  /**
   * 函数用途:设置地图图层
   * @param {String} url - 图层地址
   */
  switchLayers(url) {
    if (this.viewer.imageryLayers.length > 0) {
      this.viewer.imageryLayers.remove(this.viewer.imageryLayers.get(0));
    }

    this.viewer.imageryLayers.addImageryProvider(
      new this.Cesium.UrlTemplateImageryProvider({
        url,
      })
    );
  }

  /**
   * 函数用途:左键单击监听事件
   * @param {Function} callback - 监听回调函数
   */
  leftClick(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  /**
   * 函数用途:左键双击监听事件
   * @param {Function} callback - 监听回调函数
   */
  leftDouBleClick(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  }

  /**
   * 函数用途:左键按下监听事件
   * @param {Function} callback - 监听回调函数
   */
  leftDown(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.LEFT_DOWN);
  }

  /**
   * 函数用途:左键抬起监听事件
   * @param {Function} callback - 监听回调函数
   */
  leftUp(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.LEFT_UP);
  }

  /**
   * 函数用途:中键单击监听事件
   * @param {Function} callback - 监听回调函数
   */
  middleClick(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.MIDDLE_CLICK);
  }

  /**
   * 函数用途:中键按下监听事件
   * @param {Function} callback - 监听回调函数
   */
  middleDown(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
  }

  /**
   * 函数用途:中键抬起监听事件
   * @param {Function} callback - 监听回调函数
   */
  middleUp(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.MIDDLE_UP);
  }

  /**
   * 函数用途:右键单击监听事件
   * @param {Function} callback - 监听回调函数
   */
  rightClick(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  /**
   * 函数用途:右键按下监听事件
   * @param {Function} callback - 监听回调函数
   */
  rightDown(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.RIGHT_DOWN);
  }

  /**
   * 函数用途:右键抬起监听事件
   * @param {Function} callback - 监听回调函数
   */
  rightUp(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.RIGHT_UP);
  }

  /**
   * 函数用途:鼠标移动监听事件
   * @param {Function} callback - 监听回调函数
   */
  mouseMove(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }

  /**
   * 函数用途:鼠标滚轮监听事件
   * @param {Function} callback - 监听回调函数
   */
  mouseWheel(callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType.WHEEL);
  }

  /**
 * 函数用途:鼠标事件监听
 * @param {String} type - 事件类型:LEFT_CLICK、LEFT_DOUBLE_CLICK、......
 * @param {Function} callback - 监听回调函数
 */
  mouseListen(type, callback) {
    // 添加用户输入监听范围(element)
    let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // 处理用户输入事件
    handler.setInputAction((event) => {
      callback(event)
    }, this.Cesium.ScreenSpaceEventType[type]);
  }

  /**
   * 函数用途:移除鼠标事件监听
   * @param {String} type - 事件类型:LEFT_CLICK、LEFT_DOUBLE_CLICK、......
   */
  removeMouseListen(type) {
    this.viewer.screenSpaceEventHandler.removeInputAction(
      this.Cesium.ScreenSpaceEventType[type]
    );
  }
}

2、组件应用

<script setup>
import { mapFunction } from './mapFunction'

const mapFun = new mapFunction(viewer,Cesium)

// 示例一:根据ID查询Entity模型
mapFun.findEntityById(<model_id>)

// 示例二:根据ID删除Entity模型
mapFun.removeEntityById(<model_id>)

// 示例三:根据名称查询entity模型
mapFun.findEntityByName(<model_name>)

......
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值