231 lines
9.5 KiB
JavaScript
231 lines
9.5 KiB
JavaScript
|
import { JlGraphic, VectorText, convertToBezierParams, Vector2, splitLineEvenly, distance2, GraphicRelationParam, JlGraphicTemplate } from 'jl-graphic';
|
||
|
import { SectionGraphic } from './SectionGraphic.js';
|
||
|
import { DevicePort, IRelatedRef } from '../../../common/common.js';
|
||
|
import { Turnout } from '../../Turnout/Turnout.js';
|
||
|
import { AxleCounting } from '../../AxleCounting/AxleCounting.js';
|
||
|
|
||
|
const tolerance = 0.01;
|
||
|
var SectionType;
|
||
|
(function (SectionType) {
|
||
|
SectionType[SectionType["Physical"] = 0] = "Physical";
|
||
|
SectionType[SectionType["Logic"] = 1] = "Logic";
|
||
|
SectionType[SectionType["TurnoutPhysical"] = 2] = "TurnoutPhysical";
|
||
|
SectionType[SectionType["Track"] = 4] = "Track";
|
||
|
SectionType[SectionType["TrackLogic"] = 5] = "TrackLogic";
|
||
|
})(SectionType || (SectionType = {}));
|
||
|
const defaultDisplayConfig = {
|
||
|
lineColor: '#5578b6',
|
||
|
occupiedColor: '#f00',
|
||
|
lineWidth: 5,
|
||
|
};
|
||
|
let Section$1 = class Section extends JlGraphic {
|
||
|
static Type = 'Section';
|
||
|
lineGraphic;
|
||
|
labelGraphic;
|
||
|
displayConfig = defaultDisplayConfig;
|
||
|
constructor() {
|
||
|
super(Section.Type);
|
||
|
this.lineGraphic = new SectionGraphic();
|
||
|
this.labelGraphic = new VectorText('');
|
||
|
this.labelGraphic.setVectorFontSize(14);
|
||
|
this.labelGraphic.anchor.set(0.5);
|
||
|
this.labelGraphic.style.fill = '#0f0';
|
||
|
this.labelGraphic.transformSave = true;
|
||
|
this.labelGraphic.name = 'label';
|
||
|
this.transformSave = true;
|
||
|
this.addChild(this.lineGraphic);
|
||
|
this.addChild(this.labelGraphic);
|
||
|
}
|
||
|
setDisplayConfig(config) {
|
||
|
this.displayConfig = config;
|
||
|
}
|
||
|
getVerticesList() {
|
||
|
if (this.datas.isCurve) {
|
||
|
return [
|
||
|
this.datas.points[0],
|
||
|
...convertToBezierParams(this.datas.points).map((param) => param.p2),
|
||
|
];
|
||
|
}
|
||
|
else {
|
||
|
return this.datas.points;
|
||
|
}
|
||
|
}
|
||
|
getStartPoint() {
|
||
|
return this.datas.points[0];
|
||
|
}
|
||
|
getEndPoint() {
|
||
|
return this.datas.points[this.datas.points.length - 1];
|
||
|
}
|
||
|
doRepaint() {
|
||
|
this.lineGraphic.clear();
|
||
|
if (this.datas.sectionType === SectionType.TurnoutPhysical) {
|
||
|
return;
|
||
|
}
|
||
|
this.lineGraphic.isCurve = this.datas.isCurve;
|
||
|
if (this.lineGraphic.isCurve) {
|
||
|
this.lineGraphic.segmentsCount = this.datas.segmentsCount;
|
||
|
}
|
||
|
this.lineGraphic.points = this.datas.points;
|
||
|
this.lineGraphic.lineStyle(this.displayConfig.lineWidth, this.states.occupied
|
||
|
? this.displayConfig.occupiedColor
|
||
|
: this.displayConfig.lineColor);
|
||
|
this.labelGraphic.text = this.datas.code;
|
||
|
const labelPosition = this.datas.childTransforms?.find((t) => t.name === this.labelGraphic.name)?.transform.position;
|
||
|
if (labelPosition) {
|
||
|
this.labelGraphic.position.set(labelPosition.x, labelPosition.y);
|
||
|
}
|
||
|
else {
|
||
|
this.labelGraphic.position.set(this.datas.points[0].x, this.datas.points[0].y + 20);
|
||
|
}
|
||
|
}
|
||
|
get datas() {
|
||
|
return this.getDatas();
|
||
|
}
|
||
|
get states() {
|
||
|
return this.getStates();
|
||
|
}
|
||
|
get linePoints() {
|
||
|
return this.datas.points;
|
||
|
}
|
||
|
set linePoints(points) {
|
||
|
const old = this.datas.clone();
|
||
|
old.points = points;
|
||
|
this.updateData(old);
|
||
|
}
|
||
|
getConnectElement(port) {
|
||
|
const relation = this.relationManage
|
||
|
.getRelationsOfGraphic(this)
|
||
|
.find((relation) => relation.getRelationParam(this).getParam() === port &&
|
||
|
(relation.getOtherGraphic(this) instanceof Section ||
|
||
|
relation.getOtherGraphic(this) instanceof Turnout));
|
||
|
if (!relation) {
|
||
|
return;
|
||
|
}
|
||
|
return {
|
||
|
g: relation?.getOtherGraphic(this),
|
||
|
port: relation?.getOtherRelationParam(this).getParam(),
|
||
|
};
|
||
|
}
|
||
|
/** 获取拆分逻辑区段数据 */
|
||
|
getSplitPoints(count) {
|
||
|
if (this.datas.points.length !== 2) {
|
||
|
let totalLen = 0;
|
||
|
const lengths = [];
|
||
|
for (let i = 1; i < this.datas.points.length; i++) {
|
||
|
const { x: x1, y: y1 } = this.datas.points[i - 1], { x: x2, y: y2 } = this.datas.points[i];
|
||
|
const len = new Vector2([x2 - x1, y2 - y1]).length();
|
||
|
totalLen += len;
|
||
|
lengths.push(len);
|
||
|
}
|
||
|
const counts = lengths.map((length) => Math.round((count * length) / totalLen));
|
||
|
if (counts.reduce((p, c) => p + c, 0) !== count) {
|
||
|
const intersection = counts.reduce((p, c) => p + c, 0) - count;
|
||
|
let maxCountIndex = 0, maxCount = 0;
|
||
|
counts.forEach((c, i) => {
|
||
|
if (c > maxCount) {
|
||
|
maxCount = c;
|
||
|
maxCountIndex = i;
|
||
|
}
|
||
|
});
|
||
|
counts[maxCountIndex] + intersection;
|
||
|
}
|
||
|
return counts
|
||
|
.map((count, i) => {
|
||
|
return splitLineEvenly(this.localToCanvasPoint(this.datas.points[i]), this.localToCanvasPoint(this.datas.points[i + 1]), count);
|
||
|
})
|
||
|
.flat();
|
||
|
}
|
||
|
else {
|
||
|
return splitLineEvenly(this.localToCanvasPoint(this.datas.points[0]), this.localToCanvasPoint(this.datas.points[this.datas.points.length - 1]), count);
|
||
|
}
|
||
|
}
|
||
|
buildRelation() {
|
||
|
this.relationManage.deleteRelationOfGraphicAndOtherType(this, Section.Type);
|
||
|
if (this.datas.sectionType === SectionType.Physical) {
|
||
|
this.queryStore.queryByType(Section.Type).forEach((section) => {
|
||
|
if (section.id === this.id)
|
||
|
return;
|
||
|
let param = [];
|
||
|
if (distance2(this.localToCanvasPoint(this.getStartPoint()), section.localToCanvasPoint(section.getStartPoint())) <= tolerance) {
|
||
|
param = [DevicePort.A, DevicePort.A];
|
||
|
}
|
||
|
if (distance2(this.localToCanvasPoint(this.getEndPoint()), section.localToCanvasPoint(section.getStartPoint())) <= tolerance) {
|
||
|
param = [DevicePort.B, DevicePort.A];
|
||
|
}
|
||
|
if (distance2(this.localToCanvasPoint(this.getStartPoint()), section.localToCanvasPoint(section.getEndPoint())) <= tolerance) {
|
||
|
param = [DevicePort.A, DevicePort.B];
|
||
|
}
|
||
|
if (distance2(this.localToCanvasPoint(this.getEndPoint()), section.localToCanvasPoint(section.getEndPoint())) <= tolerance) {
|
||
|
param = [DevicePort.B, DevicePort.B];
|
||
|
}
|
||
|
if (param.length) {
|
||
|
this.relationManage.addRelation(new GraphicRelationParam(this, param[0]), new GraphicRelationParam(section, param[1]));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
saveRelations() {
|
||
|
const paRelation = this.relationManage
|
||
|
.getRelationsOfGraphic(this)
|
||
|
.find((relation) => relation.getRelationParam(this).param === DevicePort.A &&
|
||
|
(relation.getOtherGraphic(this) instanceof Section ||
|
||
|
relation.getOtherGraphic(this) instanceof Turnout));
|
||
|
const paDevice = paRelation?.getOtherGraphic(this);
|
||
|
if (paDevice) {
|
||
|
this.datas.paRef = IRelatedRef.create(paDevice.type, paDevice.id, paRelation.getOtherRelationParam(this).getParam());
|
||
|
}
|
||
|
else {
|
||
|
this.datas.paRef = undefined;
|
||
|
}
|
||
|
const pbRelation = this.relationManage
|
||
|
.getRelationsOfGraphic(this)
|
||
|
.find((relation) => relation.getRelationParam(this).param === DevicePort.B &&
|
||
|
(relation.getOtherGraphic(this) instanceof Section ||
|
||
|
relation.getOtherGraphic(this) instanceof Turnout));
|
||
|
const pbDevice = pbRelation?.getOtherGraphic(this);
|
||
|
if (pbDevice) {
|
||
|
this.datas.pbRef = IRelatedRef.create(pbDevice.type, pbDevice.id, pbRelation?.getOtherRelationParam(this).param);
|
||
|
}
|
||
|
else {
|
||
|
this.datas.pbRef = undefined;
|
||
|
}
|
||
|
this.datas.axleCountings = this.relationManage
|
||
|
.getRelationsOfGraphicAndOtherType(this, AxleCounting.Type)
|
||
|
.map((relation) => relation.getOtherGraphic(this).datas.id);
|
||
|
}
|
||
|
loadRelations() {
|
||
|
if (this.datas?.paRef?.id) {
|
||
|
this.relationManage.addRelation(new GraphicRelationParam(this, DevicePort.A), new GraphicRelationParam(this.queryStore.queryById(this.datas.paRef.id), DevicePort[this.datas.paRef.devicePort]));
|
||
|
}
|
||
|
if (this.datas?.pbRef?.id) {
|
||
|
this.relationManage.addRelation(new GraphicRelationParam(this, DevicePort.B), new GraphicRelationParam(this.queryStore.queryById(this.datas.pbRef.id), DevicePort[this.datas.pbRef.devicePort]));
|
||
|
}
|
||
|
if (this.datas.trackSectionId) {
|
||
|
this.relationManage.addRelation(this, this.queryStore.queryById(this.datas.trackSectionId));
|
||
|
}
|
||
|
if (this.datas.sectionType === SectionType.TurnoutPhysical) {
|
||
|
if (this.datas.axleCountings) {
|
||
|
this.datas.axleCountings.forEach((id) => {
|
||
|
this.relationManage.addRelation(this, this.queryStore.queryById(id));
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
class SectionTemplate extends JlGraphicTemplate {
|
||
|
constructor(dataTemplate, stateTemplate) {
|
||
|
super(Section$1.Type, {
|
||
|
dataTemplate,
|
||
|
stateTemplate,
|
||
|
});
|
||
|
}
|
||
|
new() {
|
||
|
const section = new Section$1();
|
||
|
section.loadData(this.datas);
|
||
|
section.loadState(this.states);
|
||
|
return section;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export { Section$1 as Section, SectionTemplate, SectionType };
|