Merge branch 'master' of git.code.tencent.com:xian-ncc-da/xian-ncc-da-client

This commit is contained in:
Yuan 2023-06-28 13:49:26 +08:00
commit c5d9661337
19 changed files with 475 additions and 124 deletions

View File

@ -75,6 +75,9 @@
<train-window-property
v-else-if="drawStore.selectedGraphicType === TrainWindow.Type"
></train-window-property>
<path-line-property
v-else-if="drawStore.selectedGraphicType === PathLine.Type"
></path-line-property>
<axle-counting-property
v-else-if="drawStore.selectedGraphicType === AxleCounting.Type"
></axle-counting-property>
@ -104,6 +107,7 @@ import SignalProperty from './properties/SignalProperty.vue';
import TurnoutProperty from './properties/TurnoutProperty.vue';
import SectionProperty from './properties/SectionProperty.vue';
import RunLineProperty from './properties/RunLineProperty.vue';
import PathLineProperty from './properties/PathLineProperty.vue';
import { Link } from 'src/graphics/link/Link';
import { Rect } from 'src/graphics/rect/Rect';
import { Platform } from 'src/graphics/platform/Platform';
@ -117,6 +121,7 @@ import { Turnout } from 'src/graphics/turnout/Turnout';
import { RunLine } from 'src/graphics/runLine/RunLine';
import { Section } from 'src/graphics/section/Section';
import { TrainWindow } from 'src/graphics/trainWindow/TrainWindow';
import { PathLine } from 'src/graphics/pathLine/PathLine';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
const drawStore = useDrawStore();

View File

@ -25,14 +25,33 @@
lazy-rules
autogrow
/>
<q-list bordered separator class="rounded-borders">
<q-item>
<q-item-section no-wrap class="q-gutter-y-sm column">
<q-item-label> 关联的区段 </q-item-label>
<div class="q-gutter-sm row">
<q-chip
v-for="item in sectionRelations"
:key="item.id"
square
color="primary"
text-color="white"
>
{{ item }}
</q-chip>
</div>
</q-item-section>
</q-item>
</q-list>
</q-form>
</template>
<script setup lang="ts">
import { AxleCountingData } from 'src/drawApp/graphics/AxleCountingInteraction';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { Section } from 'src/graphics/section/Section';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { computed, onMounted, reactive, watch } from 'vue';
const drawStore = useDrawStore();
const axleCountingModel = reactive(new AxleCountingData());
@ -62,4 +81,19 @@ function onUpdate() {
.updateGraphicAndRecord(axleCounting, axleCountingModel);
}
}
const sectionRelations = computed(() => {
const axleCounting = drawStore.selectedGraphic as AxleCounting;
const sectionRelations =
axleCounting?.relationManage.getRelationsOfGraphicAndOtherType(
axleCounting,
Section.Type
);
return sectionRelations.map(
(relation) =>
`${relation.getOtherGraphic<Section>(axleCounting).datas.code}(${
relation.getOtherRelationParam(axleCounting).param
})`
);
});
</script>

View File

@ -0,0 +1,70 @@
<template>
<q-form>
<q-input outlined readonly v-model="pathLineModel.id" label="id" hint="" />
<q-checkbox
v-model="pathLineModel.isUp"
label="是否上行"
@update:model-value="onUpdate"
/>
<template :key="item" v-for="item in pathLineModel.kilometerPoints">
<div style="display: flex; margin-top: 5px">
<q-input
outlined
v-model.number="item.point.x"
type="number"
@blur="onUpdate"
:label="`${item.stName}x:`"
/>
<q-input
outlined
v-model.number="item.point.y"
type="number"
@blur="onUpdate"
:label="`${item.stName}y:`"
/>
</div>
<div style="display: flex; margin-top: 5px">
<q-input outlined readonly v-model="item.stName" label="车站" hint="" />
<q-input
outlined
v-model.number="item.kilometer"
type="number"
@blur="onUpdate"
:label="`${item.stName}公里标:`"
/>
</div>
</template>
</q-form>
</template>
<script setup lang="ts">
import { PathLineData } from 'src/drawApp/graphics/PathLineInteraction';
import { PathLine } from 'src/graphics/pathLine/PathLine';
import { useDrawStore } from 'src/stores/draw-store';
import { reactive, onMounted, watch } from 'vue';
const drawStore = useDrawStore();
const pathLineModel = reactive(new PathLineData());
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == PathLine.Type) {
pathLineModel.copyFrom(val.saveData() as PathLineData);
}
}
);
onMounted(() => {
const pathLine = drawStore.selectedGraphic as PathLine;
if (pathLine) {
pathLineModel.copyFrom(pathLine.saveData());
}
});
function onUpdate() {
const pathLine = drawStore.selectedGraphic as PathLine;
if (pathLine) {
drawStore.getDrawApp().updateGraphicAndRecord(pathLine, pathLineModel);
}
}
</script>

View File

@ -142,7 +142,6 @@ onMounted(() => {
function onUpdate() {
const runLine = drawStore.selectedGraphic as RunLine;
console.log(runLineModel, '*******');
if (runLine) {
drawStore.getDrawApp().updateGraphicAndRecord(runLine, runLineModel);
}

View File

@ -16,6 +16,11 @@
lazy-rules
autogrow
/>
<q-checkbox
v-model="stationLineModel.hideName"
label="名称是否隐藏"
@update:model-value="onUpdate"
/>
<q-select
outlined
@blur="onUpdate"

View File

@ -37,11 +37,11 @@ export class AxleCountingData
set kilometerCode(v: string) {
this.data.kilometerCode = v;
}
get sectionId(): string[] {
return this.data.sectionId;
get axleCountingRef(): graphicData.RelatedRef[] {
return this.data.axleCountingRef;
}
set sectionId(sectionIds: string[]) {
this.data.sectionId = sectionIds;
set axleCountingRef(points: graphicData.RelatedRef[]) {
this.data.axleCountingRef=points
}
clone(): AxleCountingData {
return new AxleCountingData(this.data.cloneMessage());

View File

@ -39,6 +39,12 @@ export class PathLineData extends GraphicDataBase implements IPathLineData {
(p) => new graphicData.Point({ x: p.x, y: p.y })
);
}
get isUp(): boolean {
return this.data.isUp;
}
set isUp(v: boolean) {
this.data.isUp = v;
}
get kilometerPoints(): KilometerPoint[] {
return this.data.kilometerPoints;
}
@ -48,6 +54,7 @@ export class PathLineData extends GraphicDataBase implements IPathLineData {
new graphicData.KilometerPoint({
point: new graphicData.Point({ x: p.point.x, y: p.point.y }),
kilometer: p.kilometer,
stName: p.stName,
})
);
}

View File

@ -39,6 +39,12 @@ export class SignalData extends GraphicDataBase implements ISignalData {
set mirror(v: boolean) {
this.data.mirror = v;
}
get kilometer(): number {
return this.data.kilometer;
}
set kilometer(v: number) {
this.data.kilometer = v;
}
clone(): SignalData {
return new SignalData(this.data.cloneMessage());
}
@ -320,30 +326,30 @@ export class SignalOperateInteraction extends GraphicInteractionPlugin<Signal> {
signalCloseConfig.handler = () => {
signal.states.redOpen = true;
signal.states.greenOpen = false;
signal.chagneState();
signal.doRepaint();
};
signalOpenConfig.handler = () => {
signal.states.redOpen = false;
signal.states.greenOpen = true;
signal.chagneState();
signal.doRepaint();
};
signalFleetConfig.handler = () => {
signal.states.fleetMode = true;
signal.chagneState();
signal.doRepaint();
};
humanControlConfig.handler = () => {
signal.states.autoRouteDisable = true;
signal.chagneState();
signal.doRepaint();
};
logicConfig.handler = () => {
signal.states.extinguish = true;
signal.chagneState();
signal.doRepaint();
};
signalRedFlashConfig.handler = () => {
signal.states.redFlash = true;
signal.states.redOpen = false;
signal.states.greenOpen = false;
signal.chagneState();
signal.doRepaint();
};
SignalOperateMenu.open(e.global);

View File

@ -37,6 +37,12 @@ export class StationLineData
set hasTransfer(v: boolean) {
this.data.hasTransfer = v;
}
get hideName(): boolean {
return this.data.hideName;
}
set hideName(v: boolean) {
this.data.hideName = v;
}
clone(): StationLineData {
return new StationLineData(this.data.cloneMessage());
}

View File

@ -57,6 +57,12 @@ import {
} from 'src/graphics/trainWindow/TrainWindow';
import { TrainWindowDraw } from 'src/graphics/trainWindow/TrainWindowDrawAssistant';
import { TrainWindowData } from './graphics/TrainWindowInteraction';
import {
AxleCounting,
AxleCountingTemplate,
} from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingDraw } from 'src/graphics/axleCounting/AxleCountingDrawAssistant';
import { AxleCountingData } from './graphics/AxleCountingInteraction';
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
import { TurnoutDraw } from 'src/graphics/turnout/TurnoutDrawAssistant';
import { TurnoutData } from './graphics/TurnoutInteraction';
@ -158,6 +164,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
| TrainWindowDraw
| TrainDraw
| OneClickGenerateDraw
| AxleCountingDraw
)[] = [];
if (draftType === 'Line') {
drawAssistants = [
@ -178,6 +185,10 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
new TurnoutDraw(app, new TurnoutTemplate(new TurnoutData())),
new TrainWindowDraw(app, new TrainWindowTemplate(new TrainWindowData())),
new OneClickGenerateDraw(app, new OneClickGenerateTemplate()),
new AxleCountingDraw(
app,
new AxleCountingTemplate(new AxleCountingData())
),
];
DrawSignalInteraction.init(app);
} else {
@ -291,6 +302,9 @@ export function saveDrawDatas(app: JlDrawApp) {
} else if (TrainWindow.Type === g.type) {
const trainWindowData = (g as TrainWindow).saveData();
storage.trainWindows.push((trainWindowData as TrainWindowData).data);
} else if (AxleCounting.Type === g.type) {
const axleCountingData = (g as AxleCounting).saveData();
storage.axleCountings.push((axleCountingData as AxleCountingData).data);
}
});
const base64 = fromUint8Array(storage.serialize());
@ -358,6 +372,9 @@ export async function loadDrawDatas(app: GraphicApp) {
storage.trainWindows.forEach((trainWindow) => {
datas.push(new TrainWindowData(trainWindow));
});
storage.axleCountings.forEach((axleCounting) => {
datas.push(new AxleCountingData(axleCounting));
});
app.loadGraphic(datas);
} else {
app.loadGraphic([]);

View File

@ -4,6 +4,7 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
import { Turnout, TurnoutPort } from './turnout/Turnout';
import { Section, SectionPort } from './section/Section';
import { TrainWindow } from './trainWindow/TrainWindow';
import { AxleCounting } from './axleCounting/AxleCounting';
/**
*
* @param polygon
@ -83,6 +84,7 @@ export function createRelatedRefProto(
[Section.Type, graphicData.RelatedRef.DeviceType.Section],
[Turnout.Type, graphicData.RelatedRef.DeviceType.Turnout],
[TrainWindow.Type, graphicData.RelatedRef.DeviceType.TrainWindow],
[AxleCounting.Type, graphicData.RelatedRef.DeviceType.AxleCounting],
]);
const protoDeviceType = typeMap.get(type);
if (protoDeviceType === undefined) throw Error(`输入的type有误: ${type}`);

View File

@ -1,24 +1,32 @@
import { Color, Container, Graphics } from 'pixi.js';
import {
GraphicData,
GraphicRelationParam,
JlGraphic,
JlGraphicTemplate,
VectorText,
} from 'src/jl-graphic';
import { Section, SectionPort } from '../section/Section';
import {
IRelatedRefData,
createRelatedRefProto,
protoPort2Data,
} from '../CommonGraphics';
import { Turnout } from '../turnout/Turnout';
export interface IAxleCountingData extends GraphicData {
get code(): string; // 编号
set code(v: string);
get kilometerCode(): string; // 公里标
set kilometerCode(v: string);
get sectionId(): string[]; // 计轴两端的区段
set sectionId(points: string[]);
get axleCountingRef(): IRelatedRefData[]; //关联的设备
set axleCountingRef(ref: IRelatedRefData[]);
clone(): IAxleCountingData;
copyFrom(data: IAxleCountingData): void;
eq(other: IAxleCountingData): boolean;
}
const AxleCountingConsts = {
export const AxleCountingConsts = {
radius: 6,
borderWidth: 1,
circleColorBlue: '0x08F80D',
@ -28,6 +36,7 @@ const AxleCountingConsts = {
kilometerCodeColor: '0xFFFFFF',
kilometerCodeFontSize: 14,
kilometerCodeOffsetY: 95,
offsetSection: 50,
};
class TwoCircleGraphic extends Container {
circleA: Graphics = new Graphics();
@ -68,11 +77,13 @@ export class AxleCounting extends JlGraphic {
static Type = 'AxleCounting';
twoCircle: TwoCircleGraphic = new TwoCircleGraphic();
kilometerGraph: VectorText = new VectorText(''); //公里标
constructor() {
direction: number;
constructor(direction: number) {
super(AxleCounting.Type);
this.addChild(this.twoCircle);
this.addChild(this.kilometerGraph);
this.kilometerGraph.name = 'kilometer';
this.direction = direction;
}
get datas(): IAxleCountingData {
@ -80,29 +91,59 @@ export class AxleCounting extends JlGraphic {
}
doRepaint(): void {
this.twoCircle.draw();
const kilometerGraph = this.kilometerGraph;
const kilometerCode = this.datas?.kilometerCode || 12345.6789;
if (Math.floor(Number(kilometerCode)).toString().length > 3) {
const kiloBit = Math.floor(Number(kilometerCode) / 1000).toString();
kilometerGraph.text =
'K' +
kiloBit +
'+' +
kilometerCode.toString().substring(kiloBit.length);
} else {
kilometerGraph.text = kilometerCode;
}
kilometerGraph.style.fill = AxleCountingConsts.kilometerCodeColor;
kilometerGraph.setVectorFontSize(AxleCountingConsts.kilometerCodeFontSize);
kilometerGraph.anchor.set(0.5);
kilometerGraph.position.set(0, AxleCountingConsts.kilometerCodeOffsetY);
kilometerGraph.rotation = -Math.PI / 2;
if (this.datas.childTransforms?.length) {
this.datas.childTransforms.forEach((child) => {
if (child.name == 'kilometer') {
const pos = child.transform.position;
kilometerGraph.position.set(pos.x, pos.y);
}
}
buildRelation() {
this.queryStore.queryByType<Section>(Section.Type).forEach((section) => {
const ps = section.localToCanvasPoint(section.getStartPoint());
const pe = section.localToCanvasPoint(section.getEndPoint());
let param = '';
if (
ps.x == this.x &&
ps.y == this.y + AxleCountingConsts.offsetSection * this.direction
) {
param = SectionPort.A;
}
if (
pe.x == this.x &&
pe.y == this.y + AxleCountingConsts.offsetSection * this.direction
) {
param = SectionPort.B;
}
if (param !== '') {
this.relationManage.addRelation(
this,
new GraphicRelationParam(section, param)
);
}
});
}
saveRelations() {
const sectionRelations =
this.relationManage.getRelationsOfGraphicAndOtherType(this, Section.Type);
const datas: IRelatedRefData[] = [];
sectionRelations.forEach((ref) => {
const paDevice = ref.getOtherGraphic<Section | Turnout>(this);
const data = createRelatedRefProto(
paDevice.type,
paDevice.id,
ref.getOtherRelationParam(this).param
);
datas.push(data);
});
this.datas.axleCountingRef = datas;
}
loadRelations(): void {
if (this.datas.axleCountingRef.length) {
this.datas.axleCountingRef.forEach((device) => {
this.relationManage.addRelation(
this,
new GraphicRelationParam(
this.queryStore.queryById(device.id),
protoPort2Data(device.devicePort)
)
);
});
}
}
@ -115,7 +156,7 @@ export class AxleCountingTemplate extends JlGraphicTemplate<AxleCounting> {
});
}
new(): AxleCounting {
const axleCounting = new AxleCounting();
const axleCounting = new AxleCounting(1);
axleCounting.loadData(this.datas);
return axleCounting;
}

View File

@ -1,8 +1,9 @@
import { FederatedPointerEvent, Point } from 'pixi.js';
import { FederatedPointerEvent, IPointData, Point } from 'pixi.js';
import {
AbsorbableLine,
AbsorbablePosition,
GraphicDrawAssistant,
GraphicIdGenerator,
GraphicInteractionPlugin,
JlDrawApp,
JlGraphic,
@ -12,7 +13,10 @@ import {
IAxleCountingData,
AxleCounting,
AxleCountingTemplate,
AxleCountingConsts,
} from './AxleCounting';
import { Section } from '../section/Section';
import { Turnout } from '../turnout/Turnout';
export interface IAxleCountingDrawOptions {
newData: () => IAxleCountingData;
@ -24,7 +28,7 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
> {
codeGraph: AxleCounting;
constructor(app: JlDrawApp, template: AxleCountingTemplate) {
super(app, template, 'sym_o_circle', '计轴AxleCounting');
super(app, template, 'sym_o_circle', '不展示');
this.codeGraph = this.graphicTemplate.new();
this.container.addChild(this.codeGraph);
AxleCountingInteraction.init(app);
@ -51,6 +55,47 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
data.transform = this.container.saveTransform();
return true;
}
oneGenerates(height: Point) {
const sections = this.app.queryStore
.queryByType<Section>(Section.Type)
.filter((section) => {
return (
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
AxleCounting.Type
).length == 0
);
});
const turnouts = this.app.queryStore.queryByType<Turnout>(Turnout.Type);
sections.forEach((section) => {
const ps = section.localToCanvasPoint(section.getStartPoint());
let direction = 1;
if (ps.y > height.y) {
direction = -1;
}
const axleCounting = new AxleCounting(direction);
axleCounting.loadData(this.graphicTemplate.datas);
axleCounting.position.set(
ps.x,
ps.y - AxleCountingConsts.offsetSection * direction
);
axleCounting.id = GraphicIdGenerator.next();
this.storeGraphic(axleCounting);
});
turnouts.forEach((turnout) => {
const points = turnout.datas.pointA;
const transPos = turnout.datas.transform.position;
const ps: IPointData[] = [];
points.forEach((point: IPointData) => {
ps.push(new Point(point.x + transPos.x, point.y + transPos.y));
});
const axleCounting = new AxleCounting(1);
axleCounting.loadData(this.graphicTemplate.datas);
axleCounting.position.set(ps[0].x, ps[0].y);
axleCounting.id = GraphicIdGenerator.next();
this.storeGraphic(axleCounting);
});
}
}
function buildAbsorbablePositions(

View File

@ -1,25 +1,25 @@
import { JlGraphic, GraphicData, JlGraphicTemplate } from 'src/jl-graphic';
import { Graphics, IPointData } from 'pixi.js';
import { Graphics, IPointData, Point } from 'pixi.js';
import { RunLine } from '../runLine/RunLine';
import { getDrawApp } from 'src/drawApp';
// calculateDistanceFromPointToLine
import {
calculateDistanceFromPointToLine,
calculateFootPointFromPointToLine,
distance,
} from 'src/jl-graphic';
import { calculateFootPointFromPointToLine, distance } from 'src/jl-graphic';
import { StationLine } from '../stationLine/StationLine';
export interface KilometerPoint {
get point(): IPointData;
set point(point: IPointData);
get kilometer(): number;
set kilometer(kilometer: number);
get stName(): string;
set stName(stName: string);
}
export interface IPathLineData extends GraphicData {
get code(): string;
set code(v: string);
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
get isUp(): boolean;
set isUp(v: boolean);
get kilometerPoints(): KilometerPoint[];
set kilometerPoints(kilometerPoints: KilometerPoint[]);
clone(): IPathLineData;
@ -93,21 +93,32 @@ export class PathLine extends JlGraphic {
generatePathLineKilometerPoints(stas: string[]) {
const kilometerPoints: KilometerPoint[] = [];
stas.forEach((stasId) => {
const sta = this.queryStore.queryById(stasId);
this.datas.points.some((p, index) => {
const sta = this.queryStore.queryById(stasId) as StationLine;
let fp: Point | null = null;
let verticalLength = 100;
this.datas.points.forEach((p, index) => {
if (index) {
const prep = this.datas.points[index - 1];
const fp = calculateFootPointFromPointToLine(prep, p, sta.position);
const fpn = calculateFootPointFromPointToLine(prep, p, sta.position);
const length = distance(prep.x, prep.y, p.x, p.y);
const fln = distance(fpn.x, fpn.y, sta.position.x, sta.position.y);
if (
distance(fp.x, fp.y, prep.x, prep.y) <= length &&
distance(fp.x, fp.y, p.x, p.y) <= length
distance(fpn.x, fpn.y, prep.x, prep.y) <= length &&
distance(fpn.x, fpn.y, p.x, p.y) <= length &&
fln <= verticalLength
) {
kilometerPoints.push({ point: fp, kilometer: 0 });
return true;
verticalLength = fln;
fp = fpn;
}
}
});
if (fp) {
kilometerPoints.push({
point: fp,
kilometer: 0,
stName: sta.datas.code,
});
}
});
this.datas.kilometerPoints = kilometerPoints;
}

View File

@ -1,7 +1,30 @@
import { GraphicDrawAssistant, JlDrawApp } from 'src/jl-graphic';
import { IPathLineData, PathLineTemplate } from './PathLine';
import { Point, Graphics, LINE_JOIN } from 'pixi.js';
import {
GraphicDrawAssistant,
JlDrawApp,
linePoint,
GraphicInteractionPlugin,
GraphicApp,
JlGraphic,
DraggablePoint,
GraphicTransformEvent,
calculateFootPointFromPointToLine,
calculateDistanceFromPointToLine,
distance,
} from 'src/jl-graphic';
import {
IPathLineData,
PathLineTemplate,
PathLine,
pathLineConsts,
} from './PathLine';
import {
Point,
Graphics,
LINE_JOIN,
IHitArea,
DisplayObject,
IPointData,
} from 'pixi.js';
export interface IPathLineDrawOptions {
newData: () => IPathLineData;
}
@ -16,7 +39,7 @@ export class PathLineDraw extends GraphicDrawAssistant<
constructor(app: JlDrawApp, template: PathLineTemplate) {
super(app, template, 'sym_o_horizontal_rule', '不展示');
this.container.addChild(this.graphic);
// PathLinePointsEditPlugin.init(app);
PathLinePointsEditPlugin.init(app);
}
clearCache(): void {
this.points = [];
@ -60,66 +83,134 @@ export class PathLineDraw extends GraphicDrawAssistant<
}
}
// export class PathLineGraphicHitArea implements IHitArea {
// pathLine: PathLine;
// constructor(pathLine: PathLine) {
// this.pathLine = pathLine;
// }
// contains(x: number, y: number): boolean {
// const p = new Point(x, y);
// for (let i = 1; i < this.pathLine.datas.points.length; i++) {
// const p1 = this.pathLine.datas.points[i - 1];
// const p2 = this.pathLine.datas.points[i];
// if (linePoint(p1, p2, p, pathLineConsts.pathLineWidth)) {
// return true;
// }
// }
// return false;
// }
// }
export class PathLineGraphicHitArea implements IHitArea {
pathLine: PathLine;
constructor(pathLine: PathLine) {
this.pathLine = pathLine;
}
contains(x: number, y: number): boolean {
const p = new Point(x, y);
for (let i = 1; i < this.pathLine.datas.points.length; i++) {
const p1 = this.pathLine.datas.points[i - 1];
const p2 = this.pathLine.datas.points[i];
if (linePoint(p1, p2, p, pathLineConsts.pathLineWidth)) {
return true;
}
}
return false;
}
}
// export class PathLinePointsEditPlugin extends GraphicInteractionPlugin<PathLine> {
// static Name = 'LinkPointsDrag';
// constructor(app: GraphicApp) {
// super(PathLinePointsEditPlugin.Name, app);
// }
// static init(app: GraphicApp): PathLinePointsEditPlugin {
// return new PathLinePointsEditPlugin(app);
// }
// filter(...grahpics: JlGraphic[]): PathLine[] | undefined {
// return grahpics.filter((g) => g.type == PathLine.Type) as PathLine[];
// }
// bind(g: PathLine): void {
// g.pathLine.eventMode = 'static';
// g.pathLine.cursor = 'pointer';
// g.pathLine.hitArea = new PathLineGraphicHitArea(g);
// g.on('selected', this.onSelected, this);
// g.on('unselected', this.onUnselected, this);
// }
// unbind(g: PathLine): void {
// g.off('selected', this.onSelected, this);
// g.off('unselected', this.onUnselected, this);
// }
export class PathLinePointsEditPlugin extends GraphicInteractionPlugin<PathLine> {
static Name = 'LinkPointsDrag';
constructor(app: GraphicApp) {
super(PathLinePointsEditPlugin.Name, app);
}
static init(app: GraphicApp): PathLinePointsEditPlugin {
return new PathLinePointsEditPlugin(app);
}
filter(...grahpics: JlGraphic[]): PathLine[] | undefined {
return grahpics.filter((g) => g.type == PathLine.Type) as PathLine[];
}
bind(g: PathLine): void {
g.pathLine.eventMode = 'static';
g.pathLine.cursor = 'pointer';
g.pathLine.draggable = false;
g.pathLine.scalable = false;
g.pathLine.rotatable = false;
g.pathLine.hitArea = new PathLineGraphicHitArea(g);
g.on('selected', this.onSelected, this);
g.on('unselected', this.onUnselected, this);
}
unbind(g: PathLine): void {
g.off('selected', this.onSelected, this);
g.off('unselected', this.onUnselected, this);
}
// onSelected(g: DisplayObject): void {
// const runLine = g as PathLine;
// let lep;
// lep = runLine.getAssistantAppend<PolylineEditPlugin>(
// PolylineEditPlugin.Name
// );
// if (!lep) {
// lep = new PolylineEditPlugin(runLine);
// runLine.addAssistantAppend(lep);
// }
// lep.showAll();
// }
// onUnselected(g: DisplayObject): void {
// const runLine = g as PathLine;
// const lep = runLine.getAssistantAppend<PolylineEditPlugin>(
// PolylineEditPlugin.Name
// );
// if (lep) {
// lep.hideAll();
// }
// }
// }
onSelected(g: DisplayObject): void {
const pathLine = g as PathLine;
pathLine.draggable = false;
pathLine.scalable = false;
pathLine.rotatable = false;
pathLine.datas.kilometerPoints.forEach((kp, index) => {
const dp = new DraggablePoint(kp.point);
dp.on(
'transforming',
(e: GraphicTransformEvent) => {
this.movePointOnLine(pathLine.datas.points, e);
},
this
);
dp.on(
'transformend',
(e: GraphicTransformEvent) => {
const kilometerPoints = [...pathLine.datas.kilometerPoints];
kilometerPoints[index] = {
point: new Point(e.target.position.x, e.target.position.y),
kilometer: kilometerPoints[index].kilometer,
name: kilometerPoints[index].name,
};
pathLine.datas.kilometerPoints = kilometerPoints;
},
this
);
pathLine.addChild(dp);
});
}
onUnselected(g: DisplayObject): void {
const pathLine = g as PathLine;
if (pathLine.children.length > 1) {
pathLine.removeChildren(1);
}
}
kpTransforming(e: GraphicTransformEvent) {
console.log(e, '----');
}
movePointOnLine(points: IPointData[], e: GraphicTransformEvent) {
let minDistance = Number.MAX_SAFE_INTEGER;
let fp = null;
const np = e.target.position;
for (let i = 0; i < points.length; i++) {
const distancep = distance(np.x, np.y, points[i].x, points[i].y);
if (i !== 0) {
const distanceF = calculateDistanceFromPointToLine(
points[i - 1],
points[i],
np
);
const fpn = calculateFootPointFromPointToLine(
points[i - 1],
points[i],
np
);
const distance1 = distance(
fpn.x,
fpn.y,
points[i - 1].x,
points[i - 1].y
);
const distance2 = distance(fpn.x, fpn.y, points[i].x, points[i].y);
const distance3 = distance(
points[i - 1].x,
points[i - 1].y,
points[i].x,
points[i].y
);
if (distancep < minDistance) {
minDistance = distancep;
fp = points[i];
}
if (distanceF < minDistance && distance1 + distance2 <= distance3 + 1) {
minDistance = distanceF;
fp = fpn;
}
} else {
minDistance = distancep;
fp = points[i];
}
}
if (fp) {
e.target.position.set(fp.x, fp.y);
}
}
}

View File

@ -215,6 +215,7 @@ export class RunLine extends JlGraphic {
const pathLineDown = pathLineDrawAssistant.quickCreate(pointsDown);
this.datas.upPathLineId = pathLineUp?.id || '';
this.datas.downPathLineId = pathLineDown?.id || '';
this.generatePathLineKilometerPoints();
}
getStartPoint(): IPointData {

View File

@ -15,6 +15,8 @@ export interface ISignalData extends GraphicData {
set code(v: string);
get mirror(): boolean;
set mirror(v: boolean);
get kilometer(): number;
set kilometer(v: number);
clone(): ISignalData;
copyFrom(data: ISignalData): void;
eq(other: ISignalData): boolean;

View File

@ -11,6 +11,9 @@ export interface IStationLineData extends GraphicData {
set code(v: string);
get hasTransfer(): boolean;
set hasTransfer(v: boolean);
get hideName(): boolean;
set hideName(v: boolean);
clone(): IStationLineData;
copyFrom(data: IStationLineData): void;
eq(other: IStationLineData): boolean;
@ -117,6 +120,7 @@ export class StationLine extends JlGraphic {
codeGraph.style.fill = stationConsts.codeColor;
codeGraph.setVectorFontSize(stationConsts.codeFontSize);
codeGraph.anchor.set(0.5);
codeGraph.visible = !this.datas.hideName;
if (this.datas.childTransforms?.length) {
const pos = this.datas.childTransforms[0].transform.position;
codeGraph.position.set(pos.x, pos.y);

View File

@ -8,6 +8,8 @@ import {
} from 'src/jl-graphic';
import { TrainWindow } from './TrainWindow';
import { TrainWindowDraw } from './TrainWindowDrawAssistant';
import { AxleCounting } from '../axleCounting/AxleCounting';
import { AxleCountingDraw } from '../axleCounting/AxleCountingDrawAssistant';
interface IOneClickData extends GraphicData {
get code(): string; // 编号
@ -39,7 +41,7 @@ export class OneClickGenerateTemplate extends JlGraphicTemplate<OneClickGenerate
}
export class OneClickGenerateDraw extends GraphicDrawAssistant<
OneClickGenerateTemplate,
OneClickGenerateTemplate,
IOneClickData
> {
lineGraph: OneClickGenerate;
@ -54,11 +56,14 @@ OneClickGenerateTemplate,
this.lineGraph.doRepaint();
}
onLeftDown(e: FederatedPointerEvent): void {
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
const trainWindowDraw = this.app.getDrawAssistant(
TrainWindow.Type
) as TrainWindowDraw;
trainWindowDraw.oneGenerates(this.toCanvasCoordinates(e.global));
const axleCountingDraw = this.app.getDrawAssistant(
AxleCounting.Type
) as AxleCountingDraw;
axleCountingDraw.oneGenerates(this.toCanvasCoordinates(e.global));
this.finish();
}