From cbd43ac95a01d166a09dbf4983f27c2cccac234e Mon Sep 17 00:00:00 2001 From: Yuan Date: Thu, 15 Jun 2023 17:18:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=81=93=E5=B2=94=E7=BC=96=E8=BE=91=E5=90=B8?= =?UTF-8?q?=E9=99=84=E6=96=B9=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drawApp/graphics/TurnoutInteraction.ts | 18 +-- src/graphics/section/SectionDrawAssistant.ts | 40 ++--- src/graphics/turnout/Turnout.ts | 26 ++-- src/graphics/turnout/TurnoutDrawAssistant.ts | 154 +++++++++++-------- src/protos/stationLayoutGraphics.ts | 103 ++++--------- xian-ncc-da-message | 2 +- 6 files changed, 170 insertions(+), 173 deletions(-) diff --git a/src/drawApp/graphics/TurnoutInteraction.ts b/src/drawApp/graphics/TurnoutInteraction.ts index 1cc5184..f390b41 100644 --- a/src/drawApp/graphics/TurnoutInteraction.ts +++ b/src/drawApp/graphics/TurnoutInteraction.ts @@ -26,23 +26,23 @@ export class TurnoutData extends GraphicDataBase implements ITurnoutData { set code(v: string) { this.data.code = v; } - get pointA(): IPointData { + get pointA(): IPointData[] { return this.data.pointA; } - set pointA(v: IPointData) { - this.data.pointA = new graphicData.Point({ x: v.x, y: v.y }); + set pointA(v: IPointData[]) { + this.data.pointA = v.map((p) => new graphicData.Point({ x: p.x, y: p.y })); } - get pointB(): IPointData { + get pointB(): IPointData[] { return this.data.pointB; } - set pointB(v: IPointData) { - this.data.pointB = new graphicData.Point({ x: v.x, y: v.y }); + set pointB(v: IPointData[]) { + this.data.pointB = v.map((p) => new graphicData.Point({ x: p.x, y: p.y })); } - get pointC(): IPointData { + get pointC(): IPointData[] { return this.data.pointC; } - set pointC(v: IPointData) { - this.data.pointC = new graphicData.Point({ x: v.x, y: v.y }); + set pointC(v: IPointData[]) { + this.data.pointC = v.map((p) => new graphicData.Point({ x: p.x, y: p.y })); } clone(): TurnoutData { return new TurnoutData(this.data.cloneMessage()); diff --git a/src/graphics/section/SectionDrawAssistant.ts b/src/graphics/section/SectionDrawAssistant.ts index 8400561..c0e75f0 100644 --- a/src/graphics/section/SectionDrawAssistant.ts +++ b/src/graphics/section/SectionDrawAssistant.ts @@ -28,6 +28,7 @@ import { PolylineEditPlugin, } from 'src/jl-graphic/plugins/GraphicEditPlugin'; import AbsorbablePoint, { + AbsorbableLine, AbsorbablePosition, } from 'src/jl-graphic/graphic/AbsorbablePosition'; import { Turnout } from '../turnout/Turnout'; @@ -112,16 +113,18 @@ function buildAbsorbablePositions(section: Section): AbsorbablePosition[] { const sections = section.queryStore.queryByType
(Section.Type); sections.forEach((other) => { - if (other.id == section.id) { - return; - } - const apa = new AbsorbablePoint( - other.localToCanvasPoint(other.getStartPoint()) - ); - const apb = new AbsorbablePoint( - other.localToCanvasPoint(other.getEndPoint()) - ); - aps.push(apa, apb); + const [ps, pe] = [ + other.localToCanvasPoint(other.getStartPoint()), + other.localToCanvasPoint(other.getEndPoint()), + ]; + const apa = new AbsorbablePoint(ps); + const apb = new AbsorbablePoint(pe); + const { width, height } = section.getGraphicApp().canvas; + const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y }); + const ys = new AbsorbableLine({ x: ps.x, y: 0 }, { x: ps.x, y: height }); + const xe = new AbsorbableLine({ x: 0, y: pe.y }, { x: width, y: pe.y }); + const ye = new AbsorbableLine({ x: pe.x, y: 0 }, { x: pe.x, y: height }); + aps.push(apa, apb, xs, ys, xe, ye); }); const turnouts = section.queryStore.queryByType(Turnout.Type); @@ -140,16 +143,13 @@ function onEditPointCreate( index: number ): void { const section = g as Section; - if (index === 0 || index == section.datas.points.length - 1) { - // 端点 - dp.on('transformstart', (e: GraphicTransformEvent) => { - if (e.isShift()) { - section.getGraphicApp().setOptions({ - absorbablePositions: buildAbsorbablePositions(section), - }); - } - }); - } + dp.on('transformstart', (e: GraphicTransformEvent) => { + if (e.isShift()) { + section.getGraphicApp().setOptions({ + absorbablePositions: buildAbsorbablePositions(section), + }); + } + }); } class SectionPolylineEditPlugin extends PolylineEditPlugin { diff --git a/src/graphics/turnout/Turnout.ts b/src/graphics/turnout/Turnout.ts index e5c9a9b..041b10b 100644 --- a/src/graphics/turnout/Turnout.ts +++ b/src/graphics/turnout/Turnout.ts @@ -14,12 +14,12 @@ import { epsilon } from 'src/jl-graphic/math'; export interface ITurnoutData extends GraphicData { get code(): string; set code(code: string); - get pointA(): IPointData; - set pointA(point: IPointData); - get pointB(): IPointData; - set pointB(point: IPointData); - get pointC(): IPointData; - set pointC(point: IPointData); + get pointA(): IPointData[]; //A端点列表(从岔心向外) + set pointA(point: IPointData[]); + get pointB(): IPointData[]; + set pointB(point: IPointData[]); + get pointC(): IPointData[]; + set pointC(point: IPointData[]); clone(): ITurnoutData; copyFrom(data: ITurnoutData): void; eq(other: ITurnoutData): boolean; @@ -47,12 +47,15 @@ function getIntersectionPoint(r: number, p: IPointData): IPointData { } class TurnoutSection extends Graphics { - paint(p: IPointData, gap: number) { - const { x, y } = getIntersectionPoint(gap, p); + paint(pList: IPointData[], gap: number) { + const start = getIntersectionPoint(gap, pList[0]); this.clear() .lineStyle(TurnoutConsts.lineWidth, TurnoutConsts.lineColor) - .moveTo(p.x, p.y) - .lineTo(x, y); + .moveTo(start.x, start.y); + pList.forEach((p) => { + const { x, y } = p; + this.lineTo(x, y); + }); } } @@ -120,13 +123,12 @@ export class Turnout extends JlGraphic { this.graphics.sections.B.paint(pointB, 20); this.graphics.sections.C.paint(pointC, 20); - this.graphics.fork.paint(pointB); + this.graphics.fork.paint(pointB[0]); this.graphics.label.text = this.datas.code; } buildRelation(): void { - console.log('turnout build relation'); /** 道岔和区段 */ this.queryStore.queryByType
(Section.Type).forEach((section) => { this.getPortPoints().forEach((port, i) => { diff --git a/src/graphics/turnout/TurnoutDrawAssistant.ts b/src/graphics/turnout/TurnoutDrawAssistant.ts index 05c8ad6..8e60f2d 100644 --- a/src/graphics/turnout/TurnoutDrawAssistant.ts +++ b/src/graphics/turnout/TurnoutDrawAssistant.ts @@ -8,8 +8,10 @@ import { JlDrawApp, JlGraphic, VectorText, + calculateIntersectionPointOfCircleAndPoint, linePoint, pointBox, + polylinePoint, } from 'src/jl-graphic'; import { ITurnoutData, @@ -25,9 +27,10 @@ import { Point, } from 'pixi.js'; import { GraphicEditPlugin } from 'src/jl-graphic/plugins/GraphicEditPlugin'; -import Vector2 from 'src/jl-graphic/math/Vector2'; import { Section } from '../section/Section'; -import AbsorbablePoint from 'src/jl-graphic/graphic/AbsorbablePosition'; +import AbsorbablePoint, { + AbsorbableLine, +} from 'src/jl-graphic/graphic/AbsorbablePosition'; export class TurnoutDraw extends GraphicDrawAssistant< TurnoutTemplate, @@ -66,9 +69,9 @@ export class TurnoutDraw extends GraphicDrawAssistant< getDefaultEndPoint() { return { - pointA: new Point(50, 0), - pointB: new Point(-50, 0), - pointC: new Point(-50, -50), + pointA: [new Point(50, 0)], + pointB: [new Point(-50, 0)], + pointC: [new Point(-50, -50)], }; } @@ -89,9 +92,21 @@ export class TurnoutHitArea implements IHitArea { labelRect.x = labelPosition.x; labelRect.y = labelPosition.y; return ( - linePoint(pointA, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) || - linePoint(pointB, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) || - linePoint(pointC, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) || + polylinePoint( + [...pointA, { x: 0, y: 0 }], + { x, y }, + TurnoutConsts.lineWidth + ) || + polylinePoint( + [...pointB, { x: 0, y: 0 }], + { x, y }, + TurnoutConsts.lineWidth + ) || + polylinePoint( + [...pointC, { x: 0, y: 0 }], + { x, y }, + TurnoutConsts.lineWidth + ) || pointBox({ x, y }, labelRect) ); } @@ -113,10 +128,38 @@ function buildAbsorbablePositions(turnout: Turnout): AbsorbablePosition[] { const turnouts = turnout.queryStore.queryByType(Turnout.Type); turnouts.forEach((otherTurnout) => { - if (turnout.id === otherTurnout.id) return; - otherTurnout.getPortPoints().forEach((portPoint) => { - aps.push(new AbsorbablePoint(otherTurnout.localToCanvasPoint(portPoint))); + const { + pointA: [A], + pointB: [B], + pointC: [C], + } = otherTurnout.datas; + + [A, B, C].forEach((p) => { + aps.push( + new AbsorbableLine( + otherTurnout.localToCanvasPoint({ x: -5 * p.x, y: -5 * p.y }), + otherTurnout.localToCanvasPoint({ x: 5 * p.x, y: 5 * p.y }) + ) + ); }); + aps.push( + new AbsorbableLine( + otherTurnout.localToCanvasPoint({ x: 0, y: -500 }), + otherTurnout.localToCanvasPoint({ x: 0, y: 500 }) + ), + new AbsorbableLine( + otherTurnout.localToCanvasPoint({ x: -500, y: 0 }), + otherTurnout.localToCanvasPoint({ x: 500, y: 0 }) + ) + ); + + if (turnout.id !== otherTurnout.id) { + otherTurnout.getPortPoints().forEach((portPoint) => { + aps.push( + new AbsorbablePoint(otherTurnout.localToCanvasPoint(portPoint)) + ); + }); + } }); return aps; @@ -199,7 +242,7 @@ export interface ITurnoutEditOptions { export class TurnoutEditPlugin extends GraphicEditPlugin { static Name = 'TurnoutEdit'; options: ITurnoutEditOptions; - editPoints: DraggablePoint[] = []; + editPoints: DraggablePoint[][] = [[], [], []]; labels: VectorText[] = []; constructor(graphic: Turnout, options?: ITurnoutEditOptions) { @@ -215,51 +258,34 @@ export class TurnoutEditPlugin extends GraphicEditPlugin { } initEditPoints() { - const cpA = this.graphic.localToCanvasPoint(this.graphic.datas.pointA); - const cpB = this.graphic.localToCanvasPoint(this.graphic.datas.pointB); - const cpC = this.graphic.localToCanvasPoint(this.graphic.datas.pointC); - const cpMap: Map = new Map([ + const cpA = this.graphic.localToCanvasPoints(...this.graphic.datas.pointA); + const cpB = this.graphic.localToCanvasPoints(...this.graphic.datas.pointB); + const cpC = this.graphic.localToCanvasPoints(...this.graphic.datas.pointC); + const cpMap: Map = new Map([ [cpA, this.graphic.datas.pointA], [cpB, this.graphic.datas.pointB], [cpC, this.graphic.datas.pointC], ]); - cpMap.forEach((v, k) => { - const dp = new DraggablePoint(k); - dp.on('transforming', (e: GraphicTransformEvent) => { - if (k === cpA || k === cpB) { - const vecA = new Vector2([ - this.graphic.datas.pointA.x, - this.graphic.datas.pointA.y, - ]); - const vecB = new Vector2([ - this.graphic.datas.pointB.x, - this.graphic.datas.pointB.y, - ]); + Array.from(cpMap.entries()).forEach(([cpDatas, dataPoints], i) => { + cpDatas.forEach((cpData, j) => { + const dp = new DraggablePoint(cpData); + dp.on('transforming', (e: GraphicTransformEvent) => { + const localPoint = this.graphic.canvasToLocalPoint(dp.position); + dataPoints[j].x = localPoint.x; + dataPoints[j].y = localPoint.y; - if (k === cpA) { - const len = vecB.length(); - const res = vecA.normalize().scale(-len); - this.graphic.datas.pointB.x = res.x; - this.graphic.datas.pointB.y = res.y; - } else if (k === cpB) { - const len = vecA.length(); - const res = vecB.normalize().scale(-len); - this.graphic.datas.pointA.x = res.x; - this.graphic.datas.pointA.y = res.y; - } + this.graphic.repaint(); + }); + if (this.options.onEditPointCreate) { + this.options.onEditPointCreate(this.graphic, dp); } - const localPoint = this.graphic.canvasToLocalPoint(dp.position); - v.x = localPoint.x; - v.y = localPoint.y; - - this.graphic.repaint(); + this.editPoints[i].push(dp); }); - if (this.options.onEditPointCreate) { - this.options.onEditPointCreate(this.graphic, dp); - } - this.editPoints.push(dp); }); - this.addChild(...this.editPoints); + console.log(this.editPoints); + this.editPoints.forEach((cps) => { + this.addChild(...cps); + }); this.labels = ['A', 'B', 'C'].map((str) => { const vc = new VectorText(str); vc.setVectorFontSize(14); @@ -270,23 +296,27 @@ export class TurnoutEditPlugin extends GraphicEditPlugin { } destoryEditPoints() { - this.editPoints.forEach((dp) => { - dp.off('transforming'); - dp.destroy(); - this.removeChild(dp); + this.editPoints.forEach((dps) => { + dps.forEach((dp) => { + dp.off('transforming'); + dp.destroy(); + this.removeChild(dp); + }); }); - this.editPoints.splice(0, this.editPoints.length); + this.editPoints = [[], [], []]; } updateEditedPointsPosition() { - const cps = this.graphic.localToCanvasPoints( - this.graphic.datas.pointA, - this.graphic.datas.pointB, - this.graphic.datas.pointC - ); - cps.forEach((cp, i) => { - this.editPoints[i].position.copyFrom(cp); - this.labels[i].position.copyFrom({ x: cp.x, y: cp.y + 12 }); + const cpA = this.graphic.localToCanvasPoints(...this.graphic.datas.pointA); + const cpB = this.graphic.localToCanvasPoints(...this.graphic.datas.pointB); + const cpC = this.graphic.localToCanvasPoints(...this.graphic.datas.pointC); + [cpA, cpB, cpC].forEach((cps, i) => { + cps.forEach((cp, j) => { + this.editPoints[i][j].position.copyFrom(cp); + if (j === cps.length - 1) { + this.labels[i].position.copyFrom({ x: cp.x, y: cp.y + 12 }); + } + }); }); } } diff --git a/src/protos/stationLayoutGraphics.ts b/src/protos/stationLayoutGraphics.ts index 2c8cf1a..9c13250 100644 --- a/src/protos/stationLayoutGraphics.ts +++ b/src/protos/stationLayoutGraphics.ts @@ -2308,13 +2308,12 @@ export namespace graphicData { constructor(data?: any[] | { common?: CommonInfo; code?: string; - pointA?: Point; - pointB?: Point; - pointC?: Point; - labelOffset?: Point; + pointA?: Point[]; + pointB?: Point[]; + pointC?: Point[]; }) { super(); - pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); + pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [6, 7, 8], this.#one_of_decls); if (!Array.isArray(data) && typeof data == "object") { if ("common" in data && data.common != undefined) { this.common = data.common; @@ -2331,9 +2330,6 @@ export namespace graphicData { if ("pointC" in data && data.pointC != undefined) { this.pointC = data.pointC; } - if ("labelOffset" in data && data.labelOffset != undefined) { - this.labelOffset = data.labelOffset; - } } } get common() { @@ -2352,48 +2348,29 @@ export namespace graphicData { pb_1.Message.setField(this, 2, value); } get pointA() { - return pb_1.Message.getWrapperField(this, Point, 6) as Point; + return pb_1.Message.getRepeatedWrapperField(this, Point, 6) as Point[]; } - set pointA(value: Point) { - pb_1.Message.setWrapperField(this, 6, value); - } - get has_pointA() { - return pb_1.Message.getField(this, 6) != null; + set pointA(value: Point[]) { + pb_1.Message.setRepeatedWrapperField(this, 6, value); } get pointB() { - return pb_1.Message.getWrapperField(this, Point, 7) as Point; + return pb_1.Message.getRepeatedWrapperField(this, Point, 7) as Point[]; } - set pointB(value: Point) { - pb_1.Message.setWrapperField(this, 7, value); - } - get has_pointB() { - return pb_1.Message.getField(this, 7) != null; + set pointB(value: Point[]) { + pb_1.Message.setRepeatedWrapperField(this, 7, value); } get pointC() { - return pb_1.Message.getWrapperField(this, Point, 8) as Point; + return pb_1.Message.getRepeatedWrapperField(this, Point, 8) as Point[]; } - set pointC(value: Point) { - pb_1.Message.setWrapperField(this, 8, value); - } - get has_pointC() { - return pb_1.Message.getField(this, 8) != null; - } - get labelOffset() { - return pb_1.Message.getWrapperField(this, Point, 9) as Point; - } - set labelOffset(value: Point) { - pb_1.Message.setWrapperField(this, 9, value); - } - get has_labelOffset() { - return pb_1.Message.getField(this, 9) != null; + set pointC(value: Point[]) { + pb_1.Message.setRepeatedWrapperField(this, 8, value); } static fromObject(data: { common?: ReturnType; code?: string; - pointA?: ReturnType; - pointB?: ReturnType; - pointC?: ReturnType; - labelOffset?: ReturnType; + pointA?: ReturnType[]; + pointB?: ReturnType[]; + pointC?: ReturnType[]; }): Turnout { const message = new Turnout({}); if (data.common != null) { @@ -2403,16 +2380,13 @@ export namespace graphicData { message.code = data.code; } if (data.pointA != null) { - message.pointA = Point.fromObject(data.pointA); + message.pointA = data.pointA.map(item => Point.fromObject(item)); } if (data.pointB != null) { - message.pointB = Point.fromObject(data.pointB); + message.pointB = data.pointB.map(item => Point.fromObject(item)); } if (data.pointC != null) { - message.pointC = Point.fromObject(data.pointC); - } - if (data.labelOffset != null) { - message.labelOffset = Point.fromObject(data.labelOffset); + message.pointC = data.pointC.map(item => Point.fromObject(item)); } return message; } @@ -2420,10 +2394,9 @@ export namespace graphicData { const data: { common?: ReturnType; code?: string; - pointA?: ReturnType; - pointB?: ReturnType; - pointC?: ReturnType; - labelOffset?: ReturnType; + pointA?: ReturnType[]; + pointB?: ReturnType[]; + pointC?: ReturnType[]; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -2432,16 +2405,13 @@ export namespace graphicData { data.code = this.code; } if (this.pointA != null) { - data.pointA = this.pointA.toObject(); + data.pointA = this.pointA.map((item: Point) => item.toObject()); } if (this.pointB != null) { - data.pointB = this.pointB.toObject(); + data.pointB = this.pointB.map((item: Point) => item.toObject()); } if (this.pointC != null) { - data.pointC = this.pointC.toObject(); - } - if (this.labelOffset != null) { - data.labelOffset = this.labelOffset.toObject(); + data.pointC = this.pointC.map((item: Point) => item.toObject()); } return data; } @@ -2453,14 +2423,12 @@ export namespace graphicData { writer.writeMessage(1, this.common, () => this.common.serialize(writer)); if (this.code.length) writer.writeString(2, this.code); - if (this.has_pointA) - writer.writeMessage(6, this.pointA, () => this.pointA.serialize(writer)); - if (this.has_pointB) - writer.writeMessage(7, this.pointB, () => this.pointB.serialize(writer)); - if (this.has_pointC) - writer.writeMessage(8, this.pointC, () => this.pointC.serialize(writer)); - if (this.has_labelOffset) - writer.writeMessage(9, this.labelOffset, () => this.labelOffset.serialize(writer)); + if (this.pointA.length) + writer.writeRepeatedMessage(6, this.pointA, (item: Point) => item.serialize(writer)); + if (this.pointB.length) + writer.writeRepeatedMessage(7, this.pointB, (item: Point) => item.serialize(writer)); + if (this.pointC.length) + writer.writeRepeatedMessage(8, this.pointC, (item: Point) => item.serialize(writer)); if (!w) return writer.getResultBuffer(); } @@ -2477,16 +2445,13 @@ export namespace graphicData { message.code = reader.readString(); break; case 6: - reader.readMessage(message.pointA, () => message.pointA = Point.deserialize(reader)); + reader.readMessage(message.pointA, () => pb_1.Message.addToRepeatedWrapperField(message, 6, Point.deserialize(reader), Point)); break; case 7: - reader.readMessage(message.pointB, () => message.pointB = Point.deserialize(reader)); + reader.readMessage(message.pointB, () => pb_1.Message.addToRepeatedWrapperField(message, 7, Point.deserialize(reader), Point)); break; case 8: - reader.readMessage(message.pointC, () => message.pointC = Point.deserialize(reader)); - break; - case 9: - reader.readMessage(message.labelOffset, () => message.labelOffset = Point.deserialize(reader)); + reader.readMessage(message.pointC, () => pb_1.Message.addToRepeatedWrapperField(message, 8, Point.deserialize(reader), Point)); break; default: reader.skipField(); } diff --git a/xian-ncc-da-message b/xian-ncc-da-message index b0bc3b6..eec3d3f 160000 --- a/xian-ncc-da-message +++ b/xian-ncc-da-message @@ -1 +1 @@ -Subproject commit b0bc3b6100b9dbe5fd02a9e8cd2515c840ebf2a8 +Subproject commit eec3d3f6eff222e69479abb5e0bd36f29f883382