Merge branch 'master' of git.code.tencent.com:beijing-rtss-test/bj-rtss-client

This commit is contained in:
Yuan 2023-08-07 15:06:07 +08:00
commit bea870c7e6
14 changed files with 400 additions and 158 deletions

View File

@ -37,6 +37,7 @@
style="margin-top: 10px" style="margin-top: 10px"
v-model="refDevData.deviceType" v-model="refDevData.deviceType"
:options="DeviceTypeOptions" :options="DeviceTypeOptions"
:readonly="true"
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"
@update:model-value="onUpdate" @update:model-value="onUpdate"
@ -47,6 +48,7 @@
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Section" v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Section"
style="margin-top: 10px" style="margin-top: 10px"
v-model="refDevData.id" v-model="refDevData.id"
:readonly="true"
:options="sectionList" :options="sectionList"
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"
@ -59,6 +61,7 @@
style="margin-top: 10px" style="margin-top: 10px"
v-model="refDevData.id" v-model="refDevData.id"
:options="turnoutList" :options="turnoutList"
:readonly="true"
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"
@update:model-value="onUpdate" @update:model-value="onUpdate"
@ -70,6 +73,7 @@
style="margin-top: 10px" style="margin-top: 10px"
v-model="refDevData.devicePort" v-model="refDevData.devicePort"
:options="DevicePortOptions" :options="DevicePortOptions"
:readonly="true"
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"
@update:model-value="onUpdate" @update:model-value="onUpdate"
@ -127,6 +131,10 @@ function initRefData(signal: Signal) {
refDevData.id = signalModel.refDev.id; refDevData.id = signalModel.refDev.id;
refDevData.devicePort = signalModel.refDev.devicePort; refDevData.devicePort = signalModel.refDev.devicePort;
refDevData.deviceType = signalModel.refDev.deviceType; refDevData.deviceType = signalModel.refDev.deviceType;
} else {
refDevData.id = '';
refDevData.deviceType = graphicData.RelatedRef.DeviceType.Section;
refDevData.devicePort = graphicData.RelatedRef.DevicePort.A;
} }
} }
function initDeviceList() { function initDeviceList() {

View File

@ -7,26 +7,29 @@
label="坡度长度" label="坡度长度"
type="textarea" type="textarea"
@blur="onUpdate" @blur="onUpdate"
v-model="slopeModel.slopeLong" v-model="slopeLong"
lazy-rules
autogrow
/>
<q-input
outlined
readonly
label="坡度方向"
type="textarea"
@blur="onUpdate"
v-model="direction"
lazy-rules lazy-rules
autogrow autogrow
/> />
<q-input <q-input
outlined outlined
label="坡度值" label="坡度值"
type="textarea" type="number"
@blur="onUpdate" @blur="onUpdate"
v-model="slopeModel.slopeNumber" v-model.number="slopeModel.slopeNumber"
lazy-rules lazy-rules
autogrow autogrow
/> />
<q-select
outlined
@blur="onUpdate"
v-model="direction"
:options="optionsDirection"
label="坡度方向"
/>
<q-list bordered separator class="rounded-borders"> <q-list bordered separator class="rounded-borders">
<q-item> <q-item>
<q-item-section no-wrap class="q-gutter-y-sm column"> <q-item-section no-wrap class="q-gutter-y-sm column">
@ -57,18 +60,8 @@ import { computed, onMounted, reactive, ref, watch } from 'vue';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const slopeModel = reactive(new SlopeData()); const slopeModel = reactive(new SlopeData());
const direction = ref(''); const direction = ref('无坡度');
const optionsDirection = ['上坡', '下坡', '无坡度']; const slopeLong = ref(0);
enum showSelect {
上坡 = 'up',
下坡 = 'down',
无坡度 = 'none',
}
enum showSelectData {
up = '上坡',
down = '下坡',
none = '无坡度',
}
drawStore.$subscribe; drawStore.$subscribe;
watch( watch(
@ -76,7 +69,9 @@ watch(
(val) => { (val) => {
if (val && val.type == Slope.Type) { if (val && val.type == Slope.Type) {
slopeModel.copyFrom(val.saveData() as SlopeData); slopeModel.copyFrom(val.saveData() as SlopeData);
direction.value = (showSelectData as never)[slopeModel.slopeDirection]; if (slopeModel.slopeNumber !== 0) {
direction.value = slopeModel.slopeNumber > 0 ? '上坡' : '下坡';
}
} }
} }
); );
@ -85,12 +80,14 @@ onMounted(() => {
const slope = drawStore.selectedGraphic as Slope; const slope = drawStore.selectedGraphic as Slope;
if (slope) { if (slope) {
slopeModel.copyFrom(slope.saveData()); slopeModel.copyFrom(slope.saveData());
direction.value = (showSelectData as never)[slopeModel.slopeDirection]; if (slopeModel.slopeNumber !== 0) {
direction.value = slopeModel.slopeNumber > 0 ? '上坡' : '下坡';
}
slopeLong.value = +slopeModel.refDeviceId[1];
} }
}); });
function onUpdate() { function onUpdate() {
slopeModel.slopeDirection = (showSelect as never)[direction.value];
const slope = drawStore.selectedGraphic as Slope; const slope = drawStore.selectedGraphic as Slope;
if (slope) { if (slope) {
drawStore.getDrawApp().updateGraphicAndRecord(slope, slopeModel); drawStore.getDrawApp().updateGraphicAndRecord(slope, slopeModel);

View File

@ -48,6 +48,7 @@
v-model="refDevData.id" v-model="refDevData.id"
:options="sectionList" :options="sectionList"
:map-options="true" :map-options="true"
:readonly="true"
:emit-value="true" :emit-value="true"
@update:model-value="onUpdate" @update:model-value="onUpdate"
label="关联设备" label="关联设备"
@ -120,6 +121,8 @@ function initRefData(stopPosition: StopPosition) {
} }
if (stopPositionModel.refDev) { if (stopPositionModel.refDev) {
refDevData.id = stopPositionModel.refDev.id; refDevData.id = stopPositionModel.refDev.id;
} else {
refDevData.id = '';
} }
} }

View File

@ -49,17 +49,43 @@
@update:model-value="onUpdate" @update:model-value="onUpdate"
label="应答器类型" label="应答器类型"
></q-select> ></q-select>
<q-field class="q-mt-lg" outlined label="关联区段" readonly stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in sectionRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
<q-field class="q-mt-lg" outlined label="关联道岔" readonly stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in turnoutRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
</q-form> </q-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { TransponderData } from 'src/drawApp/graphics/TransponderInteraction'; import { TransponderData } from 'src/drawApp/graphics/TransponderInteraction';
import { Section } from 'src/graphics/section/Section';
import { import {
Transponder, Transponder,
transponderTypeEnum, transponderTypeEnum,
} from 'src/graphics/transponder/Transponder'; } from 'src/graphics/transponder/Transponder';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue'; import { computed, onMounted, reactive, watch } from 'vue';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const transponderModel = reactive(new TransponderData()); const transponderModel = reactive(new TransponderData());
@ -119,4 +145,33 @@ function onUpdate() {
.updateGraphicAndRecord(Transponder, transponderModel); .updateGraphicAndRecord(Transponder, transponderModel);
} }
} }
const sectionRelations = computed(() => {
const transponder = drawStore.selectedGraphic as Transponder;
const relations =
transponder.relationManage.getRelationsOfGraphicAndOtherType(
transponder,
Section.Type
);
return relations.map(
(relation) =>
`${relation.getOtherGraphic<Transponder>(transponder).datas.code}`
);
});
const turnoutRelations = computed(() => {
const transponder = drawStore.selectedGraphic as Transponder;
const relations =
transponder.relationManage.getRelationsOfGraphicAndOtherType(
transponder,
Turnout.Type
);
return relations.map(
(relation) =>
`${relation.getOtherGraphic<Transponder>(transponder).datas.code}(${
relation.getOtherRelationParam(transponder).param
})`
);
});
</script> </script>

View File

@ -48,7 +48,7 @@ export function toStorageTransform(
export interface IProtoGraphicData extends pb_1.Message { export interface IProtoGraphicData extends pb_1.Message {
common: ICommonInfo; common: ICommonInfo;
code: string; code?: string;
} }
export abstract class GraphicDataBase implements GraphicData { export abstract class GraphicDataBase implements GraphicData {

View File

@ -19,12 +19,6 @@ export class SlopeData extends GraphicDataBase implements ISlopeData {
public get data(): graphicData.Slope { public get data(): graphicData.Slope {
return this.getData<graphicData.Slope>(); return this.getData<graphicData.Slope>();
} }
get code(): string {
return this.data.code;
}
set code(v: string) {
this.data.code = v;
}
get points(): IPointData[] { get points(): IPointData[] {
return this.data.points; return this.data.points;
} }
@ -33,24 +27,12 @@ export class SlopeData extends GraphicDataBase implements ISlopeData {
(p) => new graphicData.Point({ x: p.x, y: p.y }) (p) => new graphicData.Point({ x: p.x, y: p.y })
); );
} }
get slopeNumber(): string { get slopeNumber(): number {
return this.data.slopeNumber; return this.data.slopeNumber;
} }
set slopeNumber(v: string) { set slopeNumber(v: number) {
this.data.slopeNumber = v; this.data.slopeNumber = v;
} }
get slopeDirection(): string {
return this.data.slopeDirection;
}
set slopeDirection(v: string) {
this.data.slopeDirection = v;
}
get slopeLong(): number {
return this.data.slopeLong;
}
set slopeLong(v: number) {
this.data.slopeLong = v;
}
get refDeviceId(): string[] { get refDeviceId(): string[] {
return this.data.refDeviceId; return this.data.refDeviceId;
} }

View File

@ -50,6 +50,12 @@ export class TransponderData
set kilometerSystem(v: KilometerSystem) { set kilometerSystem(v: KilometerSystem) {
this.data.kilometerSystem = new graphicData.KilometerSystem(v); this.data.kilometerSystem = new graphicData.KilometerSystem(v);
} }
get TransponderRef(): graphicData.RelatedRef {
return this.data.TransponderRef;
}
set TransponderRef(v: graphicData.RelatedRef) {
this.data.TransponderRef = v;
}
clone(): TransponderData { clone(): TransponderData {
return new TransponderData(this.data.cloneMessage()); return new TransponderData(this.data.cloneMessage());
} }

View File

@ -6,13 +6,12 @@ import {
GraphicRelationParam, GraphicRelationParam,
JlDrawApp, JlDrawApp,
JlGraphic, JlGraphic,
linePoint, pointBox,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { Section, SectionType } from '../section/Section'; import { Section, SectionType } from '../section/Section';
import { import {
ISeparatorData, ISeparatorData,
Separator, Separator,
SeparatorConsts,
SeparatorTemplate, SeparatorTemplate,
separatorTypeEnum, separatorTypeEnum,
} from './Separator'; } from './Separator';
@ -208,32 +207,8 @@ export class SeparatorGraphicHitArea implements IHitArea {
contains(x: number, y: number): boolean { contains(x: number, y: number): boolean {
let contains = false; let contains = false;
const p = new Point(x, y); const p = new Point(x, y);
const typeArr = ['section', 'turnout']; const r = this.separator.getLocalBounds();
const endTypeArr = ['endA', 'endB']; contains = pointBox(p, r);
let d = SeparatorConsts.radius;
if (typeArr.includes(this.separator.datas.separatorType)) {
const tolerance = SeparatorConsts.lineWidth;
const p1 = new Point(0, -SeparatorConsts.height / 2);
const p2 = new Point(0, SeparatorConsts.height / 2);
contains = contains || linePoint(p1, p2, p, tolerance);
return contains;
} else if (endTypeArr.includes(this.separator.datas.separatorType)) {
if (this.separator.datas.separatorType == 'endB') {
d = -d;
}
const tolerance = SeparatorConsts.lineWidth;
const p1 = new Point(0, 0);
const p2 = new Point(-d, 0);
const p3 = new Point(-d, -d);
const p4 = new Point(-d * 3, -d);
const p5 = new Point(-d, d);
const p6 = new Point(-d * 3, d);
contains = contains || linePoint(p1, p2, p, tolerance);
contains = contains || linePoint(p2, p3, p, tolerance);
contains = contains || linePoint(p3, p4, p, tolerance);
contains = contains || linePoint(p2, p5, p, tolerance);
contains = contains || linePoint(p5, p6, p, tolerance);
}
return contains; return contains;
} }
} }

View File

@ -1,14 +1,23 @@
import { Graphics, Point } from 'pixi.js'; import { Graphics, Point } from 'pixi.js';
import { import {
calculateDistanceFromPointToLine,
calculateFootPointFromPointToLine,
GraphicData, GraphicData,
GraphicState, GraphicState,
isPointOnLine,
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { calculateMirrorPoint } from 'src/jl-graphic'; import { calculateMirrorPoint } from 'src/jl-graphic';
import { LampMainBody } from './LampMainBody'; import { LampMainBody } from './LampMainBody';
import { drawArrow, IRelatedRefData } from '../CommonGraphics'; import {
drawArrow,
IRelatedRefData,
createRelatedRefProto,
} from '../CommonGraphics';
import { SignalCode } from './SignalCode'; import { SignalCode } from './SignalCode';
import { Section, SectionPort } from '../section/Section';
import { Turnout, TurnoutPort } from '../turnout/Turnout';
export enum Direction { export enum Direction {
LEFT = 0, LEFT = 0,
@ -205,6 +214,91 @@ export class Signal extends JlGraphic {
} }
this.humanControl.endFill(); this.humanControl.endFill();
} }
buildRelation() {
const sections = this.queryStore.queryByType<Section>(Section.Type);
const turnouts = this.queryStore.queryByType<Turnout>(Turnout.Type);
let deviceId = '';
let deviceType = '';
let minD = Number.MAX_SAFE_INTEGER;
let port: SectionPort | TurnoutPort = SectionPort.A;
sections.forEach((sec: Section) => {
for (let i = 0; i < sec.datas.points.length - 1; i++) {
const d = calculateDistanceFromPointToLine(
sec.localToCanvasPoint(sec.datas.points[i]),
sec.localToCanvasPoint(sec.datas.points[i + 1]),
this.position
);
const p = calculateFootPointFromPointToLine(
sec.localToCanvasPoint(sec.datas.points[i]),
sec.localToCanvasPoint(sec.datas.points[i + 1]),
this.position
);
const onLine = isPointOnLine(
sec.localToCanvasPoint(sec.datas.points[i]),
sec.localToCanvasPoint(sec.datas.points[i + 1]),
p
);
if (onLine && d < minD) {
minD = d;
deviceId = sec.id;
deviceType = sec.type;
port = SectionPort.A;
}
}
});
turnouts.forEach((turnout: Turnout) => {
for (let i = 0; i < turnout.datas.pointA.length; i++) {
const p1 = turnout.localToCanvasPoint(
i === 0 ? new Point(0, 0) : turnout.datas.pointA[i - 1]
);
const p2 = turnout.localToCanvasPoint(turnout.datas.pointA[i]);
const d = calculateDistanceFromPointToLine(p1, p2, this.position);
const p = calculateFootPointFromPointToLine(p1, p2, this.position);
const onLine = isPointOnLine(p1, p2, p);
if (onLine && d < minD) {
minD = d;
deviceId = turnout.id;
deviceType = turnout.type;
port = TurnoutPort.A;
}
}
for (let i = 0; i < turnout.datas.pointB.length; i++) {
const p1 = turnout.localToCanvasPoint(
i === 0 ? new Point(0, 0) : turnout.datas.pointB[i - 1]
);
const p2 = turnout.localToCanvasPoint(turnout.datas.pointB[i]);
const d = calculateDistanceFromPointToLine(p1, p2, this.position);
const p = calculateFootPointFromPointToLine(p1, p2, this.position);
const onLine = isPointOnLine(p1, p2, p);
if (onLine && d < minD) {
minD = d;
deviceId = turnout.id;
deviceType = turnout.type;
port = TurnoutPort.B;
}
}
for (let i = 0; i < turnout.datas.pointC.length; i++) {
const p1 = turnout.localToCanvasPoint(
i === 0 ? new Point(0, 0) : turnout.datas.pointC[i - 1]
);
const p2 = turnout.localToCanvasPoint(turnout.datas.pointC[i]);
const d = calculateDistanceFromPointToLine(p1, p2, this.position);
const p = calculateFootPointFromPointToLine(p1, p2, this.position);
const onLine = isPointOnLine(p1, p2, p);
if (onLine && d < minD) {
minD = d;
deviceId = turnout.id;
deviceType = turnout.type;
port = TurnoutPort.C;
}
}
});
if (deviceId) {
this.datas.refDev = createRelatedRefProto(deviceType, deviceId, port);
}
}
} }
export class SignalTemplate extends JlGraphicTemplate<Signal> { export class SignalTemplate extends JlGraphicTemplate<Signal> {

View File

@ -6,25 +6,12 @@ import {
VectorText, VectorText,
calculateLineMidpoint, calculateLineMidpoint,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { SlopeKiloMarker } from '../slopeKiloMarker/SlopeKiloMarker';
export interface ITurnoutPosRefData {
get id(): string; //道岔的ID
set id(v: string);
get position(): number; //道岔的正反为0是正位1是反位
set position(v: number);
}
export interface ISlopeData extends GraphicData { export interface ISlopeData extends GraphicData {
get code(): string; // 名称
set code(v: string);
get points(): IPointData[]; // 线坐标点 get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]); set points(points: IPointData[]);
get slopeNumber(): string; // 坡度的值 get slopeNumber(): number; // 坡度的值
set slopeNumber(v: string); set slopeNumber(v: number);
get slopeDirection(): string; //坡度方向 有三种,无坡度--上坡--下坡
set slopeDirection(v: string);
get slopeLong(): number; //该坡度的长度--两端公里标的差值
set slopeLong(v: number);
get refDeviceId(): string[]; // 坡度关联的设备id get refDeviceId(): string[]; // 坡度关联的设备id
set refDeviceId(v: string[]); set refDeviceId(v: string[]);
clone(): ISlopeData; clone(): ISlopeData;
@ -35,7 +22,7 @@ export interface ISlopeData extends GraphicData {
export const SlopeConsts = { export const SlopeConsts = {
lineColor: '0xffffff', lineColor: '0xffffff',
lineWidth: 2, lineWidth: 2,
height: 40, height: 100,
}; };
export class Slope extends JlGraphic { export class Slope extends JlGraphic {
@ -73,13 +60,11 @@ export class Slope extends JlGraphic {
this.lineGraphic.clear(); this.lineGraphic.clear();
this.lineGraphic.lineStyle(SlopeConsts.lineWidth, SlopeConsts.lineColor); this.lineGraphic.lineStyle(SlopeConsts.lineWidth, SlopeConsts.lineColor);
let distanceY = 0; let distanceY = 0;
switch (this.datas.slopeDirection) { if (this.datas.slopeNumber !== 0) {
case 'up': distanceY =
distanceY = -SlopeConsts.height / 2; this.datas.slopeNumber > 0
break; ? -SlopeConsts.height / 2
case 'down': : SlopeConsts.height / 2;
distanceY = SlopeConsts.height / 2;
break;
} }
this.datas.points.forEach((p, i) => { this.datas.points.forEach((p, i) => {
if (i !== 0) { if (i !== 0) {
@ -89,7 +74,7 @@ export class Slope extends JlGraphic {
} }
}); });
//坡度值 //坡度值
this.slopeNumber.text = this.datas.slopeNumber; this.slopeNumber.text = parseFloat(this.datas.slopeNumber / 1000 + '');
const slopeNumberPosition = this.datas.childTransforms?.find( const slopeNumberPosition = this.datas.childTransforms?.find(
(t) => t.name === this.slopeNumber.name (t) => t.name === this.slopeNumber.name
)?.transform.position; )?.transform.position;
@ -106,7 +91,15 @@ export class Slope extends JlGraphic {
this.slopeNumber.position.set(centerPos.x, centerPos.y - 15); this.slopeNumber.position.set(centerPos.x, centerPos.y - 15);
} }
//坡度长度 //坡度长度
this.slopeLong.text = this.datas.slopeLong; const slopeKiloMarkerL = this.queryStore.queryById(
this.datas.refDeviceId[0]
) as SlopeKiloMarker;
const slopeKiloMarkerR = this.queryStore.queryById(
this.datas.refDeviceId[1]
) as SlopeKiloMarker;
this.slopeLong.text =
slopeKiloMarkerR.datas.kilometerSystem.kilometer -
slopeKiloMarkerL.datas.kilometerSystem.kilometer;
const slopeLongPosition = this.datas.childTransforms?.find( const slopeLongPosition = this.datas.childTransforms?.find(
(t) => t.name === this.slopeLong.name (t) => t.name === this.slopeLong.name
)?.transform.position; )?.transform.position;

View File

@ -9,7 +9,7 @@ import {
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { ISlopeData, Slope, SlopeTemplate, SlopeConsts } from './Slope'; import { ISlopeData, Slope, SlopeTemplate, SlopeConsts } from './Slope';
import { AxleCounting } from '../axleCounting/AxleCounting'; import { SlopeKiloMarker } from '../slopeKiloMarker/SlopeKiloMarker';
export interface ISlopeDrawOptions { export interface ISlopeDrawOptions {
newData: () => ISlopeData; newData: () => ISlopeData;
@ -44,7 +44,7 @@ export class SlopeDraw extends GraphicDrawAssistant<SlopeTemplate, ISlopeData> {
data.transform = this.container.saveTransform(); data.transform = this.container.saveTransform();
return true; return true;
} }
draw(graphics: AxleCounting[], map: Map<string, number>) { draw(graphics: SlopeKiloMarker[], map: Map<string, number>) {
if ( if (
map.has(`${graphics[0].id}+${graphics[1].id}`) || map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`) map.has(`${graphics[1].id}+${graphics[0].id}`)
@ -61,18 +61,26 @@ export class SlopeDraw extends GraphicDrawAssistant<SlopeTemplate, ISlopeData> {
} }
oneGenerates() { oneGenerates() {
const map = new Map(); const map = new Map();
const slopes = this.app.queryStore.queryByType<Slope>(Slope.Type); for (let dirSlop = 0; dirSlop < 2; dirSlop++) {
const axleCountings = this.app.queryStore.queryByType<AxleCounting>( const slopes = this.app.queryStore
AxleCounting.Type .queryByType<Slope>(Slope.Type)
); .filter((g) => {
axleCountings.sort((a, b) => a.position.x - b.position.x); const refSlopeKiloMarker = this.app.queryStore.queryById(
const axleCountingsPos = axleCountings.map((g) => g.position.x); g.datas.refDeviceId[0]
) as SlopeKiloMarker;
return refSlopeKiloMarker.datas.direction == dirSlop;
});
const slopeKiloMarkers = this.app.queryStore
.queryByType<SlopeKiloMarker>(SlopeKiloMarker.Type)
.filter((g) => g.datas.direction == dirSlop);
slopeKiloMarkers.sort((a, b) => a.position.x - b.position.x);
const slopeKiloMarkersPos = slopeKiloMarkers.map((g) => g.position.x);
//检验坡度有效性--是否有增加和删除 //检验坡度有效性--是否有增加和删除
slopes.forEach((slope) => { slopes.forEach((slope) => {
const pS = slope.datas.points[0].x; const pS = slope.datas.points[0].x;
const mapS = axleCountingsPos.findIndex((x) => x == pS); const mapS = slopeKiloMarkersPos.findIndex((x) => x == pS);
const pE = slope.datas.points[1].x; const pE = slope.datas.points[1].x;
const mapE = axleCountingsPos.findIndex((x) => x == pE); const mapE = slopeKiloMarkersPos.findIndex((x) => x == pE);
if (mapS !== -1 && mapE !== -1 && mapE - mapS == 1) { if (mapS !== -1 && mapE !== -1 && mapE - mapS == 1) {
map.set( map.set(
`${slope.datas.refDeviceId[0]}+${slope.datas.refDeviceId[1]}`, `${slope.datas.refDeviceId[0]}+${slope.datas.refDeviceId[1]}`,
@ -82,8 +90,9 @@ export class SlopeDraw extends GraphicDrawAssistant<SlopeTemplate, ISlopeData> {
this.app.deleteGraphics(slope); this.app.deleteGraphics(slope);
} }
}); });
for (let i = 0; i < axleCountings.length - 1; i++) { for (let i = 0; i < slopeKiloMarkers.length - 1; i++) {
this.draw([axleCountings[i], axleCountings[i + 1]], map); this.draw([slopeKiloMarkers[i], slopeKiloMarkers[i + 1]], map);
}
} }
} }
} }
@ -119,6 +128,7 @@ export class SlopeInteraction extends GraphicInteractionPlugin<Slope> {
g.eventMode = 'static'; g.eventMode = 'static';
g.cursor = 'pointer'; g.cursor = 'pointer';
g.scalable = true; g.scalable = true;
g.draggable = false;
g.transformSave = true; g.transformSave = true;
g.lineGraphic.eventMode = 'static'; g.lineGraphic.eventMode = 'static';
g.lineGraphic.cursor = 'pointer'; g.lineGraphic.cursor = 'pointer';

View File

@ -1,11 +1,15 @@
import { Graphics } from 'pixi.js'; import { Graphics } from 'pixi.js';
import { import {
calculateDistanceFromPointToLine,
calculateFootPointFromPointToLine,
isPointOnLine,
GraphicData, GraphicData,
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
VectorText, VectorText,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { IRelatedRefData } from '../CommonGraphics'; import { IRelatedRefData, createRelatedRefProto } from '../CommonGraphics';
import { Section, SectionPort } from '../section/Section';
export enum CoachNum { export enum CoachNum {
Four = 0, Four = 0,
@ -88,6 +92,41 @@ export class StopPosition extends JlGraphic {
} }
this.signBody.endFill(); this.signBody.endFill();
} }
buildRelation() {
const sections = this.queryStore.queryByType<Section>(Section.Type);
let deviceId = '';
let deviceType = '';
let minD = Number.MAX_SAFE_INTEGER;
let port = SectionPort.A;
sections.forEach((sec: Section) => {
for (let i = 0; i < sec.datas.points.length - 1; i++) {
const d = calculateDistanceFromPointToLine(
sec.localToCanvasPoint(sec.datas.points[i]),
sec.localToCanvasPoint(sec.datas.points[i + 1]),
this.position
);
const p = calculateFootPointFromPointToLine(
sec.localToCanvasPoint(sec.datas.points[i]),
sec.localToCanvasPoint(sec.datas.points[i + 1]),
this.position
);
const onLine = isPointOnLine(
sec.localToCanvasPoint(sec.datas.points[i]),
sec.localToCanvasPoint(sec.datas.points[i + 1]),
p
);
if (onLine && d < minD) {
minD = d;
deviceId = sec.id;
deviceType = sec.type;
port = SectionPort.A;
}
}
});
if (deviceId) {
this.datas.refDev = createRelatedRefProto(deviceType, deviceId, port);
}
}
} }
export class StopPositionTemplate extends JlGraphicTemplate<StopPosition> { export class StopPositionTemplate extends JlGraphicTemplate<StopPosition> {

View File

@ -1,11 +1,20 @@
import { Container, Graphics } from 'pixi.js'; import { Container, Graphics, Point } from 'pixi.js';
import { import {
GraphicData, GraphicData,
GraphicRelationParam,
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
VectorText, VectorText,
linePoint,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { KilometerSystem } from '../signal/Signal'; import { KilometerSystem } from '../signal/Signal';
import {
IRelatedRefData,
createRelatedRefProto,
protoPort2Data,
} from '../CommonGraphics';
import { Section, SectionConsts, SectionPort } from '../section/Section';
import { Turnout, TurnoutConsts, TurnoutPort } from '../turnout/Turnout';
export interface ITransponderData extends GraphicData { export interface ITransponderData extends GraphicData {
get code(): string; // 编号 get code(): string; // 编号
@ -16,6 +25,8 @@ export interface ITransponderData extends GraphicData {
set index(v: number); set index(v: number);
get kilometerSystem(): KilometerSystem; get kilometerSystem(): KilometerSystem;
set kilometerSystem(v: KilometerSystem); set kilometerSystem(v: KilometerSystem);
get TransponderRef(): IRelatedRefData;
set TransponderRef(v: IRelatedRefData);
clone(): ITransponderData; clone(): ITransponderData;
copyFrom(data: ITransponderData): void; copyFrom(data: ITransponderData): void;
eq(other: ITransponderData): boolean; eq(other: ITransponderData): boolean;
@ -125,6 +136,7 @@ export class Transponder extends JlGraphic {
? TransponderConsts.wblineColor ? TransponderConsts.wblineColor
: TransponderConsts.lineColor; : TransponderConsts.lineColor;
polygonGraphic.lineStyle(TransponderConsts.lineWidth, lineColor); polygonGraphic.lineStyle(TransponderConsts.lineWidth, lineColor);
polygonGraphic.beginFill(TransponderConsts.lineColor, 0.00001); // 填充透明色(用于碰撞检测)
const indexArr = [0, 5, 7]; const indexArr = [0, 5, 7];
ps.forEach((item, index) => { ps.forEach((item, index) => {
if (indexArr.includes(index)) { if (indexArr.includes(index)) {
@ -133,6 +145,7 @@ export class Transponder extends JlGraphic {
polygonGraphic.lineTo(item[0], item[1]); polygonGraphic.lineTo(item[0], item[1]);
} }
}); });
polygonGraphic.endFill;
this.labelGraphic.paint(this.datas); this.labelGraphic.paint(this.datas);
const style = { const style = {
fill: lineColor, fill: lineColor,
@ -156,6 +169,102 @@ export class Transponder extends JlGraphic {
); );
} }
} }
buildRelation() {
this.relationManage.deleteRelationOfGraphic(this);
const { x, y } = this.position;
const sections = this.queryStore.queryByType<Section>(Section.Type);
const findSection = sections.find((section) => {
let s = false;
for (let i = 1; i < section.datas.points.length; i++) {
const p1 = section.datas.points[i - 1];
const p2 = section.datas.points[i];
if (
linePoint(
section.localToCanvasPoint(p1),
section.localToCanvasPoint(p2),
{ x, y },
SectionConsts.lineWidth
)
) {
s = true;
break;
}
}
return s;
});
if (findSection) {
this.relationManage.addRelation(
new GraphicRelationParam(this),
new GraphicRelationParam(findSection, SectionPort.A)
);
return;
}
let tPort: TurnoutPort | null = null;
const portList = [TurnoutPort.A, TurnoutPort.B, TurnoutPort.C];
const turnouts = this.queryStore.queryByType<Turnout>(Turnout.Type);
const findTurnout = turnouts.find((turnout) => {
let s = false;
const aPs = turnout.getPortPoints();
aPs.some((item, index) => {
const Ps = [new Point(0, 0), ...item];
for (let i = 1; i < Ps.length; i++) {
const p1 = Ps[i - 1];
const p2 = Ps[i];
if (
linePoint(
turnout.localToCanvasPoint(p1),
turnout.localToCanvasPoint(p2),
{ x, y },
TurnoutConsts.lineWidth
)
) {
s = true;
tPort = portList[index];
break;
}
}
return s;
});
return s;
});
if (findTurnout) {
this.relationManage.addRelation(
new GraphicRelationParam(this),
new GraphicRelationParam(findTurnout, tPort)
);
return;
}
}
saveRelations() {
const relationM = this.relationManage
.getRelationsOfGraphic(this)
.find(
(relation) =>
relation.getOtherGraphic(this) instanceof Section ||
relation.getOtherGraphic(this) instanceof Turnout
);
const device = relationM?.getOtherGraphic<Section | Turnout>(this);
if (device) {
this.datas.TransponderRef = createRelatedRefProto(
device.type,
device.id,
relationM?.getOtherRelationParam(this).param
);
}
}
loadRelations() {
if (this.datas?.TransponderRef?.id) {
this.relationManage.addRelation(
new GraphicRelationParam(this),
new GraphicRelationParam(
this.queryStore.queryById(this.datas.TransponderRef.id),
protoPort2Data(this.datas.TransponderRef.devicePort)
)
);
}
}
} }
export class TransponderTemplate extends JlGraphicTemplate<Transponder> { export class TransponderTemplate extends JlGraphicTemplate<Transponder> {

View File

@ -1,4 +1,4 @@
import { DisplayObject, FederatedPointerEvent, IHitArea, Point } from 'pixi.js'; import { DisplayObject, FederatedPointerEvent, Point } from 'pixi.js';
import { import {
AbsorbableLine, AbsorbableLine,
AbsorbablePosition, AbsorbablePosition,
@ -7,15 +7,11 @@ import {
GraphicTransformEvent, GraphicTransformEvent,
JlDrawApp, JlDrawApp,
JlGraphic, JlGraphic,
linePoint,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { import {
ITransponderData, ITransponderData,
Transponder, Transponder,
TransponderConsts,
TransponderTemplate, TransponderTemplate,
transponderTypeEnum,
transponderTypePoints,
} from './Transponder'; } from './Transponder';
export class TransponderDraw extends GraphicDrawAssistant< export class TransponderDraw extends GraphicDrawAssistant<
@ -51,30 +47,6 @@ export class TransponderDraw extends GraphicDrawAssistant<
} }
} }
//碰撞检测
export class TransponderGraphicHitArea implements IHitArea {
transponder: Transponder;
constructor(transponder: Transponder) {
this.transponder = transponder;
}
contains(x: number, y: number): boolean {
let contains = false;
const p = new Point(x, y);
const type = transponderTypeEnum[this.transponder.datas.transponderType];
const ps = transponderTypePoints[type];
const tolerance = TransponderConsts.lineWidth;
const indexArr = [0, 5, 7];
ps.forEach((item, index) => {
if (!indexArr.includes(index)) {
const p1 = new Point(ps[index - 1][0], ps[index - 1][1]);
const p2 = new Point(item[0], item[1]);
contains = contains || linePoint(p1, p2, p, tolerance);
}
});
return contains;
}
}
export class TransponderInteraction extends GraphicInteractionPlugin<Transponder> { export class TransponderInteraction extends GraphicInteractionPlugin<Transponder> {
static Name = 'Transponder_transform'; static Name = 'Transponder_transform';
constructor(app: JlDrawApp) { constructor(app: JlDrawApp) {
@ -92,7 +64,6 @@ export class TransponderInteraction extends GraphicInteractionPlugin<Transponder
g.polygonGraphic.eventMode = 'static'; g.polygonGraphic.eventMode = 'static';
g.polygonGraphic.cursor = 'pointer'; g.polygonGraphic.cursor = 'pointer';
g.polygonGraphic.scalable = true; g.polygonGraphic.scalable = true;
g.polygonGraphic.hitArea = new TransponderGraphicHitArea(g);
g.on('transformstart', this.transformstart, this); g.on('transformstart', this.transformstart, this);
g.labelGraphic.on('transformstart', this.codetransformstart, this); g.labelGraphic.on('transformstart', this.codetransformstart, this);
g.labelGraphic.draggable = true; g.labelGraphic.draggable = true;