vue3+Cesium开发教程(19)---多边形标绘代码封装修改,新增矩形绘制

86 阅读2分钟

本学习系列将以Cesium + Vue3 + Vite +Typescript+elementplus作为主要技术栈展开,后续会循序渐进,持续探索Cesium的高级功能,请关注原文Cesium+Vue3学习教程系列(19)---多边形标绘代码封装修改,新增矩形绘制

之前在Cesium+Vue3学习系列(13)---态势标绘代码封装优化-CSDN博客中对箭头标绘进行了封装,近期有读者提议标绘加上矩形、圆形、扇形等。仔细想一想,箭头与矩形、圆形、扇形这些都是多边形呀,因此本篇将对之前的代码稍加修改,并根据最新封装,新增矩形绘制代码。提前预告一下,下一篇更新圆形、扇形标绘等代码,敬请关注。之前的代码在dev_situation_plot_20250925分支里,最新代码在master分支里。修改过程如下:

1、之前封装的BaseArrowArrow类改为BasePolygon类,所有多边形类都继承BasePolygon。之前的抽象函数createArrowPoints改为createPolygonPoints。

import { CallbackProperty, Cartesian3, ClassificationType, Color, Entity, PolygonGraphics, Viewer } from "cesium";
import { BaseDraw } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
export default abstract class BasePolygon extends BaseDraw{
    /** 临时点,用来实时跟随鼠标 */
        private tempCursor = new Cartesian3();
    
        /** 算法函数,子类注入 */
        protected abstract createPolygonPoints(pos: Cartesian3[]): Cartesian3[];
    
        /** 达到几个点自动结束 */
        protected abstract get maxPointCount(): number;
    
        constructor(viewer: Viewer, dispatcher: EventDispatcher) {
            super(viewer, dispatcher);
    
        }
    
        protected buildFinalEntity(): Entity {
            const geometryPoints = this.createPolygonPoints(this.getPositions())
            return this.viewer.entities.add({
                polygon: new PolygonGraphics({
                    hierarchy: new CallbackProperty(() => ({
                        positions: geometryPoints
                    }), false),
                    classificationType: ClassificationType.BOTH,
                    material: Color.BLUE.withAlpha(0.4)
                })
            });
    
        }
        protected buildTempEntity(): Entity | undefined {
            if (this.getPositions().length < (this.minPointCount - 1)) return undefined;
            return this.viewer.entities.add({
                polygon: new PolygonGraphics({
                    hierarchy: new CallbackProperty(
                        () => ({
                            positions: this.createPolygonPoints([
                                ...this.getPositions(),
                                this.tempCursor,
                            ]),
                        }),
                        false
                    ),
                    classificationType: ClassificationType.BOTH,
                    material: Color.CYAN.withAlpha(0.3),
                }),
            });
        }
    
        protected updateTempEntity(cursor: Cartesian3): void {
        this.tempCursor = cursor;
      }
    
      /* -------------------- 鼠标事件 -------------------- */
      protected onLeftClick(e: any): void {
        super.onLeftClick(e);
        if (this.getPositions().length === this.maxPointCount) {
          this.finish();
        }
      }
}

2、攻击箭头类AttackArrow、钳形攻击箭头类PincerAttackArrow、直线箭头类StraightArrow、燕尾攻击箭头类SwallowtailAttackArrow都改为继承BasePolygon。详情请查阅git代码,在此不再赘述。

3、新增矩形类CommonRectangle继承BasePolygon。

import { Viewer } from "cesium";
import BasePolygon from "./BasePolygon";
import { GeometryType } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
import { CreateRectanglePoints } from "./CreatePolygonPoints";
export default class CommonRectangle extends BasePolygon {
    constructor(viewer: Viewer, dispatcher: EventDispatcher) {
        super(viewer, dispatcher);
        this.geometryType = GeometryType.COMMON_RECTANGLE;
        this.minPointCount = 2;
    }
    protected get maxPointCount() { return 2; }
    protected createPolygonPoints = CreateRectanglePoints;
}

4、计算矩形坐标

/**
 * 创建矩形的四个点,顺时针返回
 * @param pos 传入的两个点
 * @returns 矩形的四个点,顺时针返回
 */
export const CreateRectanglePoints = (pos: Cartesian3[]) => {
    if (pos.length !== 2) return pos;
    const carto1 = Cartographic.fromCartesian(pos[0]);
    const carto2 = Cartographic.fromCartesian(pos[1]);
    const minLon = Math.min(carto1.longitude, carto2.longitude);
    const maxLon = Math.max(carto1.longitude, carto2.longitude);
    const minLat = Math.min(carto1.latitude, carto2.latitude);
    const maxLat = Math.max(carto1.latitude, carto2.latitude);
    const height = (carto1.height + carto2.height) / 2;
    // 顺时针:左下、左上、右上、右下
    const leftBottom = Cartesian3.fromRadians(minLon, minLat, height);
    const leftTop = Cartesian3.fromRadians(minLon, maxLat, height);
    const rightTop = Cartesian3.fromRadians(maxLon, maxLat, height);
    const rightBottom = Cartesian3.fromRadians(maxLon, minLat, height);
    return [leftBottom, leftTop, rightTop, rightBottom];
};

5、添加到EditHelper里

case GeometryType.COMMON_RECTANGLE:
                this.shapeEntity.polygon!.hierarchy = new CallbackProperty(() => new PolygonHierarchy(CreateRectanglePoints(this.positions)), false);
                break;

6、前端代码实现


 <el-button type="primary" @click="DrawRectangleOnScene">矩形</el-button>

const DrawPolygonOnScene = () => {
    const polygonTool = new CommonPolygon(viewer!, dispatcher);
    polygonTool.start();
}

7、实现效果

8、更多代码请关注原文Cesium+Vue3学习教程系列(19)---多边形标绘代码封装修改,新增矩形绘制