本学习系列将以Cesium + Vue3 + Vite +Typescript+elementplus作为主要技术栈展开,后续会循序渐进,持续探索Cesium的高级功能,相关源码全部免费公开。 请关注微信公众号 “webgis学习”或扫描下方二维码,关注后,在公众号里输入“Cesium学习系列源码”,即可看到本系列全部代码。

前两篇介绍如何标绘和编辑普通的点、线、多边形。本篇在之前的基础上扩展到态势标绘中的直箭头、细直线箭头的绘制和编辑。先看效果

1、直箭头画法:新建StraightArrow类继承自BaseDraw,通过createStraightArrowPoints函数进行更新关键点数据。
import { BaseDraw, GeometryType } from "../BaseDraw";
import { CallbackProperty, Cartesian3, ClassificationType, Color, Entity, PolygonGraphics, Viewer } from "cesium";
import { createStraightArrowPoints } from "@/system/Utils/SituationUtil";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
export default class StraightArrow extends BaseDraw {
private tempCursor = new Cartesian3();
constructor(viewer: Viewer, dispatcher: EventDispatcher) {
super(viewer, dispatcher);
this.geometryType = GeometryType.STRAIGHT_ARROW;
this.minPointCount = 2;
}
protected buildFinalEntity(): Entity {
const geometryPoints = createStraightArrowPoints(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 == 0) return undefined;
return this.viewer.entities.add({
polygon: new PolygonGraphics({
hierarchy: new CallbackProperty(() => ({
positions: createStraightArrowPoints([...this.getPositions(), this.tempCursor || new Cartesian3()])
}), false),
classificationType: ClassificationType.BOTH,
material: Color.CYAN.withAlpha(0.3)
})
});
}
protected onLeftClick(e: any) {
super.onLeftClick(e);
// 点只需要 2 次点击即可结束
if (this.getPositions().length == 2) {
this.finish();
}
}
protected updateTempEntity(cursor: Cartesian3) {
this.tempCursor = cursor;
}
}
* 创建一条直箭头
* @param positions 箭头的起点和终点
* @param tailWidthFactor 尾端宽度因子
* @param neckWidthFactor 颈部宽度因子
* @param headWidthFactor 头端宽度因子
* @param headAngle 头端角度
* @param neckAngle 颈部角度
* @returns 箭头的点数组
*/
export const createStraightArrowPoints = (positions: Cartesian3[], tailWidthFactor: number=0.1, neckWidthFactor: number=0.2, headWidthFactor: number=0.25, headAngle: number=Math.PI/8.5, neckAngle: number=Math.PI/13) => {
const firstPnt = CoordinatesUtil.Cartesian2Wgs84Lonlat(positions[0]);
const lastPnt = CoordinatesUtil.Cartesian2Wgs84Lonlat(positions[1]);
const distance = MathDistance([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]]);
const tailWidth = distance * tailWidthFactor;
const neckWidth = distance * neckWidthFactor;
const headWidth = distance * headWidthFactor;
const tailLeft = getThirdPoint([lastPnt[0], lastPnt[1]], [firstPnt[0], firstPnt[1]], Math.PI / 2, tailWidth, true);
const tailRight = getThirdPoint([lastPnt[0], lastPnt[1]], [firstPnt[0], firstPnt[1]], Math.PI / 2, tailWidth, false);
const headLeft = getThirdPoint([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]], headAngle, headWidth, false);
const headRight = getThirdPoint([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]], headAngle, headWidth, true);
const neckLeft = getThirdPoint([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]], neckAngle, neckWidth, false);
const neckRight = getThirdPoint([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]], neckAngle, neckWidth, true);
const points = [...tailLeft, ...neckLeft, ...headLeft, ...lastPnt, ...headRight, ...neckRight, ...tailRight, ...firstPnt];
const cartesianPoints = Cartesian3.fromDegreesArray(points);
return cartesianPoints;
}
2、细直线箭头画法:新建StraightLineArrow类,继承继承自BaseDraw,通过createStraightLineArrowPoints函数进行更新关键点数据。
import { CallbackProperty, Cartesian3, Color, Entity, PolylineGraphics, Viewer } from "cesium";
import { BaseDraw, GeometryType } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
import { createStraightLineArrowPoints } from "@/system/Utils/SituationUtil";
export default class StraightLineArrow extends BaseDraw {
private tempCursor?: Cartesian3;
constructor(viewer: Viewer, dispatcher: EventDispatcher) {
super(viewer, dispatcher);
this.geometryType = GeometryType.STRAIGHT_LINE_ARROW;
this.minPointCount = 2;
}
protected buildFinalEntity(): Entity {
return this.viewer.entities.add({
polyline: new PolylineGraphics({
positions: new CallbackProperty(() => createStraightLineArrowPoints(this.getPositions()), false),
width: 3,
material: Color.ORANGE,
clampToGround: true
})
});
}
protected buildTempEntity(): Entity | undefined {
if(this.getPositions().length == 0) return undefined;
return this.viewer.entities.add({
polyline: new PolylineGraphics({
positions: new CallbackProperty(() => createStraightLineArrowPoints([...this.getPositions(), this.tempCursor || new Cartesian3()]), false),
width: 3,
material: Color.YELLOW.withAlpha(0.6),
clampToGround: true
})
});
}
protected updateTempEntity(cursor: Cartesian3) {
this.tempCursor = cursor;
}
protected onLeftClick(e: any) {
super.onLeftClick(e);
// 需要 2 次点击即可结束
if (this.getPositions().length == 2) {
this.finish();
}
}
}
/**
* 创建一条直线箭头
* @param positions 直箭头的起点和终点
* @param arrowLengthScale 箭头长度缩放因子
* @param maxArrowLength 最大箭头长度
* @param minPointsForShape 最小点数以形成形状
* @returns 直箭头的点数组
*/
export const createStraightLineArrowPoints = (positions: Cartesian3[],arrowLengthScale:number=5,maxArrowLength: number = 3000000) => {
const firstPnt = CoordinatesUtil.Cartesian2Wgs84Lonlat(positions[0]);
const lastPnt = CoordinatesUtil.Cartesian2Wgs84Lonlat(positions[1]);
const distance = MathDistance([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]]);
let len = distance / arrowLengthScale;
len = len > maxArrowLength ? maxArrowLength : len;
const leftPnt = getThirdPoint([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]], Math.PI / 6, len / 2, false);
const rightPnt = getThirdPoint([firstPnt[0], firstPnt[1]], [lastPnt[0], lastPnt[1]], Math.PI / 6, len / 2, true);
const points = [...firstPnt, ...lastPnt, ...leftPnt, ...lastPnt, ...rightPnt];
const cartesianPoints = Cartesian3.fromDegreesArray(points);
return cartesianPoints;
}
3、在EditHelper.ts中修改updateShape函数
/** 更新被编辑的图形 */
private updateShape() {
switch (this.geometryType) {
case GeometryType.COMMON_POLYGON:
this.shapeEntity.polygon!.hierarchy = new CallbackProperty(() => new PolygonHierarchy(this.positions), false);
break;
case GeometryType.COMMON_LINE:
this.shapeEntity.polyline!.positions = new CallbackProperty(() => this.positions, false);
break;
case GeometryType.COMMON_POINT:
this.shapeEntity.position = new ConstantPositionProperty(this.positions[this.positions.length - 1]);
break;
case GeometryType.STRAIGHT_ARROW:
this.shapeEntity.polygon!.hierarchy = new CallbackProperty(() => new PolygonHierarchy(createStraightArrowPoints(this.positions)), false);
break;
case GeometryType.STRAIGHT_LINE_ARROW:
this.shapeEntity.polyline!.positions = new CallbackProperty(() => createStraightLineArrowPoints(this.positions), false);
break;
}
}
4、实现效果

5、更多详细代码,请关注微信公众号“webgis学习”,回复“Cesium学习系列源码”,即可看到本系列全部代码。


599

被折叠的 条评论
为什么被折叠?



