本学习系列将以Cesium + Vue3+Typescript+elementplus作为主要技术栈展开,后续会循序渐进,持续探索Cesium的高级功能。 详情请关注原文Cesium+Vue3学习系列(12)---态势标绘 钳形攻击箭头(双箭头)标绘与编辑
上篇介绍攻击箭头与燕尾攻击箭头的标绘与编辑。下面开始继续扩展,本篇介绍钳形攻击箭头(双箭头)标绘与编辑。先看效果
新建PincerAttackArrow继承BaseDraw。通过createPincerAttackArrowPoints函数实现计算具体的箭头需要的点。
import { CallbackProperty, Cartesian3, ClassificationType, Color, Entity, PolygonGraphics, Viewer } from "cesium";
import { BaseDraw, GeometryType } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
import { createPincerAttackArrowPoints } from "@/system/Utils/SituationUtils/SituationUtil";
export default class PincerAttackArrow extends BaseDraw {
private tempCursor = new Cartesian3();
constructor(viewer: Viewer, dispatcher: EventDispatcher) {
super(viewer, dispatcher);
this.geometryType = GeometryType.PINCER_ATTACK_ARROW;
this.minPointCount = 4;
}
protected buildFinalEntity(): Entity {
const geometryPoints = createPincerAttackArrowPoints(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: createPincerAttackArrowPoints([...this.getPositions(), this.tempCursor || new Cartesian3()])
}), false),
classificationType: ClassificationType.BOTH,
material: Color.CYAN.withAlpha(0.3)
})
});
}
protected updateTempEntity(cursor: Cartesian3) {
this.tempCursor = cursor;
}
protected onLeftClick(e: any) {
super.onLeftClick(e);
// 需要 5次点击即可结束
if (this.getPositions().length == 5) {
this.finish();
}
}
}
export const createPincerAttackArrowPoints = (positions: Cartesian3[],headHeightFactor: number=0.25,headWidthFactor:number=0.3,neckWidthFactor:number=0.15,neckHeightFactor:number=0.85) => {
const lnglatPoints = positions.map((pnt) => {
return CoordinatesUtil.Cartesian2Wgs84Lonlat(pnt);
});
const [pnt1, pnt2, pnt3] = [lnglatPoints[0], lnglatPoints[1], lnglatPoints[2]];
const count = lnglatPoints.length;
let tempPoint4: number[] = [];
let connPoint: number[] = [];
if (count === 3) {
tempPoint4 = getPincerAttackArrowTempPoint4(pnt1, pnt2, pnt3);
connPoint = CoordinatesUtil.MidPoint(pnt1, pnt2);
} else if (count === 4) {
tempPoint4 = lnglatPoints[3];
connPoint = CoordinatesUtil.MidPoint(pnt1, pnt2);
} else {
tempPoint4 = lnglatPoints[3];
connPoint = lnglatPoints[4];
}
let leftArrowPnts: number[][];
let rightArrowPnts;
let isCW = isClockWise(pnt1, pnt2, pnt3);
if (isCW) {
leftArrowPnts = getPincerAttackArrowPoints(pnt1, connPoint, tempPoint4, false,headHeightFactor,headWidthFactor,neckWidthFactor,neckHeightFactor);
rightArrowPnts = getPincerAttackArrowPoints(connPoint, pnt2, pnt3, true,headHeightFactor,headWidthFactor,neckWidthFactor,neckHeightFactor);
} else {
leftArrowPnts = getPincerAttackArrowPoints(pnt2, connPoint, pnt3, false,headHeightFactor,headWidthFactor,neckWidthFactor,neckHeightFactor);
rightArrowPnts = getPincerAttackArrowPoints(connPoint, pnt1, tempPoint4, true,headHeightFactor,headWidthFactor,neckWidthFactor,neckHeightFactor);
}
const m = leftArrowPnts.length;
const t = (m - 5) / 2;
const llBodyPnts = leftArrowPnts.slice(0, t);
const lArrowPnts = leftArrowPnts.slice(t, t + 5);
let lrBodyPnts = leftArrowPnts.slice(t + 5, m);
let rlBodyPnts = rightArrowPnts.slice(0, t);
const rArrowPnts = rightArrowPnts.slice(t, t + 5);
const rrBodyPnts = rightArrowPnts.slice(t + 5, m);
rlBodyPnts = getBezierPoints(rlBodyPnts);
const bodyPnts = getBezierPoints(rrBodyPnts.concat(llBodyPnts.slice(1)));
lrBodyPnts = getBezierPoints(lrBodyPnts);
const pnts: number[][] = rlBodyPnts.concat(rArrowPnts, bodyPnts, lArrowPnts, lrBodyPnts);
const temp: number[] = ([] as number[]).concat(...pnts);
const cartesianPoints = Cartesian3.fromDegreesArray(temp);
return cartesianPoints;
}
上述代码封装层级较多,完整源码请关注原文Cesium+Vue3学习系列(12)---态势标绘 钳形攻击箭头(双箭头)标绘与编辑