|  | @@ -0,0 +1,1824 @@
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  Appearance,
 | 
	
		
			
				|  |  | +  Billboard,
 | 
	
		
			
				|  |  | +  CallbackProperty,
 | 
	
		
			
				|  |  | +  Cartesian3,
 | 
	
		
			
				|  |  | +  Color,
 | 
	
		
			
				|  |  | +  defined,
 | 
	
		
			
				|  |  | +  EllipseGeometry,
 | 
	
		
			
				|  |  | +  Entity,
 | 
	
		
			
				|  |  | +  GeometryInstance,
 | 
	
		
			
				|  |  | +  GroundPrimitive,
 | 
	
		
			
				|  |  | +  HeightReference,
 | 
	
		
			
				|  |  | +  Material,
 | 
	
		
			
				|  |  | +  Primitive,
 | 
	
		
			
				|  |  | +  ScreenSpaceEventHandler,
 | 
	
		
			
				|  |  | +  ScreenSpaceEventType,
 | 
	
		
			
				|  |  | +  VerticalOrigin,
 | 
	
		
			
				|  |  | +  Math as cesiumMath,
 | 
	
		
			
				|  |  | +  PolygonGeometry,
 | 
	
		
			
				|  |  | +  PolygonHierarchy,
 | 
	
		
			
				|  |  | +  Rectangle as cesiumRectangle,
 | 
	
		
			
				|  |  | +  RectangleGeometry,
 | 
	
		
			
				|  |  | +  BillboardCollection,
 | 
	
		
			
				|  |  | +} from "cesium";
 | 
	
		
			
				|  |  | +import { getCatesian3FromPX, cartesianToLonlat } from "../../tools";
 | 
	
		
			
				|  |  | +import type { BaseAreaI, PlotFuncI, PointArr } from "./../../interface";
 | 
	
		
			
				|  |  | +import { areaPlot } from "./algorithm";
 | 
	
		
			
				|  |  | +import emitter from "@/mitt";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class BaseArea implements BaseAreaI {
 | 
	
		
			
				|  |  | +  type: string;
 | 
	
		
			
				|  |  | +  baseType: string;
 | 
	
		
			
				|  |  | +  objId: number;
 | 
	
		
			
				|  |  | +  handler: any;
 | 
	
		
			
				|  |  | +  state: number;
 | 
	
		
			
				|  |  | +  step: number;
 | 
	
		
			
				|  |  | +  floatPoint: any;
 | 
	
		
			
				|  |  | +  floatPointArr: any;
 | 
	
		
			
				|  |  | +  areaPrimitive: any;
 | 
	
		
			
				|  |  | +  areaEntity: any;
 | 
	
		
			
				|  |  | +  modifyHandler: any;
 | 
	
		
			
				|  |  | +  pointList: any[];
 | 
	
		
			
				|  |  | +  material: any;
 | 
	
		
			
				|  |  | +  selectPoint: any;
 | 
	
		
			
				|  |  | +  clickStep: number;
 | 
	
		
			
				|  |  | +  constructor(obj: BaseAreaI) {
 | 
	
		
			
				|  |  | +    this.type = obj.type;
 | 
	
		
			
				|  |  | +    this.baseType = "area";
 | 
	
		
			
				|  |  | +    this.objId = obj.objId;
 | 
	
		
			
				|  |  | +    this.handler = obj.handler;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = obj.areaPrimitive;
 | 
	
		
			
				|  |  | +    this.areaEntity = obj.areaEntity;
 | 
	
		
			
				|  |  | +    this.state = obj.state; //state用于区分当前的状态 0 为删除 1为添加 2为编辑
 | 
	
		
			
				|  |  | +    this.step = obj.step;
 | 
	
		
			
				|  |  | +    this.floatPoint = obj.floatPoint;
 | 
	
		
			
				|  |  | +    this.floatPointArr = obj.floatPointArr;
 | 
	
		
			
				|  |  | +    this.modifyHandler = obj.modifyHandler;
 | 
	
		
			
				|  |  | +    this.pointList = obj.pointList;
 | 
	
		
			
				|  |  | +    this.material = obj.material;
 | 
	
		
			
				|  |  | +    this.selectPoint = obj.selectPoint;
 | 
	
		
			
				|  |  | +    this.clickStep = obj.clickStep;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  disable() {
 | 
	
		
			
				|  |  | +    if (this.areaEntity) {
 | 
	
		
			
				|  |  | +      window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +      window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +      this.floatPointArr.forEach((item: Billboard) => {
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(item);
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      this.areaEntity = null;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    this.state = -1;
 | 
	
		
			
				|  |  | +    this.stopDraw();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  stopDraw() {
 | 
	
		
			
				|  |  | +    if (this.handler) {
 | 
	
		
			
				|  |  | +      this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +      this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +      this.handler.removeInputAction(ScreenSpaceEventType.RIGHT_CLICK);
 | 
	
		
			
				|  |  | +      this.handler.destroy();
 | 
	
		
			
				|  |  | +      this.handler = null;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (this.modifyHandler) {
 | 
	
		
			
				|  |  | +      this.modifyHandler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +      this.modifyHandler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +      this.modifyHandler.removeInputAction(ScreenSpaceEventType.RIGHT_CLICK);
 | 
	
		
			
				|  |  | +      this.modifyHandler.destroy();
 | 
	
		
			
				|  |  | +      this.modifyHandler = null;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  creatPoint(cartesian: number[]): Primitive {
 | 
	
		
			
				|  |  | +    if (!window.Viewer.billboards)
 | 
	
		
			
				|  |  | +      window.Viewer.billboards = window.Viewer.scene.primitives.add(
 | 
	
		
			
				|  |  | +        new BillboardCollection({
 | 
	
		
			
				|  |  | +          scene: window.Viewer.scene,
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    return window.Viewer.billboards.add({
 | 
	
		
			
				|  |  | +      id: "moveBillboard",
 | 
	
		
			
				|  |  | +      position: cartesian,
 | 
	
		
			
				|  |  | +      image: "/src/assets/icon/point.png",
 | 
	
		
			
				|  |  | +      verticalOrigin: VerticalOrigin.BOTTOM,
 | 
	
		
			
				|  |  | +      heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * circle 圆
 | 
	
		
			
				|  |  | +class Circle extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "Circle",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 3) {
 | 
	
		
			
				|  |  | +        this.state = -1;
 | 
	
		
			
				|  |  | +        this.pointList.pop();
 | 
	
		
			
				|  |  | +        this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +        window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +        this.areaEntity = null;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        this.stopDraw();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const distance = Cartesian3.distance(this.pointList[0], this.pointList[1]);
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new EllipseGeometry({
 | 
	
		
			
				|  |  | +        center: this.pointList[0],
 | 
	
		
			
				|  |  | +        semiMajorAxis: distance,
 | 
	
		
			
				|  |  | +        semiMinorAxis: distance,
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算曲线,若有两个点则应该直接返回两个点的连线,若有三个点则返回处理后的坐标集合
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2) {
 | 
	
		
			
				|  |  | +        return this.pointList[0];
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    // * 通过坐标计算半径
 | 
	
		
			
				|  |  | +    const computeDistance = () => {
 | 
	
		
			
				|  |  | +      return Cartesian3.distance(this.pointList[0], this.pointList[1]);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      position: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +      ellipse: {
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        clampToGround: true,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +        semiMajorAxis: new CallbackProperty(computeDistance, false),
 | 
	
		
			
				|  |  | +        semiMinorAxis: new CallbackProperty(computeDistance, false),
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * ellipse 椭圆
 | 
	
		
			
				|  |  | +class Ellipse extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "Ellipse",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 3) {
 | 
	
		
			
				|  |  | +        this.state = -1;
 | 
	
		
			
				|  |  | +        this.pointList.pop();
 | 
	
		
			
				|  |  | +        this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +        window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +        this.areaEntity = null;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        this.stopDraw();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const maxDistance = Cartesian3.distance(
 | 
	
		
			
				|  |  | +      this.pointList[0],
 | 
	
		
			
				|  |  | +      this.pointList[1]
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new EllipseGeometry({
 | 
	
		
			
				|  |  | +        center: this.pointList[0],
 | 
	
		
			
				|  |  | +        semiMajorAxis: maxDistance,
 | 
	
		
			
				|  |  | +        semiMinorAxis: maxDistance / 2,
 | 
	
		
			
				|  |  | +        rotation: this.computeRoate(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算曲线,若有两个点则应该直接返回两个点的连线,若有三个点则返回处理后的坐标集合
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2) {
 | 
	
		
			
				|  |  | +        return this.pointList[0];
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    // * 通过坐标计算长半轴
 | 
	
		
			
				|  |  | +    const computeMaxDistance = () => {
 | 
	
		
			
				|  |  | +      const maxDistance = Cartesian3.distance(
 | 
	
		
			
				|  |  | +        this.pointList[0],
 | 
	
		
			
				|  |  | +        this.pointList[1]
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +      return maxDistance;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    // * 通过坐标计算短半轴
 | 
	
		
			
				|  |  | +    const computeMinDistance = () => {
 | 
	
		
			
				|  |  | +      const minDistance =
 | 
	
		
			
				|  |  | +        Cartesian3.distance(this.pointList[0], this.pointList[1]) / 2;
 | 
	
		
			
				|  |  | +      return minDistance;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    // * 计算椭圆朝向
 | 
	
		
			
				|  |  | +    const computeRoate = () => {
 | 
	
		
			
				|  |  | +      return this.computeRoate.apply(this);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      position: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +      ellipse: {
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        clampToGround: true,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +        semiMajorAxis: new CallbackProperty(computeMaxDistance, false),
 | 
	
		
			
				|  |  | +        semiMinorAxis: new CallbackProperty(computeMinDistance, false),
 | 
	
		
			
				|  |  | +        rotation: new CallbackProperty(computeRoate, false),
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  computeRoate() {
 | 
	
		
			
				|  |  | +    if (
 | 
	
		
			
				|  |  | +      (this.pointList[0].x >= this.pointList[1].x &&
 | 
	
		
			
				|  |  | +        this.pointList[0].y >= this.pointList[1].y) ||
 | 
	
		
			
				|  |  | +      (this.pointList[0].x < this.pointList[1].x &&
 | 
	
		
			
				|  |  | +        this.pointList[0].y < this.pointList[1].y)
 | 
	
		
			
				|  |  | +    ) {
 | 
	
		
			
				|  |  | +      return Math.atan2(
 | 
	
		
			
				|  |  | +        Math.abs(this.pointList[0].y - this.pointList[1].y),
 | 
	
		
			
				|  |  | +        Math.abs(this.pointList[0].x - this.pointList[1].x)
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      return (
 | 
	
		
			
				|  |  | +        cesiumMath.toRadians(cesiumMath.TWO_PI) -
 | 
	
		
			
				|  |  | +        Math.atan2(
 | 
	
		
			
				|  |  | +          Math.abs(this.pointList[0].y - this.pointList[1].y),
 | 
	
		
			
				|  |  | +          Math.abs(this.pointList[0].x - this.pointList[1].x)
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * lune 弓形
 | 
	
		
			
				|  |  | +class Lune extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "Lune",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 4) {
 | 
	
		
			
				|  |  | +        this.state = -1;
 | 
	
		
			
				|  |  | +        this.pointList.pop();
 | 
	
		
			
				|  |  | +        this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +        window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +        this.areaEntity = null;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        this.stopDraw();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const lnglatArr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new PolygonGeometry({
 | 
	
		
			
				|  |  | +        polygonHierarchy: new PolygonHierarchy(
 | 
	
		
			
				|  |  | +          areaPlot.algorithm.getArcPositions(lnglatArr)
 | 
	
		
			
				|  |  | +        ),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算坐标
 | 
	
		
			
				|  |  | +      const lnglatArr = [];
 | 
	
		
			
				|  |  | +      for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +        const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +        lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      if (lnglatArr.length == 2) {
 | 
	
		
			
				|  |  | +        lnglatArr.push([lnglatArr[1][0] + 0.0000001, lnglatArr[1][1]]);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const res = areaPlot.algorithm.getArcPositions(lnglatArr);
 | 
	
		
			
				|  |  | +      return new PolygonHierarchy(res);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      polygon: {
 | 
	
		
			
				|  |  | +        hierarchy: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * Sector 扇形
 | 
	
		
			
				|  |  | +class Sector extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "Sector",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 4) {
 | 
	
		
			
				|  |  | +        this.state = -1;
 | 
	
		
			
				|  |  | +        this.pointList.pop();
 | 
	
		
			
				|  |  | +        this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +        window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +        this.areaEntity = null;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        this.stopDraw();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const lnglatArr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new PolygonGeometry({
 | 
	
		
			
				|  |  | +        polygonHierarchy: new PolygonHierarchy(
 | 
	
		
			
				|  |  | +          areaPlot.algorithm.getSectorPositions(lnglatArr)
 | 
	
		
			
				|  |  | +        ),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitives = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitives;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算坐标
 | 
	
		
			
				|  |  | +      const lnglatArr = [];
 | 
	
		
			
				|  |  | +      for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +        const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +        lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      if (lnglatArr.length == 2) {
 | 
	
		
			
				|  |  | +        lnglatArr.push([lnglatArr[1][0] + 0.0000001, lnglatArr[1][1]]);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const res = areaPlot.algorithm.getSectorPositions(lnglatArr);
 | 
	
		
			
				|  |  | +      return new PolygonHierarchy(res);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      polygon: {
 | 
	
		
			
				|  |  | +        hierarchy: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * Rectangle 矩形
 | 
	
		
			
				|  |  | +class Rectangle extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "Rectangle",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 3) {
 | 
	
		
			
				|  |  | +        this.state = -1;
 | 
	
		
			
				|  |  | +        this.pointList.pop();
 | 
	
		
			
				|  |  | +        this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +        window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +        this.areaEntity = null;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        this.stopDraw();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const lnglatArr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const res = areaPlot.algorithm.getRectanglePositions(
 | 
	
		
			
				|  |  | +      lnglatArr[0],
 | 
	
		
			
				|  |  | +      lnglatArr[1]
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new RectangleGeometry({
 | 
	
		
			
				|  |  | +        rectangle: cesiumRectangle.fromDegrees(res[0], res[2], res[1], res[3]),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算坐标
 | 
	
		
			
				|  |  | +      const lnglatArr = [];
 | 
	
		
			
				|  |  | +      for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +        const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +        lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const res = areaPlot.algorithm.getRectanglePositions(
 | 
	
		
			
				|  |  | +        lnglatArr[0],
 | 
	
		
			
				|  |  | +        lnglatArr[1]
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +      return cesiumRectangle.fromDegrees(res[0], res[2], res[1], res[3]);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      rectangle: {
 | 
	
		
			
				|  |  | +        coordinates: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * closedCurve 曲线面
 | 
	
		
			
				|  |  | +class ClosedCurve extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "ClosedCurve",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +    // * 鼠标右击完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction(() => {
 | 
	
		
			
				|  |  | +      if (this.pointList.length < 3) return;
 | 
	
		
			
				|  |  | +      this.state = -1;
 | 
	
		
			
				|  |  | +      this.pointList.pop();
 | 
	
		
			
				|  |  | +      this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +      window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +      window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +      this.areaEntity = null;
 | 
	
		
			
				|  |  | +      this.floatPoint = null;
 | 
	
		
			
				|  |  | +      this.stopDraw();
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.RIGHT_CLICK);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const lnglatArr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const res = areaPlot.algorithm.getClosedCurvePositions(lnglatArr);
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new PolygonGeometry({
 | 
	
		
			
				|  |  | +        polygonHierarchy: new PolygonHierarchy(res),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算坐标
 | 
	
		
			
				|  |  | +      const lnglatArr = [];
 | 
	
		
			
				|  |  | +      for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +        const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +        lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const res = areaPlot.algorithm.getClosedCurvePositions(lnglatArr);
 | 
	
		
			
				|  |  | +      return new PolygonHierarchy(res);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      polygon: {
 | 
	
		
			
				|  |  | +        hierarchy: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * polygon 多边形
 | 
	
		
			
				|  |  | +class Polygon extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "Polygon",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +    // * 鼠标右击完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction(() => {
 | 
	
		
			
				|  |  | +      if (this.pointList.length < 3) return;
 | 
	
		
			
				|  |  | +      this.state = -1;
 | 
	
		
			
				|  |  | +      this.pointList.pop();
 | 
	
		
			
				|  |  | +      this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +      window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +      window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +      this.areaEntity = null;
 | 
	
		
			
				|  |  | +      this.floatPoint = null;
 | 
	
		
			
				|  |  | +      this.stopDraw();
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.RIGHT_CLICK);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new PolygonGeometry({
 | 
	
		
			
				|  |  | +        polygonHierarchy: new PolygonHierarchy(this.pointList),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      return new PolygonHierarchy(this.pointList);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      polygon: {
 | 
	
		
			
				|  |  | +        hierarchy: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * freeHandPolygon 自由面
 | 
	
		
			
				|  |  | +class FreeHandPolygon extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "FreeHandPolygon",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else if (this.pointList.length >= 2) {
 | 
	
		
			
				|  |  | +        // * 随着鼠标移动添加数据
 | 
	
		
			
				|  |  | +        this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +    // * 鼠标右击完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction(() => {
 | 
	
		
			
				|  |  | +      if (this.pointList.length < 3) return;
 | 
	
		
			
				|  |  | +      this.state = -1;
 | 
	
		
			
				|  |  | +      this.pointList.pop();
 | 
	
		
			
				|  |  | +      this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +      window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +      window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +      this.areaEntity = null;
 | 
	
		
			
				|  |  | +      this.floatPoint = null;
 | 
	
		
			
				|  |  | +      this.stopDraw();
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.RIGHT_CLICK);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new PolygonGeometry({
 | 
	
		
			
				|  |  | +        polygonHierarchy: new PolygonHierarchy(this.pointList),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      return new PolygonHierarchy(this.pointList);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      polygon: {
 | 
	
		
			
				|  |  | +        hierarchy: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// * gatheringPlace 聚集地
 | 
	
		
			
				|  |  | +class GatheringPlace extends BaseArea implements PlotFuncI {
 | 
	
		
			
				|  |  | +  constructor() {
 | 
	
		
			
				|  |  | +    super({
 | 
	
		
			
				|  |  | +      type: "GatheringPlace",
 | 
	
		
			
				|  |  | +      objId: Number(
 | 
	
		
			
				|  |  | +        new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0)
 | 
	
		
			
				|  |  | +      ),
 | 
	
		
			
				|  |  | +      handler: new ScreenSpaceEventHandler(window.Viewer.scene.canvas),
 | 
	
		
			
				|  |  | +      state: -1,
 | 
	
		
			
				|  |  | +      step: -1,
 | 
	
		
			
				|  |  | +      areaPrimitive: null,
 | 
	
		
			
				|  |  | +      areaEntity: null,
 | 
	
		
			
				|  |  | +      floatPoint: null,
 | 
	
		
			
				|  |  | +      floatPointArr: [],
 | 
	
		
			
				|  |  | +      modifyHandler: null,
 | 
	
		
			
				|  |  | +      pointList: [],
 | 
	
		
			
				|  |  | +      material: Material.fromType("Color", {
 | 
	
		
			
				|  |  | +        color: Color.PINK.clone(),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +      selectPoint: null,
 | 
	
		
			
				|  |  | +      clickStep: 0,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startDraw() {
 | 
	
		
			
				|  |  | +    this.state = 1;
 | 
	
		
			
				|  |  | +    // * 单击开始绘制,当点击第三次的时候完成绘制
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 4) {
 | 
	
		
			
				|  |  | +        this.state = -1;
 | 
	
		
			
				|  |  | +        this.pointList.pop();
 | 
	
		
			
				|  |  | +        this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +        window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +        window.Viewer.billboards.remove(this.floatPoint);
 | 
	
		
			
				|  |  | +        this.areaEntity = null;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        this.stopDraw();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    // * 移动时改变物体positions
 | 
	
		
			
				|  |  | +    this.handler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +      if (this.floatPoint) this.floatPoint.position = cartesian.clone();
 | 
	
		
			
				|  |  | +      else this.floatPoint = this.creatPoint(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 只有当第一次点击之后再给pointList添加值
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 1) this.pointList.push(cartesian.clone());
 | 
	
		
			
				|  |  | +      // * 若点击了一次就创建entity使用callback进行数据更新
 | 
	
		
			
				|  |  | +      if (this.pointList.length == 2 && !this.areaEntity) {
 | 
	
		
			
				|  |  | +        this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // * 当鼠标移动时,修改最后一个值
 | 
	
		
			
				|  |  | +        if (this.pointList.length >= 2)
 | 
	
		
			
				|  |  | +          this.pointList.splice(
 | 
	
		
			
				|  |  | +            this.pointList.length - 1,
 | 
	
		
			
				|  |  | +            1,
 | 
	
		
			
				|  |  | +            cartesian.clone()
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  startModify() {
 | 
	
		
			
				|  |  | +    if (!this.modifyHandler)
 | 
	
		
			
				|  |  | +      this.modifyHandler = new ScreenSpaceEventHandler(
 | 
	
		
			
				|  |  | +        window.Viewer.scene.canvas
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    this.state = 2;
 | 
	
		
			
				|  |  | +    this.pointList.forEach((point) => {
 | 
	
		
			
				|  |  | +      const billboard = this.creatPoint(point);
 | 
	
		
			
				|  |  | +      this.floatPointArr.push(billboard);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    // 进入编辑之后将创建好的primitive删除,添加entity用以适应动态数据变化
 | 
	
		
			
				|  |  | +    this.areaEntity = this.createEntity();
 | 
	
		
			
				|  |  | +    window.Viewer.scene.groundPrimitives.remove(this.areaPrimitive);
 | 
	
		
			
				|  |  | +    this.areaPrimitive = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      const cartesian = getCatesian3FromPX(evt.position);
 | 
	
		
			
				|  |  | +      if (!cartesian) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 如果有移动点在跟随鼠标移动,则在单击的时候固定此点的位置
 | 
	
		
			
				|  |  | +      if (this.step != -1) {
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +        this.step = -1;
 | 
	
		
			
				|  |  | +        this.floatPoint = null;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 如果没有移动点跟随鼠标移动,则在单击的时候查看是否有要素,如有则设置跟随点
 | 
	
		
			
				|  |  | +        const feature = window.Viewer.scene.pick(evt.position);
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          defined(feature) &&
 | 
	
		
			
				|  |  | +          feature.primitive instanceof Billboard &&
 | 
	
		
			
				|  |  | +          feature.primitive.id == "moveBillboard"
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          this.floatPoint = feature.primitive;
 | 
	
		
			
				|  |  | +          this.step = this.floatPointArr.indexOf(this.floatPoint);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.floatPoint = null;
 | 
	
		
			
				|  |  | +          this.state = -1;
 | 
	
		
			
				|  |  | +          this.floatPointArr.forEach((point: Billboard) => {
 | 
	
		
			
				|  |  | +            window.Viewer.billboards.remove(point);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          this.floatPointArr = [];
 | 
	
		
			
				|  |  | +          this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +          window.Viewer.entities.remove(this.areaEntity);
 | 
	
		
			
				|  |  | +          this.areaEntity = null;
 | 
	
		
			
				|  |  | +          this.stopDraw();
 | 
	
		
			
				|  |  | +          emitter.emit("modifiedEnd");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.LEFT_CLICK);
 | 
	
		
			
				|  |  | +    this.modifyHandler.setInputAction((evt: any) => {
 | 
	
		
			
				|  |  | +      if (this.step != -1 && this.floatPoint) {
 | 
	
		
			
				|  |  | +        const cartesian = getCatesian3FromPX(evt.endPosition);
 | 
	
		
			
				|  |  | +        if (!cartesian) return;
 | 
	
		
			
				|  |  | +        this.floatPoint.position = cartesian;
 | 
	
		
			
				|  |  | +        this.pointList[this.step] = cartesian.clone();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, ScreenSpaceEventType.MOUSE_MOVE);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  createByData(data: PointArr[]) {
 | 
	
		
			
				|  |  | +    this.pointList = data;
 | 
	
		
			
				|  |  | +    this.areaPrimitive = this.showPrimitiveOnMap();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getLnglats(): PointArr[] {
 | 
	
		
			
				|  |  | +    const arr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const item = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      arr.push(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return arr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  getPositions(): any[] {
 | 
	
		
			
				|  |  | +    return this.pointList;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建primitive进行展示
 | 
	
		
			
				|  |  | +  showPrimitiveOnMap(): Primitive {
 | 
	
		
			
				|  |  | +    // * 计算坐标
 | 
	
		
			
				|  |  | +    const lnglatArr = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +      const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +      lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const res = areaPlot.algorithm.getGatheringPlacePositions(lnglatArr);
 | 
	
		
			
				|  |  | +    const instance = new GeometryInstance({
 | 
	
		
			
				|  |  | +      id: this.objId,
 | 
	
		
			
				|  |  | +      geometry: new PolygonGeometry({
 | 
	
		
			
				|  |  | +        polygonHierarchy: new PolygonHierarchy(res),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const primitive = window.Viewer.scene.groundPrimitives.add(
 | 
	
		
			
				|  |  | +      new GroundPrimitive({
 | 
	
		
			
				|  |  | +        geometryInstances: instance,
 | 
	
		
			
				|  |  | +        appearance: new Appearance({
 | 
	
		
			
				|  |  | +          material: this.material,
 | 
	
		
			
				|  |  | +        }),
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +    emitter.emit("drawEnd");
 | 
	
		
			
				|  |  | +    return primitive;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // * 创建中间entity以适应动态数据
 | 
	
		
			
				|  |  | +  createEntity(): Entity {
 | 
	
		
			
				|  |  | +    const update = () => {
 | 
	
		
			
				|  |  | +      // * 计算坐标
 | 
	
		
			
				|  |  | +      const lnglatArr = [];
 | 
	
		
			
				|  |  | +      for (let i = 0; i < this.pointList.length; i++) {
 | 
	
		
			
				|  |  | +        const lnglat = cartesianToLonlat(this.pointList[i]);
 | 
	
		
			
				|  |  | +        lnglatArr.push(lnglat);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      if (lnglatArr.length == 2) {
 | 
	
		
			
				|  |  | +        lnglatArr.push([lnglatArr[1][0] + 0.0000001, lnglatArr[1][1]]);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const res = areaPlot.algorithm.getGatheringPlacePositions(lnglatArr);
 | 
	
		
			
				|  |  | +      return new PolygonHierarchy(res);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return window.Viewer.entities.add({
 | 
	
		
			
				|  |  | +      polygon: {
 | 
	
		
			
				|  |  | +        hierarchy: new CallbackProperty(update, false),
 | 
	
		
			
				|  |  | +        material: Color.BLUE,
 | 
	
		
			
				|  |  | +        heightReference: HeightReference.CLAMP_TO_GROUND,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export {
 | 
	
		
			
				|  |  | +  Circle,
 | 
	
		
			
				|  |  | +  Ellipse,
 | 
	
		
			
				|  |  | +  Lune,
 | 
	
		
			
				|  |  | +  Sector,
 | 
	
		
			
				|  |  | +  Rectangle,
 | 
	
		
			
				|  |  | +  ClosedCurve,
 | 
	
		
			
				|  |  | +  Polygon,
 | 
	
		
			
				|  |  | +  FreeHandPolygon,
 | 
	
		
			
				|  |  | +  GatheringPlace,
 | 
	
		
			
				|  |  | +};
 |