cesium绘制区域编辑

news2024/11/18 4:28:20

npm 安装也是可以的 

#默认安装最新的
yarn add cesium
 
#卸载插件
yarn remove cesium
 
#安装指定版本的
yarn add cesium@1.96.0
 
#安装指定版本到测试环境
yarn add cesium@1.96.0 -D
yarn install @turf/turf

<template>
  <div id="cesiumContainer"></div>
  <div class="but" >
    <div  :class="tableDataObj.drawList.length===0?'zoomIn animated_three':'wobble animated_eight'" @click="drawPlane">开始绘制</div>
    <div  :class="tableDataObj.drawList.length===0?'fadeOut animated_two':'fadeInDown animated'"  @click="echoEditing">回显编辑</div>
    <div  :class="tableDataObj.drawList.length===0?'fadeOutDownBig animated_six':'fadeInUpBig animated_four'"  @click="clean">清除</div>
    <div  :class="tableDataObj.drawList.length===0?'rotateOut animated_seven':'rotateIn animated_five'"  @click="thoroughClean">彻底清除</div>
     
  </div>
</template>
  <!-- 绘制面并且编辑 -->
  <script setup lang="ts">
import * as Cesium from "cesium";
import { onMounted, reactive, ref } from "vue";
import * as turf from "@turf/turf";

 
 
 

// 地图实例
let viewer: any;
// 存点数组,里面对象是这个{
//       lon: '',
//       lat: '',
//       hei: '',
//     };
const points: any = ref([]);
// 区域面积
const area = ref(0);
// 实体
let handler: any = null;
// 是否点击
let mouseClick = false;
// 是否移动
let mouseMove = false;
// 取消绘制
let startPicking = ref(false);
let deleteState=ref(false)
interface PositionsList {
  x: number;
  y: number;
  z: number;
}
// 存储绘制点
let  tableDataObj   = reactive({
  drawList:[]
});
onMounted(() => {
  // 初始化Cesium并创建viewer
  Cesium.Ion.defaultAccessToken =
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmMGU1MDc1Yy0zZTMyLTQ0ODEtYjcxYi0yYjAyNDgyZGY1MjQiLCJpZCI6MjAxMDQ3LCJpYXQiOjE3MTAxNjM4NjF9.b9qwNlQbvo49RJTHEMpjIiOS-mOvf9MF8ZHSYTdf6CI";
  viewer = new Cesium.Viewer("cesiumContainer", {
    infoBox: false, // 禁用沙箱,解决控制台报错
    selectionIndicator: false, //选择指示器
    timeline: false, // 时间轴
    animation: false, // 动画小组件
    geocoder: false, // 地理编码(搜索)组件
    homeButton: false, // 首页,点击之后将视图跳转到默认视角
    sceneModePicker: false, // 投影方式,切换2D、3D 和 Columbus View (CV) 模式。
    baseLayerPicker: false, // 底图组件,选择三维数字地球的底图(imagery and terrain)。
    navigationHelpButton: false, // 帮助按钮
    fullscreenButton: false, // 全屏按钮

    // vrButton: false, // VR模式
    // shouldAnimate: true, // 自动播放动画控件
    // shadows: true, // 是否显示光照投射的阴影
    // terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY, // 地质接收阴影`

    // imageryProvider: esri, //自定义图层,默认是谷歌的影响图层
    scene3DOnly: true, // 每个几何实例将只能以3D渲染以节省GPU内存
    sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
  });
  viewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏logo版权
  let destination = Cesium.Cartesian3.fromDegrees(116.3974, 39.9087, 10000); // 北京天安门广场的经纬度坐标及高度
  pointerdefault();
  viewer.camera.flyTo({
    destination: destination,
    duration: 2, // 飞行动画持续时间(单位:秒)
  });
});

//开始绘制
const drawPlane = () => {
  console.log(handler, "handler");

  if (handler != null) {
    clean();
  }

  points.value = [];
  startPicking.value = false;
  // 点位存储
  let positions: any = [];
  area.value = 0;
  let polygon = new Cesium.PolygonHierarchy();
  let dynamicPolygon: any = new Cesium.Entity();
  let polyObj: any = null;
  let polyId = "planBy" + buildUUID();

  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  handler.setInputAction(
    (movement: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
      let pick: any = pickEllisoidPosition(viewer, movement.position);
      mouseClick = true;
      if (
        Cesium.defined(pick) &&
        Cesium.defined(pick.cartesian) &&
        pick.cartesian.x
      ) {
        positions.push(pick.cartesian.clone());
        polygon.positions.push(pick.cartesian.clone());
        if (!polyObj) {
          dynamicPolygon = {
            id: polyId,
            polyline: {
              width: 7,
              // ...lineStyle,
              material: new Cesium.PolylineOutlineMaterialProperty({
                color: Cesium.Color.AQUA.withAlpha(0.7), // 线的颜色
                outlineWidth: 4,
                outlineColor: Cesium.Color.WHITE.withAlpha(0.6),
              }),
              show: true,
              clampToGround: true,
              positions: new Cesium.CallbackProperty(function () {
                return positions;
              }, false),
            },
            polygon: {
              hierarchy: new Cesium.CallbackProperty(function () {
                return polygon;
              }, false),
              // 绘制区域颜色
              material: Cesium.Color.STEELBLUE.withAlpha(0.4),
              clampToGround: true,
            },
          };
          polyObj = viewer.entities.add(dynamicPolygon);
        }
        let ray = viewer.camera.getPickRay(movement.position);
        let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
        let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
        viewer.entities.add({
          id: "editPoint" + buildUUID(),
          name: "点",
          point: {
            pixelSize: 15,
            color: Cesium.Color.WHITE,
            // ...lineStyle,
            show: true,
            clampToGround: true,
            // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
          },
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            0,
            3000
          ), // 可视范围
          position: Cesium.Cartesian3.fromDegrees(lng, lat, 0),
        });
      }
    },
    Cesium.ScreenSpaceEventType.LEFT_CLICK
  );

  handler.setInputAction(
    (movement: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
      if (mouseClick) {
        let pick: any = pickEllisoidPosition(viewer, movement?.endPosition);
        if (positions.length >= 0 && Cesium.defined(pick)) {
          if (mouseMove) {
            positions.pop();
            polygon.positions.pop();
          }
          if (pick.cartesian && pick.cartesian.x) {
            positions.push(pick.cartesian);
            polygon.positions.push(pick.cartesian);
            mouseMove = true;
          }
        }
      }
    },
    Cesium.ScreenSpaceEventType.MOUSE_MOVE
  );
  handler.setInputAction((movement) => {
    if (mouseClick && mouseMove) {
      positions.pop();
      polygon.positions.pop();
    }
    if (positions.length < 3) {
      alert("必须绘制三个点以上,请重新绘制");
      // 再次开启
      drawPlane();
      return;
    }
   
    // 计算面积
    getCalculateArea(positions);
    positions.push(positions[0]);
    mouseMove = false;
    mouseClick = false;
    points.value = [];

    for (let i = 0; i < positions.length; i++) {
      const tmp = cartesian3ToGps(viewer, positions[i]);
      const tmpPoint: object = {
        lon: tmp[0],
        lat: tmp[1],
        hei: tmp[2],
      };
      points.value.push(tmpPoint);
    }

    const arr = points.value.map((item) => [item.lon, item.lat]);
    area.value = turf.area(turf.polygon([arr])).toFixed(2) as any;

    // let pick =  viewer.scene.pick(movement.position);
    // console.log("右键:",pick.id.id)
    pickClear(polyObj);
    // 停止绘制
    stopDraw();

    handlePolyClick();
    // 右键删除
    handlePolyRightClick();
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};

// 计算面积
function getCalculateArea(positions: PositionsList) {
  tableDataObj.drawList = positions as any;
   console.log("cesium坐标:",tableDataObj.drawList.length)
  var areaCenter = getAreaAndCenter(positions);
  var calculatearea = areaCenter.area;
  var center = areaCenter.center;
  var text = formateArea(calculatearea, "m");
  // console.log("calculatearea面积:",calculatearea)
  // console.log("text面积",text)
  let labelId = viewer.entities.add({
    id: "label_" + buildUUID(),
    position: center,
    label: {
      text: "面积:" + text,
      // 字体大小
      font: "18px sans-serif",
      // FILL填充/OUTLINE描边/FILL_AND_OUTLINED填充描边
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      // 描边颜色
      outlineColor: Cesium.Color.WHITE,
      // 描边宽度
      outlineWidth: 5,
      // 字体颜色
      fillColor: Cesium.Color.BLUE,
    },
  });
}

// 添加小手
function pointerdefault() {
  // 添加小手
  viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) {
    const pickedObject = viewer.scene.pick(movement.endPosition);
    if (pickedObject && pickedObject.id) {
      viewer.container.style.cursor = "pointer";
    } else {
      viewer.container.style.cursor = "default";
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}

// 创建完面之后监听事件
const handlePolyClick = () => {
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  let pickData: any;
  handler.setInputAction((event: any) => {
    let windowPosition = event.position;
    // 通过屏幕坐标获取当前位置的实体信息
    let pickedObject = viewer.scene.pick(windowPosition);
    if (Cesium.defined(pickedObject)) {
      if (/planBy/.test(pickedObject.id._id)) {
        if (pickData && pickData._id == pickedObject._id) {
          return;
        }
        pickData = pickedObject.id; //获取编辑的事件
        editPlane(pickData, handler);
      }
    } else {
      if (!pickData) {
        return;
      }
      pickClear(pickData);
      pickData = undefined;
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
// 右键删除
const handlePolyRightClick = () => {
  console.log("触发了么");
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  handler.setInputAction((event: any) => {
    let windowPosition = event.position;
    // 通过屏幕坐标获取当前位置的实体信息
    let pickedObject = viewer.scene.pick(windowPosition);
    let pick = viewer.scene.pick(event.position);
    // 通过屏幕坐标获取当前位置的实体信息
    let pickData: any;
    if (Cesium.defined(pickedObject)) {
      pickData = pickedObject.id; //获取编辑的事件

      pickClear(pickData);
      pickData = undefined;
      
      if(!deleteState.value){
        //右键删除
        createDelteDom(event.position, pick.id.id);
      }else{
         return
      }
    
    }  
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};

// 删除
function createDelteDom(px, objId) {
  deleteState.value=true
   if (!objId) return;
  let deleteDom = window.document.createElement("span");
  deleteDom.style.background = "red";
  deleteDom.style.position = "absolute";
  deleteDom.style.color = "white";
  deleteDom.style.left = px.x + 10 + "px";
  deleteDom.style.top = px.y + 10 + "px";
  deleteDom.style.padding = "6px";
  deleteDom.style.borderRadius = "6px";
  deleteDom.style.cursor = "pointer";
  deleteDom.id = "easy3d-plot-delete";
  deleteDom.setAttribute("objId", objId);
  deleteDom.innerHTML = `删除`;
  let mapDom = window.document.getElementById(viewer.container.id);
  mapDom.appendChild(deleteDom);

  const clsBtn = window.document.getElementById("easy3d-plot-delete");
  if (!clsBtn) return;

  clsBtn.addEventListener("click", (e) => {
    let id = deleteDom.getAttribute("objId");
    removeByObjId(id);
  });
  document.addEventListener("click", function () {
    clsBtn.remove();
    deleteState.value=false
  });
}
/**
 * 根据id移除创建的对象
 * @param {String | Number} id 对象id
 */
function removeByObjId(id) {
  console.log("查看写ID", id);
  if (!id) return;
  let entity = viewer.entities.getById(id);
  if (entity) {
    viewer.entities.remove(entity);
  }

  // 删除面积label
  let label_id = viewer.entities.values[0].id;
  var reg = new RegExp("label_");
  if (reg.test(label_id)) {
    viewer.entities.removeById(label_id);
  }
}

// 创建完面之后编辑事件
const editPlane = (pick: any, handler: any) => {
  if (!pick) {
    return;
  }
  // const view = viewer.entities.getById(polyId)
  pick.polyline.width = 7;
  pick.polyline.material.outlineWidth = 4;
  pick.polyline.material.outlineColor = Cesium.Color.WHITE.withAlpha(0.6);
  removeEntities(viewer, {
    filterType: "id",
    filterReg: /(editPoint)|labelPoy_/,
  });
  let pointId: any = [];
  let downStatus = false;
  let currentPoint: any; //当前编辑点
  console.log(pick.polygon.hierarchy.getValue(), "pick.polygon.hierarchy");
  let positions = pick.polygon.hierarchy.getValue(
    Cesium.JulianDate.now()
  ).positions;
  // 生成编辑点
  for (let i = 0; i < positions.length; i++) {
    let ID = "editPoint" + buildUUID();

    let point = viewer.entities.add({
      id: ID,
      position: positions[i],
      vertexIndex: i,
      point: {
        pixelSize: 15,
        color: Cesium.Color.WHITE,
        // ...lineStyle,
        show: true,
        clampToGround: true,
        // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      },
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 3000), // 可视范围
    });
    // 保存点的ID以便删除
    pointId.push(ID);
  }
  const resp = positions.map((item) => {
    let cartographic = Cesium.Cartographic.fromCartesian(item);
    let longitude = Cesium.Math.toDegrees(cartographic.longitude);
    let latitude = Cesium.Math.toDegrees(cartographic.latitude);
    return {
      longitude: longitude,
      latitude: latitude,
      height: cartographic.height,
    };
  });
  resp.push(resp[0]);
  resp.forEach((item, index) => {
    if (resp[index + 1]?.longitude) {
      let longitude = (+item.longitude + +resp[index + 1].longitude) / 2;
      let latitude = (+item.latitude + +resp[index + 1].latitude) / 2;
      let height = (+item.height + +resp[index + 1].height) / 2;
      let position = [+longitude, +latitude, +height];
      let text = distanceApi(item, resp[index + 1]).toFixed(1) + "m";
      labelApis(`labelPoy_${buildUUID()}`, position, text);
    }
  });
  handler.setInputAction((event) => {
    // 获取屏幕坐标
    let windowPosition = event.position;
    // 通过屏幕坐标获取当前位置的实体信息
    let pickedObject = viewer.scene.pick(windowPosition);
    if (Cesium.defined(pickedObject)) {
      if (/editPoint/.test(pickedObject.id._id)) {
        downStatus = true;
        viewer.scene.screenSpaceCameraController.enableRotate = false;
        viewer.scene.screenSpaceCameraController.enableZoom = false;
        currentPoint = pickedObject.id;
        console.log(currentPoint);
      } else {
        viewer.scene.screenSpaceCameraController.enableRotate = true;
        viewer.scene.screenSpaceCameraController.enableZoom = true;
        return false;
      }
    } else {
      viewer.scene.screenSpaceCameraController.enableRotate = true;
      viewer.scene.screenSpaceCameraController.enableZoom = true;
      return false;
    }
  }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
  handler.setInputAction((event) => {
    if (!downStatus) {
      return;
    }
    removeEntities(viewer, {
      filterType: "id",
      filterReg: /labelPoy_|label_/,
    });
    let windowPosition = event.startPosition;
    // 将屏幕坐标转为笛卡尔坐标
    let ellipsoid = viewer.scene.globe.ellipsoid;
    let cartesian = viewer.camera.pickEllipsoid(windowPosition, ellipsoid);
    // 如果点击到地球外,那么返回
    if (!cartesian) {
      return;
    }
    // 更新编辑点的位置
    // console.log(currentPoint, cartesian);
    currentPoint.position._value = cartesian;
    let point: any = []; // 线的定位
    let polyData: any = [];
    for (let id of pointId) {
      // console.log(viewer.entities.getById(id), "0");
      point.push(viewer.entities.getById(id).position._value);
      polyData.push(viewer.entities.getById(id).position._value);
    }
    // const data = viewer.entities.getById(polyId)
    positions = point;

    point.push({ x: point[0]["x"], y: point[0]["y"], z: point[0]["z"] });

    const resp = point.map((item) => {
      let cartographic = Cesium.Cartographic.fromCartesian(item);
      let longitude = Cesium.Math.toDegrees(cartographic.longitude);
      let latitude = Cesium.Math.toDegrees(cartographic.latitude);
      return {
        lon: longitude,
        lat: latitude,
        height: cartographic.height,
      };
    });

    points.value = resp;
    const resps = points.value.map((item) => {
      return {
        longitude: item.lon,
        latitude: item.lat,
        height: item.height,
      };
    });
    // resp.push(resp[0])
    resps.forEach((item, index) => {
      if (resps[index + 1]?.longitude) {
        let longitude = (+item.longitude + +resps[index + 1].longitude) / 2;
        let latitude = (+item.latitude + +resps[index + 1].latitude) / 2;
        let height = (+item.height + +resps[index + 1].height) / 2;
        let position = [+longitude, +latitude, +height];
        let text = distanceApi(item, resps[index + 1]).toFixed(1) + "m";
        labelApis(`labelPoy_${buildUUID()}`, position, text);
      }
    });
    pick.polyline.positions = point;
    pick.polygon.hierarchy = polyData;
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  handler.setInputAction(() => {
    if (!downStatus) {
      return;
    }
    // removeEntities(viewer, {
    //   filterType: "id",
    //   filterReg: /label_/,
    // });
    console.log(points.value, "value");
    console.log("positions", positions);
    // 重新计算面积
    getCalculateArea(positions);

    viewer.scene.screenSpaceCameraController.enableRotate = true;
    viewer.scene.screenSpaceCameraController.enableZoom = true;
    downStatus = false;
    currentPoint = undefined;
  }, Cesium.ScreenSpaceEventType.LEFT_UP);
  // }
};
const pickClear = (pickData: any) => {
  pickData.polyline.width = 5;
  pickData.polyline.material.outlineWidth = 2;
  pickData.polyline.material.outlineColor = Cesium.Color.WHITE.withAlpha(0.4);
  removeEntities(viewer, {
    filterType: "id",
    filterReg: /(editPoint)|labelPoy_/,
  });
};
//结束绘制
const stopDraw = () => {
  if (handler) {
    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
    handler?.destroy();
    startPicking.value = true;
    handler = null;
  }
};
// 随机数字
const buildUUID = () => {
  const hexList: string[] = [];
  for (let i = 0; i <= 15; i++) {
    hexList[i] = i.toString(16);
  }
  let uuid = "";
  for (let i = 1; i <= 36; i++) {
    if (i === 9 || i === 14 || i === 19 || i === 24) {
      uuid += "-";
    } else if (i === 15) {
      uuid += 4;
    } else if (i === 20) {
      uuid += hexList[(Math.random() * 4) | 8];
    } else {
      uuid += hexList[(Math.random() * 16) | 0];
    }
  }
  return uuid.replace(/-/g, "");
};
/**
 * @description: cesium获取两点之间距离 (m)
 * @param {*} root 当前组件的根实例
 * @param {*} point1 坐标1
 * @param {*} point2  坐标2
 * @return {*} 距离
 */
const distanceApi = (position1: any, position2: any) => {
  let cartesian1 = Cesium.Cartesian3.fromDegrees(
    position1.longitude,
    position1.latitude,
    position1.height
  );
  let cartesian2 = Cesium.Cartesian3.fromDegrees(
    position2.longitude,
    position2.latitude,
    position2.height
  );

  var point1cartographic = Cesium.Cartographic.fromCartesian(cartesian1);
  var point2cartographic = Cesium.Cartographic.fromCartesian(cartesian2);

  /**根据经纬度计算出距离**/
  var geodesic = new Cesium.EllipsoidGeodesic();
  geodesic.setEndPoints(point1cartographic, point2cartographic);
  var distance = geodesic.surfaceDistance;
  //返回两点之间的距离
  return (distance = Math.sqrt(
    Math.pow(distance, 2) +
      Math.pow(point2cartographic.height - point1cartographic.height, 2)
  ));
};
/**
 * 删除地图上的实体
 * @param viewer
 * @param option
 */
const removeEntities = (viewer: Cesium.Viewer, option: any) => {
  if (!viewer) {
    return;
  }
  const removedId: string[] = [];
  viewer.entities.values.map((item) => {
    if (option.filterType == "id") {
      if (option.filterReg.test(item.id)) {
        removedId.push(item.id);
      }
    }
  });
  removedId.sort(function (a, b) {
    return b.indexOf("measureLineXL") !== -1 ? 1 : -1;
  });
  removedId.map(function (item) {
    viewer.entities.removeById(item);
  });
};
/**
 * cartesian3转gps
 * @param viewer
 * @param cartesian
 * @returns
 */
const cartesian3ToGps = (
  viewer: Cesium.Viewer,
  cartesian: Cesium.Cartesian3
): number[] => {
  const cartographic =
    viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  return [
    Cesium.Math.toDegrees(cartographic.longitude),
    Cesium.Math.toDegrees(cartographic.latitude),
    cartographic.height,
  ];
};
/**
 * 拾取球面坐标
 * @param viewer  场景视图
 * @param position 屏幕坐标
 * @returns array 地理坐标数组
 */
const pickEllisoidPosition = (
  viewer: Cesium.Viewer,
  position: Cesium.Cartesian2
) => {
  const pickRay = viewer.scene.camera.getPickRay(position);
  if (pickRay) {
    const cartesian = viewer.scene.globe.pick(pickRay, viewer.scene);
    if (cartesian) {
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      const result = {
        geoPositon: [
          Cesium.Math.toDegrees(cartographic.longitude),
          Cesium.Math.toDegrees(cartographic.latitude),
          cartographic.height,
        ],
        cartesian: cartesian,
      };
      return result;
    }
  }
};

const labelApis = (id, position, text) => {
  viewer.entities.add({
    id: id,
    name: "labelApi",
    position: Cesium.Cartesian3.fromDegrees(...position),
    label: {
      text: text,
      showBackground: true, //显示背景
      backgroundColor: new Cesium.Color.fromCssColorString("rgba(0,0,0,0.7)"),
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //对齐方式
      font: "16px sans-serif",
      fillColor: Cesium.Color.MIDNIGHTBLUE,
      outlineColor: Cesium.Color.WHITE,
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      outlineWidth: 4,
      pixelOffset: new Cesium.Cartesian2(0, -10), // 视角偏移
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 400000), // 可视范围
      eyeOffset: new Cesium.Cartesian3(0, 0, -30),
    },
  });
};

const clean = () => {
  removeEntities(viewer, {
    filterType: "id",
    filterReg: /(editPoint)|planBy|labelPoy_|label_/,
  });
  // 停止绘制

  stopDraw();

  // console.log(handler, "handler");
};
// 彻底清除
function thoroughClean(){
  tableDataObj.drawList=[]
  clean()
}
const echoEditing = () => {
  let square=ref()
console.log("square",square)
  clean();
  let polyObj: any = null;
  let polyId = "planBy" + buildUUID();
  // 点位存储

  let polygon = new Cesium.PolygonHierarchy();
  let dynamicPolygon: any = new Cesium.Entity();
  let pointData: any = [];
  pointData = tableDataObj.drawList;
  let points: any = [];
// console.log("drawList",tableDataObj.drawList)
// console.log("pointData",pointData)
if(pointData.length==0){
  alert("没有点位数据,无法回显!!!")
  return
}
  for (let i = 0; i < pointData.length; i++) {
    const tmp = cartesian3ToGps(viewer, pointData[i]);
    points.push(tmp[0], tmp[1], tmp[2]);
  }
  // console.log(points, "lll");

  if (!polyObj) {
    dynamicPolygon = {
      id: polyId,
      polyline: {
        width: 7,
        // ...lineStyle,
        material: new Cesium.PolylineOutlineMaterialProperty({
          color: Cesium.Color.AQUA.withAlpha(0.7), // 线的颜色
          outlineWidth: 4,
          outlineColor: Cesium.Color.WHITE.withAlpha(0.6),
        }),
        show: true,
        clampToGround: true,
        positions: Cesium.Cartesian3.fromDegreesArrayHeights(points),
      },
      polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(points),
        material: Cesium.Color.STEELBLUE.withAlpha(0.4),
        clampToGround: true,
      },
    };
    polyObj = viewer.entities.add(dynamicPolygon);
    handlePolyClick();
    // 计算面积
    getCalculateArea(pointData);
    // 右键删除
    handlePolyRightClick();
  }
};

//调用第三方插件计算面积 turf
function getAreaAndCenter(positions: any) {
  if (!positions || positions.length < 1) return;
  var cartographics = [];
  var turfPoints = [];
  for (var i = 0; i < positions.length; i++) {
    var cartesian3 = positions[i];
    var cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
    cartographics.push([
      Cesium.Math.toDegrees(cartographic.longitude),
      Cesium.Math.toDegrees(cartographic.latitude),
    ]);
    turfPoints.push(
      turf.point([
        Cesium.Math.toDegrees(cartographic.longitude),
        Cesium.Math.toDegrees(cartographic.latitude),
      ])
    );
  }
  if (!cartographics.length) return;
  cartographics = cartographics.concat([cartographics[0]]);
  var polygon = turf.polygon([cartographics]);
  var area = turf.area(polygon);
  //获取当前范围的中心点
  var features = turf.featureCollection(turfPoints);
  var turfCenter = turf.center(features);
  var center = turfCenter.geometry.coordinates;

  return {
    area: area,
    center: Cesium.Cartesian3.fromDegrees(center[0], center[1]),
  };
}
function formateArea(val: any, dw: string) {
  if (val == undefined) return;
  let dwStr = "";
  dw = dw || "m";
  if (dw == "km" || dw == "平方千米") {
    dwStr += (Number(val) / 1000000).toFixed(2) + "km²";
  } else if (dw == "m" || dw == "平方米") {
    dwStr += Number(val).toFixed(2) + "m²";
  } else {
  }
  return dwStr;
}
</script>
  
  <style scoped>
#cesiumContainer {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0px;
  left: 0px;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.but {
  position: absolute;
  top: 50px;
  left: 100px;
  width: 200px;
  height: 20px;
  display: flex;
  justify-content: space-between;
  /* background-color: black; */
  z-index: 2;
}
.but div {
  height: 20px;
  font-size: 12px;
  z-index: 2;
  cursor: pointer;
  min-width: 100px;
  text-align: center;
  padding: 10px;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  border-radius: 5px;
  margin-left: 10px;
}


</style>
<style lang="scss" scoped>
 
.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

.animated.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}

.animated.hinge {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
}

/*the animation definition*/

@-webkit-keyframes fadeInDown {
  0% {
    opacity: 0;
    -webkit-transform: translate3d(0, -100%, 0);
    transform: translate3d(0, -100%, 0)
  }
  100% {
    opacity: 1;
    -webkit-transform: none;
    transform: none
  }
}

@keyframes fadeInDown {
  0% {
    opacity: 0;
    -webkit-transform: translate3d(0, -100%, 0);
    -ms-transform: translate3d(0, -100%, 0);
    transform: translate3d(0, -100%, 0)
  }
  100% {
    opacity: 1;
    -webkit-transform: none;
    -ms-transform: none;
    transform: none
  }
}

.fadeInDown {
  -webkit-animation-name: fadeInDown;
  animation-name: fadeInDown
}


/*base code*/
.animated_two {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_two.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_two.hinge {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes fadeOut {
  0% {
    opacity: 1
  }
  100% {
    opacity: 0
  }
}
@keyframes fadeOut {
  0% {
    opacity: 1
  }
  100% {
    opacity: 0
  }
}
.fadeOut {
  -webkit-animation-name: fadeOut;
  animation-name: fadeOut
}

/*base code*/
.animated_three {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_three.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_three.hinge {
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
}
/*the animation definition*/
@-webkit-keyframes zoomIn {
  0% {
    opacity: 0;
    -webkit-transform: scale3d(.3, .3, .3);
    transform: scale3d(.3, .3, .3)
  }
  50% {
    opacity: 1
  }
}
@keyframes zoomIn {
  0% {
    opacity: 0;
    -webkit-transform: scale3d(.3, .3, .3);
    -ms-transform: scale3d(.3, .3, .3);
    transform: scale3d(.3, .3, .3)
  }
  50% {
    opacity: 1
  }
}
.zoomIn {
  -webkit-animation-name: zoomIn;
  animation-name: zoomIn
}


/*base code*/
.animated_four {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_four.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_four.hinge {
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
}
/*the animation definition*/
@-webkit-keyframes fadeInUpBig {
  0% {
    opacity: 0;
    -webkit-transform: translate3d(0, 2000px, 0);
    transform: translate3d(0, 2000px, 0)
  }
  100% {
    opacity: 1;
    -webkit-transform: none;
    transform: none
  }
}
@keyframes fadeInUpBig {
  0% {
    opacity: 0;
    -webkit-transform: translate3d(0, 2000px, 0);
    -ms-transform: translate3d(0, 2000px, 0);
    transform: translate3d(0, 2000px, 0)
  }
  100% {
    opacity: 1;
    -webkit-transform: none;
    -ms-transform: none;
    transform: none
  }
}
.fadeInUpBig {
  -webkit-animation-name: fadeInUpBig;
  animation-name: fadeInUpBig
}

/*base code*/
.animated_six {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_six.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_six.hinge {
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
}
/*the animation definition*/
@-webkit-keyframes fadeOutDownBig {
  0% {
    opacity: 1
  }
  100% {
    opacity: 0;
    -webkit-transform: translate3d(0, 2000px, 0);
    transform: translate3d(0, 2000px, 0)
  }
}
@keyframes fadeOutDownBig {
  0% {
    opacity: 1
  }
  100% {
    opacity: 0;
    -webkit-transform: translate3d(0, 2000px, 0);
    -ms-transform: translate3d(0, 2000px, 0);
    transform: translate3d(0, 2000px, 0)
  }
}
.fadeOutDownBig {
  -webkit-animation-name: fadeOutDownBig;
  animation-name: fadeOutDownBig
}


/*base code*/
.animated_five {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_five.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_five.hinge {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes rotateIn {
  0% {
    -webkit-transform-origin: center;
    transform-origin: center;
    -webkit-transform: rotate3d(0, 0, 1, -200deg);
    transform: rotate3d(0, 0, 1, -200deg);
    opacity: 0
  }
  100% {
    -webkit-transform-origin: center;
    transform-origin: center;
    -webkit-transform: none;
    transform: none;
    opacity: 1
  }
}
@keyframes rotateIn {
  0% {
    -webkit-transform-origin: center;
    -ms-transform-origin: center;
    transform-origin: center;
    -webkit-transform: rotate3d(0, 0, 1, -200deg);
    -ms-transform: rotate3d(0, 0, 1, -200deg);
    transform: rotate3d(0, 0, 1, -200deg);
    opacity: 0
  }
  100% {
    -webkit-transform-origin: center;
    -ms-transform-origin: center;
    transform-origin: center;
    -webkit-transform: none;
    -ms-transform: none;
    transform: none;
    opacity: 1
  }
}
.rotateIn {
  -webkit-animation-name: rotateIn;
  animation-name: rotateIn
}


/*base code*/
.animated_seven {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_seven.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_seven.hinge {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes rotateOut {
  0% {
    -webkit-transform-origin: center;
    transform-origin: center;
    opacity: 1
  }
  100% {
    -webkit-transform-origin: center;
    transform-origin: center;
    -webkit-transform: rotate3d(0, 0, 1, 200deg);
    transform: rotate3d(0, 0, 1, 200deg);
    opacity: 0
  }
}
@keyframes rotateOut {
  0% {
    -webkit-transform-origin: center;
    -ms-transform-origin: center;
    transform-origin: center;
    opacity: 1
  }
  100% {
    -webkit-transform-origin: center;
    -ms-transform-origin: center;
    transform-origin: center;
    -webkit-transform: rotate3d(0, 0, 1, 200deg);
    -ms-transform: rotate3d(0, 0, 1, 200deg);
    transform: rotate3d(0, 0, 1, 200deg);
    opacity: 0
  }
}
.rotateOut {
  -webkit-animation-name: rotateOut;
  animation-name: rotateOut
}


/*base code*/
.animated_eight {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated_eight.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated_eight.hinge {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes wobble {
  0% {
    -webkit-transform: none;
    transform: none
  }
  15% {
    -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg)
  }
  30% {
    -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)
  }
  45% {
    -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)
  }
  60% {
    -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)
  }
  75% {
    -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)
  }
  100% {
    -webkit-transform: none;
    transform: none
  }
}
@keyframes wobble {
  0% {
    -webkit-transform: none;
    -ms-transform: none;
    transform: none
  }
  15% {
    -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
    -ms-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg)
  }
  30% {
    -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
    -ms-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)
  }
  45% {
    -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
    -ms-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)
  }
  60% {
    -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
    -ms-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)
  }
  75% {
    -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
    -ms-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)
  }
  100% {
    -webkit-transform: none;
    -ms-transform: none;
    transform: none
  }
}
.wobble {
  -webkit-animation-name: wobble;
  animation-name: wobble
}


</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1708163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始学React--环境搭建

React官网 快速入门 – React 中文文档 1.搭建环境 下载nodejs,双击安装 nodejs下载地址 更新npm npm install -g npm 设置npm源&#xff0c;加快下载速度 npm config set registry https://registry.npmmirror.com 创建一个react应用 npx create-react-app react-ba…

QT 自定义协议TCP传输文件

后面附带实例的下载地址 一、将文件看做是由:文件头+文件内容组成,其中文件头包含文件的一些信息:文件名称、文件大小等。 二、文件头单独发送,文件内容切块发送。 三、每次发送信息格式:发送内容大小、发送内容类型(文件头或是文件块内容)、文件块内容。 四、效果展…

项目十三:搜狗——python爬虫实战案例

根据文章项目十二&#xff1a;简单的python基础爬虫训练-CSDN博客的简单应用&#xff0c;这一次来升级我们的技术&#xff0c;那么继续往下看&#xff0c;希望对技术有好运。 还是老样子&#xff0c;按流程走&#xff0c;一条龙服务&#xff0c;嘿嘿。 第一步&#xff1a;导入…

设置AXI主寄存器切片和AXI数据FIFO

设置AXI主寄存器切片和AXI数据FIFO 打开MHS文件&#xff0c;并为每个AXI主机设置启用寄存器切片/启用数据FIFO。到 确定正确的设置&#xff0c;使用下表中的信息搜索MHS。 进行搜索时&#xff0c;将<intf_name>替换为相关的BUS_INTERFACE名称。 例如&#xff0c;BUS_INTE…

开发远程遥控情趣玩具软件,提供现成程序源码应具备哪些基础功能

以“东莞梦情智能”为参考&#xff0c;其提供的现成情趣玩具遥控软件程序源码&#xff0c;所具备哪些基础功能&#xff0c;看看它们如何让情趣玩具变得更加丰富多彩。 一、设备连接 设备连接是情趣玩具遥控软件的基础功能之一。“东莞梦情智能”的现成源码支持多种连接方式&am…

迅狐跨境商城系统源码

在当今全球化的商业环境中&#xff0c;跨境电商的兴起为商家提供了无限的可能性。为了满足这一需求&#xff0c;跨境商城系统源码的开发显得尤为重要。本文将探讨跨境商城系统源码的优势&#xff0c;以及如何利用这些优势来构建一个成功的跨境电商平台。 独立开发&#xff0c;…

双指针技巧,链表

双指针链表 虚拟头节点双指针&#xff0c;都要用虚拟1头节点 合并两个有序链表 设置双指针&#xff0c;都指向虚拟头节点 ListNode list1 代表的是头节点 class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode dummynew ListNode(-1…

pytorch比较操作

文章目录 常用的比较操作1.torch.allclose()2.torch.argsort()3.torch.eq()4.torch.equal()5.torch.greater_equal()6.torch.gt()7.torch.isclose()8.torch.isfinite()9.torch.isif()10.torch.isposinf()11.torch.isneginf()12.torch.isnan()13.torch.kthvalue()14.torch.less_…

常见排序算法之选择排序

目录 一、选择排序 1.1 什么是选择排序&#xff1f; 1.2 思路 1.2.1 思路一 1.2.2 优化思路 1.3 C语言源码 1.3.1 思路一 1.3.2 优化思路 二、堆排序 2.1 调整算法 2.1.2 向上调整算法 2.1.3 向下调整算法 2.2 建堆排序 一、选择排序 1.1 什么是选择排序&#xf…

百川股份:大王蹲完,小王蹲

一根大阴线&#xff0c;正丹股份的十倍股传奇之旅即将落幕&#xff1f; 有股民表示&#xff1a;化工板块还有高手&#xff0c;大王倒了还有小王。 今天我们聊的正是化工板块被称为“正丹第二”的百川股份。 虽难比正丹的十倍涨幅&#xff0c;但百川也不简单&#xff0c;3个月…

德比软件携手亚马逊云科技,用生成式AI赋能旅游行业降本增效

旅游行业是最早被数字化技术赋能的行业之一。比如&#xff0c;消费者早已习惯在携程、艺龙、Booking等OTA平台根据实时酒店信息预订酒店。 这种丝滑的消费者体验背后&#xff0c;离不开领先的管理软件支撑。实际上大型酒店集团与OTA平台之间的系统对接非常复杂&#xff0c;酒店…

无人机侦察:雷达系统概述

一、雷达基本原理 无人机侦察中的雷达系统主要基于无线电波的传播和反射原理。雷达发射机产生特定频率的电磁波&#xff0c;并通过天线以定向波束形式向空间发射。当这些电磁波遇到目标时&#xff0c;部分能量会被反射回来&#xff0c;被雷达接收机捕获。通过测量发射和接收电…

自建公式,VBA在Excel中解一元一次方程

自建公式,VBA在Excel中解一元一次方程 文章目录 前言一、运行效果图二、操作思路三、代码1.去除方程中未知数,将未知数转为“*0”2.计算方程中常数3.计算方程中未知数的系数一,先将未知数替换成“*1”4.计算方程中未知数的系数二5.计算方程得数前言 小学必考内容:一元一次…

C++ STL 中的自定义比较:深入理解相等和等价

STL 中的自定义比较、相等和等价 一、简介二、STL 的排序部分三、STL 的未排序部分四、比较元素五、实现比较器六、总结 一、简介 本文主要讨论了在 STL 中使用自定义比较函数&#xff0c;以及比较操作中的相等和等价概念。 有如下的代码&#xff1a; std::vector< std::…

【全开源】优校管理系统支持微信小程序+微信公众号+H5

概述 优校管理系统(简称优校管)是基于FastAdmin和ThinkPHP进行开发的中小学信息化管理系统&#xff0c;拥有PC版、UniAPP版(高级授权)。支持微信小程序、H5等多平台&#xff0c;主要用于信息管理、教学管理、素养评价&#xff0c;支持多个学校(标准授权限5个&#xff0c;高级授…

吴恩达2022机器学习专项课程C2W2:2.19 sigmoid函数的替代方案 2.20如何选择激活函数 2.21 激活函数的重要性

这里写目录标题 引言sigmoid激活函数的局限1.回顾需求案例2.ReLU激活函数 常用的激活函数1.线性激活函数的解释 如何选择激活函数&#xff1f;1.选择输出层的激活函数2.选择隐藏层的激活函数 选择激活函数的总结1.输出层总结2.隐藏层总结3.TensorFlow设置激活函数 激活函数多样…

CSS中的Flex布局

目录 一.什么是Flex布局 二.Flex布局使用 2.1Flex使用语法 2.2基本概念 三.容器的属性 3.1所有属性概述 3.2flex-direction 3.3flex-wrap 3.4flex-flow 3.5justify-content 3.6align-items 3.7align-content 四.项目(子元素)的属性 4.1所有属性概述 4.2order 4…

FPGA DMA技术分享(赋能高速数据处理的新动力介绍篇)

一、引言 在现代数字信号处理系统中&#xff0c;数据的高速、高效传输与处理是关键。FPGA&#xff08;现场可编程门阵列&#xff09;以其高度的灵活性和并行处理能力&#xff0c;成为实现这一目标的理想平台。而DMA&#xff08;直接内存访问&#xff09;技术&#xff0c;作为FP…

配置物联网平台 保姆级教程

一、云平台配置&#xff08;我们这里使用阿里云&#xff09; 1、注册和登录 &#xff08;1&#xff09;找到云平台官网&#xff0c;点击右上角的注册登录&#xff0c;完成之后&#xff0c;进行实名认证&#xff0c;任选一种认证方式。 ​​​​​​​ 2、实例的开通和创建 …

常用批处理命令及批处理文件编写技巧

一常用批处理命令 1.查看命令用法&#xff1a;命令 /? //如&#xff1a;cd /? 2.切换盘符目录&#xff1a;cd /d D:\test 或直接输入 d: //进入上次d盘所在的目录 3.切换目录&#xff1a;cd test 4.清屏:cls 5.“arp -a” //它会列出当前设备缓存中的所有…