diff --git a/examples/index.ts b/examples/index.ts index 3f53482..2c1caec 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -27,6 +27,7 @@ const viewer = new Cesium.Viewer('cesiumContainer', { contextOptions: { requestWebgl2: true, }, + // msaaSamples: 4, }); viewer.scene.postProcessStages.fxaa.enabled = true; @@ -58,3 +59,8 @@ const swallowtailSquadCombat = document.getElementById('drawSwallowtailSquadComb swallowtailSquadCombat.onclick = () => { new CesiumPlot.SwallowtailSquadCombat(Cesium, viewer, {}); }; + +const straightArrow = document.getElementById('drawStraightArrow') as HTMLElement; +straightArrow.onclick = () => { + new CesiumPlot.StraightArrow(Cesium, viewer, {}); +}; diff --git a/index.html b/index.html index 9e48d9b..0b9f0c7 100644 --- a/index.html +++ b/index.html @@ -39,6 +39,7 @@
+ diff --git a/src/arrow/attack-arrow.ts b/src/arrow/attack-arrow.ts index d8cf289..f4004dc 100644 --- a/src/arrow/attack-arrow.ts +++ b/src/arrow/attack-arrow.ts @@ -9,10 +9,12 @@ export default class AttackArrow extends Draw { neckHeightFactor: number; neckWidthFactor: number; headTailFactor: number; + type: 'polygon' | 'line'; constructor(cesium: any, viewer: any, style: any) { super(cesium, viewer); this.cesium = cesium; + this.type = 'polygon'; this.headHeightFactor = 0.18; this.headWidthFactor = 0.3; this.neckHeightFactor = 0.85; @@ -31,7 +33,7 @@ export default class AttackArrow extends Draw { this.onMouseMove(); } else if (this.points.length === 2) { this.setGeometryPoints(this.points); - this.addToMap(); + this.drawPolygon(); } else { this.lineEntity && this.viewer.entities.remove(this.lineEntity); } @@ -48,7 +50,7 @@ export default class AttackArrow extends Draw { } else { const geometryPoints = this.createPolygon(tempPoints); this.setGeometryPoints(geometryPoints); - this.addToMap(); + this.drawPolygon(); } } @@ -141,6 +143,6 @@ export default class AttackArrow extends Draw { this.points[index] = cartesian; const geometryPoints = this.createPolygon(this.points); this.setGeometryPoints(geometryPoints); - this.addToMap(); + this.drawPolygon(); } } diff --git a/src/arrow/fine-arrow.ts b/src/arrow/fine-arrow.ts index e8015f6..ca40bcb 100644 --- a/src/arrow/fine-arrow.ts +++ b/src/arrow/fine-arrow.ts @@ -11,10 +11,12 @@ export default class FineArrow extends Draw { headWidthFactor: number; headAngle: number; neckAngle: number; + type: 'polygon' | 'line'; constructor(cesium: any, viewer: any, style: any) { super(cesium, viewer); this.cesium = cesium; + this.type = 'polygon'; this.tailWidthFactor = 0.1; this.neckWidthFactor = 0.2; this.headWidthFactor = 0.25; @@ -34,7 +36,7 @@ export default class FineArrow extends Draw { if (this.points.length === 2) { const geometryPoints = this.createPolygon(this.points); this.setGeometryPoints(geometryPoints); - this.addToMap(); + this.drawPolygon(); this.finishDrawing(); } } @@ -46,7 +48,7 @@ export default class FineArrow extends Draw { const tempPoints = [...this.points, cartesian]; const geometryPoints = this.createPolygon(tempPoints); this.setGeometryPoints(geometryPoints); - this.addToMap(); + this.drawPolygon(); } /** @@ -56,7 +58,7 @@ export default class FineArrow extends Draw { this.points[index] = cartesian; const geometryPoints = this.createPolygon(this.points); this.setGeometryPoints(geometryPoints); - this.addToMap(); + this.drawPolygon(); } /** diff --git a/src/arrow/squad-combat.ts b/src/arrow/squad-combat.ts index 9471cc1..ac21d0e 100644 --- a/src/arrow/squad-combat.ts +++ b/src/arrow/squad-combat.ts @@ -9,16 +9,17 @@ export default class SquadCombat extends AttackArrow { neckHeightFactor: number; neckWidthFactor: number; tailWidthFactor: number; + type: 'polygon' | 'line'; constructor(cesium: any, viewer: any, style: any) { super(cesium, viewer, {}); - + this.cesium = cesium; + this.type = 'polygon'; this.headHeightFactor = 0.18; this.headWidthFactor = 0.3; this.neckHeightFactor = 0.85; this.neckWidthFactor = 0.15; this.tailWidthFactor = 0.1; - this.cesium = cesium; } /** @@ -32,7 +33,7 @@ export default class SquadCombat extends AttackArrow { } else { const geometryPoints = this.createPolygon(tempPoints); this.setGeometryPoints(geometryPoints); - this.addToMap(); + this.drawPolygon(); } } diff --git a/src/arrow/straight-arrow.ts b/src/arrow/straight-arrow.ts new file mode 100644 index 0000000..39454b1 --- /dev/null +++ b/src/arrow/straight-arrow.ts @@ -0,0 +1,72 @@ +import * as Utils from '../utils'; +import Draw from '../draw'; +import { Cartesian3 } from '@examples/cesium'; + +export default class StraightArrow extends Draw { + points: Cartesian3[] = []; + arrowLengthScale: number = 5; + maxArrowLength: number = 2; + type: 'polygon' | 'line'; + + constructor(cesium: any, viewer: any, style: any) { + super(cesium, viewer); + this.cesium = cesium; + this.type = 'line'; + this.setState('drawing'); + } + + /** + * Add points only on click events + */ + addPoint(cartesian: Cartesian3) { + if (this.points.length < 2) { + this.points.push(cartesian); + this.onMouseMove(); + } + if (this.points.length === 2) { + const geometryPoints = this.createLine(this.points); + this.setGeometryPoints(geometryPoints); + this.drawLine(); + this.finishDrawing(); + } + } + + /** + * Draw a shape based on mouse movement points during the initial drawing. + */ + updateMovingPoint(cartesian: Cartesian3) { + const tempPoints = [...this.points, cartesian]; + const geometryPoints = this.createLine(tempPoints); + this.setGeometryPoints(geometryPoints); + this.drawLine(); + } + + /** + * In edit mode, drag key points to update corresponding key point data. + */ + updateDraggingPoint(cartesian: Cartesian3, index: number) { + this.points[index] = cartesian; + const geometryPoints = this.createLine(this.points); + this.setGeometryPoints(geometryPoints); + this.drawLine(); + } + + /** + * Generate geometric shapes based on key points. + */ + createLine(positions: Cartesian3[]) { + const [pnt1, pnt2] = positions.map(this.cartesianToLnglat); + const distance = Utils.MathDistance(pnt1, pnt2); + let len = distance / this.arrowLengthScale; + len = len > this.maxArrowLength ? this.maxArrowLength : len; + const leftPnt = Utils.getThirdPoint(pnt1, pnt2, Math.PI / 6, len, false); + const rightPnt = Utils.getThirdPoint(pnt1, pnt2, Math.PI / 6, len, true); + const points = [...pnt1, ...pnt2, ...leftPnt, ...pnt2, ...rightPnt]; + const cartesianPoints = this.cesium.Cartesian3.fromDegreesArray(points); + return cartesianPoints; + } + + getPoints() { + return this.points; + } +} diff --git a/src/arrow/swallowtail-attack-arrow.ts b/src/arrow/swallowtail-attack-arrow.ts index 7f78a22..b792f2c 100644 --- a/src/arrow/swallowtail-attack-arrow.ts +++ b/src/arrow/swallowtail-attack-arrow.ts @@ -12,10 +12,13 @@ export default class SwallowtailAttackArrow extends AttackArrow { tailWidthFactor: number; swallowTailFactor: number; swallowTailPnt: [number, number]; + type: 'polygon' | 'line'; constructor(cesium: any, viewer: any, style: any) { super(cesium, viewer, {}); + this.cesium = cesium; + this.type = 'polygon'; this.headHeightFactor = 0.18; this.headWidthFactor = 0.3; this.neckHeightFactor = 0.85; @@ -24,7 +27,6 @@ export default class SwallowtailAttackArrow extends AttackArrow { this.headTailFactor = 0.8; this.swallowTailFactor = 1; this.swallowTailPnt = [0, 0]; - this.cesium = cesium; } /** diff --git a/src/arrow/swallowtail-squad-combat.ts b/src/arrow/swallowtail-squad-combat.ts index 6055316..1a6dc44 100644 --- a/src/arrow/swallowtail-squad-combat.ts +++ b/src/arrow/swallowtail-squad-combat.ts @@ -10,17 +10,19 @@ export default class SwallowtailSquadCombat extends SquadCombat { neckWidthFactor: number; tailWidthFactor: number; swallowTailFactor: number; + type: 'polygon' | 'line'; constructor(cesium: any, viewer: any, style: any) { super(cesium, viewer, {}); + this.cesium = cesium; + this.type = 'polygon'; this.headHeightFactor = 0.18; this.headWidthFactor = 0.3; this.neckHeightFactor = 0.85; this.neckWidthFactor = 0.15; this.tailWidthFactor = 0.1; this.swallowTailFactor = 1; - this.cesium = cesium; } /** diff --git a/src/draw.ts b/src/draw.ts index 1682974..149fd40 100644 --- a/src/draw.ts +++ b/src/draw.ts @@ -11,6 +11,7 @@ export default class Draw { controlPoints: CesiumTypeOnly.EntityCollection = []; controlPointsEventHandler: CesiumTypeOnly.ScreenSpaceEventHandler; lineEntity: CesiumTypeOnly.Entity; + type!: 'polygon' | 'line'; constructor(cesium: typeof CesiumTypeOnly, viewer: CesiumTypeOnly.Viewer) { this.cesium = cesium; @@ -44,6 +45,11 @@ export default class Draw { this.eventHandler.setInputAction((evt: any) => { const pickedObject = this.viewer.scene.pick(evt.position); const hitEntities = this.cesium.defined(pickedObject) && pickedObject.id instanceof CesiumTypeOnly.Entity; + let activeEntity = this.polygonEntity; + if (this.type === 'line') { + activeEntity = this.lineEntity; + } + if (this.state === 'drawing') { // In the drawing state, the points clicked are key nodes of the shape, and they are saved in this.points. const cartesian = this.pixelToCartesian(evt.position); @@ -56,13 +62,13 @@ export default class Draw { this.addPoint(cartesian); } else if (this.state === 'edit') { //In edit mode, exit the editing state and delete control points when clicking outside the currently edited shape. - if (!hitEntities || this.polygonEntity.id !== pickedObject.id.id) { + if (!hitEntities || activeEntity.id !== pickedObject.id.id) { this.setState('static'); this.removeControlPoints(); } } else if (this.state === 'static') { //When drawing multiple shapes, the click events for all shapes are triggered. Only when hitting a completed shape should it enter editing mode. - if (hitEntities && this.polygonEntity.id === pickedObject.id.id) { + if (hitEntities && activeEntity.id === pickedObject.id.id) { const pickedEntity = pickedObject.id; if (this.cesium.defined(pickedEntity.polygon)) { // Hit PolygonGraphics geometry. @@ -124,7 +130,7 @@ export default class Draw { return this.geometryPoints; } - addToMap() { + drawPolygon() { const callback = () => { return new this.cesium.PolygonHierarchy(this.geometryPoints); }; diff --git a/src/index.ts b/src/index.ts index 310b2c1..882c378 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import AttackArrow from './arrow/attack-arrow'; import SwallowtailAttackArrow from './arrow/swallowtail-attack-arrow'; import SquadCombat from './arrow/squad-combat'; import SwallowtailSquadCombat from './arrow/swallowtail-squad-combat'; +import StraightArrow from './arrow/straight-arrow'; const CesiumPlot = { FineArrow, @@ -10,6 +11,7 @@ const CesiumPlot = { SwallowtailAttackArrow, SquadCombat, SwallowtailSquadCombat, + StraightArrow, }; export default CesiumPlot;