This commit is contained in:
fan 2023-08-08 11:16:33 +08:00
commit dfc8f0c776
26 changed files with 1054 additions and 165 deletions

View File

@ -96,15 +96,23 @@
<esb-button-property <esb-button-property
v-else-if="drawStore.selectedGraphicType === EsbButton.Type" v-else-if="drawStore.selectedGraphicType === EsbButton.Type"
></esb-button-property> ></esb-button-property>
<KiloMarkerProperty <SlopeKiloMarkerProperty
v-else-if="drawStore.selectedGraphicType === SlopeKiloMarker.Type" v-else-if="drawStore.selectedGraphicType === SlopeKiloMarker.Type"
/> />
<CurvatureKiloMarkerProperty
v-else-if="
drawStore.selectedGraphicType === CurvatureKiloMarker.Type
"
/>
<slope-property <slope-property
v-else-if="drawStore.selectedGraphicType === Slope.Type" v-else-if="drawStore.selectedGraphicType === Slope.Type"
></slope-property> ></slope-property>
<link-property <link-property
v-else-if="drawStore.selectedGraphicType === Link.Type" v-else-if="drawStore.selectedGraphicType === Link.Type"
></link-property> ></link-property>
<curvature-property
v-else-if="drawStore.selectedGraphicType === Curvature.Type"
></curvature-property>
</q-card-section> </q-card-section>
</template> </template>
</q-card> </q-card>
@ -152,11 +160,16 @@ import GatedBoxProperty from './properties/GatedBoxProperty.vue';
import { GatedBox } from 'src/graphics/gatedBox/GatedBox'; import { GatedBox } from 'src/graphics/gatedBox/GatedBox';
import EsbButtonProperty from './properties/EsbButtonProperty.vue'; import EsbButtonProperty from './properties/EsbButtonProperty.vue';
import { EsbButton } from 'src/graphics/esbButton/EsbButton'; import { EsbButton } from 'src/graphics/esbButton/EsbButton';
import KiloMarkerProperty from './properties/KiloMarkerProperty.vue'; import SlopeKiloMarkerProperty from './properties/SlopeKiloMarkerProperty.vue';
import CurvatureKiloMarkerProperty from './properties/CurvatureKiloMarkerProperty.vue';
import { SlopeKiloMarker } from 'src/graphics/slopeKiloMarker/SlopeKiloMarker'; import { SlopeKiloMarker } from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
import { Slope } from 'src/graphics/slope/Slope'; import { Slope } from 'src/graphics/slope/Slope';
import SlopeProperty from './properties/SlopeProperty.vue'; import SlopeProperty from './properties/SlopeProperty.vue';
import { Link } from 'src/graphics/link/Link'; import { Link } from 'src/graphics/link/Link';
import LinkProperty from './properties/LinkProperty.vue'; import LinkProperty from './properties/LinkProperty.vue';
import { Curvature } from 'src/graphics/curvature/Curvature';
import CurvatureProperty from './properties/CurvatureProperty.vue';
import { CurvatureKiloMarker } from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
</script> </script>

View File

@ -0,0 +1,140 @@
<script setup lang="ts">
import { CurvatureKiloMarkerData } from 'src/drawApp/graphics/CurvatureKiloMarkerInteraction';
import { CurvatureKiloMarker } from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
import { useDrawStore } from 'src/stores/draw-store';
import { reactive, shallowRef, watchEffect } from 'vue';
const drawStore = useDrawStore();
const kiloMarkerModel = shallowRef(new CurvatureKiloMarkerData());
const kilometerSystem = reactive([
{
coordinateSystem: '',
kilometer: 0,
direction: 0,
},
{
coordinateSystem: '',
kilometer: 0,
direction: 0,
},
]);
const CoordinateSystemOptions = [
{ label: '车辆段', value: 'DEPOT' },
{ label: '停车场', value: 'PARKING_LOT' },
{ label: '正线', value: 'MAIN_LINE' },
{ label: '换线', value: 'TRANSFER' },
];
const directionOptions = [
{ label: '左行', value: 0 },
{ label: '右行', value: 1 },
];
watchEffect(() => {
const kiloMarker = drawStore.selectedGraphic;
if (kiloMarker && kiloMarker instanceof CurvatureKiloMarker) {
kiloMarkerModel.value = kiloMarker.saveData();
if (kiloMarkerModel.value.kilometerSystem.length > 0) {
kilometerSystem.forEach((ks, i) => {
ks.coordinateSystem =
kiloMarkerModel.value.kilometerSystem[i].coordinateSystem;
ks.kilometer = kiloMarkerModel.value.kilometerSystem[i].kilometer;
ks.direction = kiloMarkerModel.value.kilometerSystem[i].direction;
});
} else {
kilometerSystem.forEach((ks) => {
ks.coordinateSystem = '';
ks.kilometer = 0;
ks.direction = 0;
});
}
}
});
const onUpdate = () => {
const kiloMarker = drawStore.selectedGraphic as CurvatureKiloMarker;
kiloMarkerModel.value.kilometerSystem = kilometerSystem.map((ks) => ({
coordinateSystem: ks.coordinateSystem,
kilometer: ks.kilometer,
direction: ks.direction,
}));
if (kiloMarker) {
drawStore
.getDrawApp()
.updateGraphicAndRecord(kiloMarker, kiloMarkerModel.value);
}
};
</script>
<template>
<q-form class="q-gutter-sm">
<q-input
outlined
readonly
v-model="kiloMarkerModel.id"
label="id"
hint=""
/>
<!-- <q-input
outlined
label="索引编号"
type="textarea"
@blur="onUpdate"
v-model="logicSectionModel.index"
lazy-rules
autogrow
/> -->
<q-select
outlined
v-model="kilometerSystem[0].coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="坐标系"
></q-select>
<q-input
outlined
v-model.number="kilometerSystem[0].kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-select
outlined
v-model="kilometerSystem[0].direction"
:options="directionOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="方向"
></q-select>
<q-select
outlined
class="q-mt-lg"
v-model="kilometerSystem[1].coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="坐标系"
></q-select>
<q-input
outlined
v-model.number="kilometerSystem[1].kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-select
outlined
v-model="kilometerSystem[1].direction"
:options="directionOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="方向"
></q-select>
</q-form>
</template>
<style scoped></style>

View File

@ -0,0 +1,97 @@
<template>
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="curvatureModel.id" label="id" hint="" />
<q-input
outlined
readonly
label="曲度方向"
type="textarea"
@blur="onUpdate"
v-model="direction"
lazy-rules
autogrow
/>
<q-input
outlined
label="曲度半径"
type="number"
@blur="onUpdate"
v-model.number="curvatureModel.curvatureNumber"
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 curvatureKiloMarkerRelations"
:key="item"
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 { CurvatureData } from 'src/drawApp/graphics/CurvatureInteraction';
import { Curvature } from 'src/graphics/curvature/Curvature';
import { CurvatureKiloMarker } from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, ref, watch } from 'vue';
const drawStore = useDrawStore();
const curvatureModel = reactive(new CurvatureData());
const direction = ref('无曲度');
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Curvature.Type) {
curvatureModel.copyFrom(val.saveData() as CurvatureData);
if (curvatureModel.curvatureNumber !== 0) {
direction.value = curvatureModel.curvatureNumber > 0 ? '外侧' : '内侧';
}
}
}
);
onMounted(() => {
const curvature = drawStore.selectedGraphic as Curvature;
if (curvature) {
curvatureModel.copyFrom(curvature.saveData());
if (curvatureModel.curvatureNumber !== 0) {
direction.value = curvatureModel.curvatureNumber > 0 ? '外侧' : '内侧';
}
}
});
function onUpdate() {
const curvature = drawStore.selectedGraphic as Curvature;
if (curvature) {
drawStore.getDrawApp().updateGraphicAndRecord(curvature, curvatureModel);
}
}
const curvatureKiloMarkerRelations = computed(() => {
const curvature = drawStore.selectedGraphic as Curvature;
const relations = curvature?.relationManage.getRelationsOfGraphicAndOtherType(
curvature,
CurvatureKiloMarker.Type
);
const ref = relations.map(
(relation) =>
`${relation.getOtherGraphic<CurvatureKiloMarker>(curvature).datas.id}`
);
return Array.from(new Set(ref));
});
</script>

View File

@ -85,7 +85,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { SignalData } from 'src/drawApp/graphics/SignalInteraction'; import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
import { Section } from 'src/graphics/section/Section'; import { Section } from 'src/graphics/section/Section';
import { Signal } from 'src/graphics/signal/Signal'; import { Direction, Signal } from 'src/graphics/signal/Signal';
import { Turnout } from 'src/graphics/turnout/Turnout'; import { Turnout } from 'src/graphics/turnout/Turnout';
import { graphicData } from 'src/protos/stationLayoutGraphics'; import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
@ -93,7 +93,11 @@ import { onMounted, reactive, watch } from 'vue';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const signalModel = reactive(new SignalData()); const signalModel = reactive(new SignalData());
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 }); const kilometerSystem = reactive({
coordinateSystem: '',
kilometer: 0,
direction: Direction.LEFT,
});
const sectionList: { label: string; value: string }[] = reactive([]); const sectionList: { label: string; value: string }[] = reactive([]);
const turnoutList: { label: string; value: string }[] = reactive([]); const turnoutList: { label: string; value: string }[] = reactive([]);
const refDevData = reactive({ const refDevData = reactive({
@ -176,6 +180,7 @@ function onUpdate() {
signalModel.kilometerSystem = { signalModel.kilometerSystem = {
coordinateSystem: kilometerSystem.coordinateSystem, coordinateSystem: kilometerSystem.coordinateSystem,
kilometer: kilometerSystem.kilometer, kilometer: kilometerSystem.kilometer,
direction: kilometerSystem.direction,
}; };
if (refDevData.id) { if (refDevData.id) {
signalModel.refDev = new graphicData.RelatedRef({ signalModel.refDev = new graphicData.RelatedRef({

View File

@ -6,7 +6,18 @@ import { reactive, shallowRef, watchEffect } from 'vue';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const kiloMarkerModel = shallowRef(new SlopeKiloMarkerData()); const kiloMarkerModel = shallowRef(new SlopeKiloMarkerData());
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 }); const kilometerSystem = reactive([
{
coordinateSystem: '',
kilometer: 0,
direction: 0,
},
{
coordinateSystem: '',
kilometer: 0,
direction: 0,
},
]);
const CoordinateSystemOptions = [ const CoordinateSystemOptions = [
{ label: '车辆段', value: 'DEPOT' }, { label: '车辆段', value: 'DEPOT' },
@ -15,18 +26,37 @@ const CoordinateSystemOptions = [
{ label: '换线', value: 'TRANSFER' }, { label: '换线', value: 'TRANSFER' },
]; ];
const directionOptions = [ const directionOptions = [
{ label: '行', value: 0 }, { label: '行', value: 0 },
{ label: '行', value: 1 }, { label: '行', value: 1 },
]; ];
watchEffect(() => { watchEffect(() => {
const kiloMarker = drawStore.selectedGraphic; const kiloMarker = drawStore.selectedGraphic;
if (kiloMarker && kiloMarker instanceof SlopeKiloMarker) { if (kiloMarker && kiloMarker instanceof SlopeKiloMarker) {
kiloMarkerModel.value = kiloMarker.saveData(); kiloMarkerModel.value = kiloMarker.saveData();
if (kiloMarkerModel.value.kilometerSystem.length > 0) {
kilometerSystem.forEach((ks, i) => {
ks.coordinateSystem =
kiloMarkerModel.value.kilometerSystem[i].coordinateSystem;
ks.kilometer = kiloMarkerModel.value.kilometerSystem[i].kilometer;
ks.direction = kiloMarkerModel.value.kilometerSystem[i].direction;
});
} else {
kilometerSystem.forEach((ks) => {
ks.coordinateSystem = '';
ks.kilometer = 0;
ks.direction = 0;
});
}
} }
}); });
const onUpdate = () => { const onUpdate = () => {
const kiloMarker = drawStore.selectedGraphic as SlopeKiloMarker; const kiloMarker = drawStore.selectedGraphic as SlopeKiloMarker;
kiloMarkerModel.value.kilometerSystem = kilometerSystem.map((ks) => ({
coordinateSystem: ks.coordinateSystem,
kilometer: ks.kilometer,
direction: ks.direction,
}));
if (kiloMarker) { if (kiloMarker) {
drawStore drawStore
.getDrawApp() .getDrawApp()
@ -55,7 +85,7 @@ const onUpdate = () => {
/> --> /> -->
<q-select <q-select
outlined outlined
v-model="kilometerSystem.coordinateSystem" v-model="kilometerSystem[0].coordinateSystem"
:options="CoordinateSystemOptions" :options="CoordinateSystemOptions"
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"
@ -64,14 +94,40 @@ const onUpdate = () => {
></q-select> ></q-select>
<q-input <q-input
outlined outlined
v-model.number="kilometerSystem.kilometer" v-model.number="kilometerSystem[0].kilometer"
type="number" type="number"
@blur="onUpdate" @blur="onUpdate"
label="公里标(mm):" label="公里标(mm):"
/> />
<q-select <q-select
outlined outlined
v-model="kiloMarkerModel.direction" v-model="kilometerSystem[0].direction"
:options="directionOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="方向"
></q-select>
<q-select
outlined
class="q-mt-lg"
v-model="kilometerSystem[1].coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="坐标系"
></q-select>
<q-input
outlined
v-model.number="kilometerSystem[1].kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-select
outlined
v-model="kilometerSystem[1].direction"
:options="directionOptions" :options="directionOptions"
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"

View File

@ -33,10 +33,10 @@
<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">
<q-item-label> 关联的设备 </q-item-label> <q-item-label> 关联的坡度公里标 </q-item-label>
<div class="q-gutter-sm row"> <div class="q-gutter-sm row">
<q-chip <q-chip
v-for="item in axleCountingRelations" v-for="item in slopeKiloMarkerRelations"
:key="item" :key="item"
square square
color="primary" color="primary"
@ -53,8 +53,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { SlopeData } from 'src/drawApp/graphics/SlopeInteraction'; import { SlopeData } from 'src/drawApp/graphics/SlopeInteraction';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { Slope } from 'src/graphics/slope/Slope'; import { Slope } from 'src/graphics/slope/Slope';
import { SlopeKiloMarker } from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, ref, watch } from 'vue'; import { computed, onMounted, reactive, ref, watch } from 'vue';
@ -83,7 +83,7 @@ onMounted(() => {
if (slopeModel.slopeNumber !== 0) { if (slopeModel.slopeNumber !== 0) {
direction.value = slopeModel.slopeNumber > 0 ? '上坡' : '下坡'; direction.value = slopeModel.slopeNumber > 0 ? '上坡' : '下坡';
} }
slopeLong.value = +slopeModel.refDeviceId[1]; slopeLong.value = +slope.slopeLong.text;
} }
}); });
@ -94,15 +94,14 @@ function onUpdate() {
} }
} }
const axleCountingRelations = computed(() => { const slopeKiloMarkerRelations = computed(() => {
const slope = drawStore.selectedGraphic as Slope; const slope = drawStore.selectedGraphic as Slope;
const sectionRelations = const relations = slope?.relationManage.getRelationsOfGraphicAndOtherType(
slope?.relationManage.getRelationsOfGraphicAndOtherType( slope,
slope, SlopeKiloMarker.Type
AxleCounting.Type );
); const ref = relations.map(
const ref = sectionRelations.map( (relation) => `${relation.getOtherGraphic<SlopeKiloMarker>(slope).datas.id}`
(relation) => `${relation.getOtherGraphic<AxleCounting>(slope).datas.code}`
); );
return Array.from(new Set(ref)); return Array.from(new Set(ref));
}); });

View File

@ -80,6 +80,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction'; import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction';
import { Section } from 'src/graphics/section/Section'; import { Section } from 'src/graphics/section/Section';
import { Direction } from 'src/graphics/signal/Signal';
import { Turnout } from 'src/graphics/turnout/Turnout'; import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { computed, reactive, shallowRef, watchEffect } from 'vue'; import { computed, reactive, shallowRef, watchEffect } from 'vue';
@ -93,8 +94,8 @@ const CoordinateSystemOptions = [
]; ];
const turnoutModel = shallowRef(new TurnoutData()); const turnoutModel = shallowRef(new TurnoutData());
const kilometerSystem = reactive([ const kilometerSystem = reactive([
{ coordinateSystem: '', kilometer: 0 }, { coordinateSystem: '', kilometer: 0, direction: Direction.LEFT },
{ coordinateSystem: '', kilometer: 0 }, { coordinateSystem: '', kilometer: 0, direction: Direction.LEFT },
]); ]);
const sectionRelations = computed(() => { const sectionRelations = computed(() => {
@ -148,6 +149,7 @@ const onUpdate = () => {
turnoutModel.value.kilometerSystem = kilometerSystem.map((ks) => ({ turnoutModel.value.kilometerSystem = kilometerSystem.map((ks) => ({
coordinateSystem: ks.coordinateSystem, coordinateSystem: ks.coordinateSystem,
kilometer: ks.kilometer, kilometer: ks.kilometer,
direction: ks.direction,
})); }));
if (turnout) { if (turnout) {
drawStore.getDrawApp().updateGraphicAndRecord(turnout, turnoutModel.value); drawStore.getDrawApp().updateGraphicAndRecord(turnout, turnoutModel.value);

View File

@ -0,0 +1,52 @@
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase } from './GraphicDataBase';
import { ICurvatureData, Curvature } from 'src/graphics/curvature/Curvature';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { IPointData } from 'pixi.js';
export class CurvatureData extends GraphicDataBase implements ICurvatureData {
constructor(data?: graphicData.Curvature) {
let curvature;
if (!data) {
curvature = new graphicData.Curvature({
common: GraphicDataBase.defaultCommonInfo(Curvature.Type),
});
} else {
curvature = data;
}
super(curvature);
}
public get data(): graphicData.Curvature {
return this.getData<graphicData.Curvature>();
}
get points(): IPointData[] {
return this.data.points;
}
set points(points: IPointData[]) {
this.data.points = points.map(
(p) => new graphicData.Point({ x: p.x, y: p.y })
);
}
get curvatureNumber(): number {
return this.data.curvatureNumber;
}
set curvatureNumber(v: number) {
this.data.curvatureNumber = v;
}
get refDeviceId(): string[] {
return this.data.refDeviceId;
}
set refDeviceId(v: string[]) {
this.data.refDeviceId = v;
}
clone(): CurvatureData {
return new CurvatureData(this.data.cloneMessage());
}
copyFrom(data: CurvatureData): void {
pb_1.Message.copyInto(data.data, this.data);
}
eq(other: CurvatureData): boolean {
return pb_1.Message.equals(this.data, other.data);
}
}

View File

@ -0,0 +1,52 @@
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase } from './GraphicDataBase';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { KilometerSystem } from 'src/graphics/signal/Signal';
import { IKiloMarkerData } from 'src/graphics/kilometerMarker/KilometerMarker';
import { CurvatureKiloMarker } from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
export class CurvatureKiloMarkerData
extends GraphicDataBase
implements IKiloMarkerData
{
constructor(data?: graphicData.CurvatureKiloMarker) {
let platform;
if (!data) {
platform = new graphicData.CurvatureKiloMarker({
common: GraphicDataBase.defaultCommonInfo(CurvatureKiloMarker.Type),
});
} else {
platform = data;
}
super(platform);
}
public get data(): graphicData.CurvatureKiloMarker {
return this.getData<graphicData.CurvatureKiloMarker>();
}
get code(): string {
return this.data.code;
}
set code(v: string) {
this.data.code = v;
}
get kilometerSystem(): KilometerSystem[] {
return this.data.kilometerSystem;
}
set kilometerSystem(value: KilometerSystem[]) {
this.data.kilometerSystem = value.map(
(v) => new graphicData.KilometerSystem(v)
);
}
clone(): CurvatureKiloMarkerData {
return new CurvatureKiloMarkerData(this.data.cloneMessage());
}
copyFrom(data: CurvatureKiloMarkerData): void {
pb_1.Message.copyInto(data.data, this.data);
}
eq(other: CurvatureKiloMarkerData): boolean {
return pb_1.Message.equals(this.data, other.data);
}
}

View File

@ -1,14 +1,13 @@
import * as pb_1 from 'google-protobuf'; import * as pb_1 from 'google-protobuf';
import { import { SlopeKiloMarker } from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
ISlopeKiloMarkerData,
SlopeKiloMarker,
} from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
import { GraphicDataBase } from './GraphicDataBase'; import { GraphicDataBase } from './GraphicDataBase';
import { graphicData } from 'src/protos/stationLayoutGraphics'; import { graphicData } from 'src/protos/stationLayoutGraphics';
import { KilometerSystem } from 'src/graphics/signal/Signal';
import { IKiloMarkerData } from 'src/graphics/kilometerMarker/KilometerMarker';
export class SlopeKiloMarkerData export class SlopeKiloMarkerData
extends GraphicDataBase extends GraphicDataBase
implements ISlopeKiloMarkerData implements IKiloMarkerData
{ {
constructor(data?: graphicData.SlopeKiloMarker) { constructor(data?: graphicData.SlopeKiloMarker) {
let platform; let platform;
@ -32,17 +31,13 @@ export class SlopeKiloMarkerData
set code(v: string) { set code(v: string) {
this.data.code = v; this.data.code = v;
} }
get direction(): graphicData.Direction { get kilometerSystem(): KilometerSystem[] {
return this.data.direction;
}
set direction(v: graphicData.Direction) {
this.data.direction = v;
}
get kilometerSystem(): graphicData.KilometerSystem {
return this.data.kilometerSystem; return this.data.kilometerSystem;
} }
set kilometerSystem(v: graphicData.KilometerSystem) { set kilometerSystem(value: KilometerSystem[]) {
this.data.kilometerSystem = v; this.data.kilometerSystem = value.map(
(v) => new graphicData.KilometerSystem(v)
);
} }
clone(): SlopeKiloMarkerData { clone(): SlopeKiloMarkerData {

View File

@ -122,10 +122,18 @@ import { SlopeData } from './graphics/SlopeInteraction';
import { Slope, SlopeTemplate } from 'src/graphics/slope/Slope'; import { Slope, SlopeTemplate } from 'src/graphics/slope/Slope';
import { useLineStore } from 'src/stores/line-store'; import { useLineStore } from 'src/stores/line-store';
import { LinkData } from './graphics/LinkInteraction'; import { LinkData } from './graphics/LinkInteraction';
import { ILinkData, Link, LinkTemplate } from 'src/graphics/link/Link'; import { Link, LinkTemplate } from 'src/graphics/link/Link';
import { generateCalculateLink } from 'src/api/GenerateApi'; import { generateCalculateLink } from 'src/api/GenerateApi';
import { Point } from 'pixi.js';
import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant'; import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant';
import {
CurvatureKiloMarker,
CurvatureKiloMarkerTemplate,
} from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
import { CurvatureKiloMarkerDrawAssistant } from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarkerDrawAssistant';
import { CurvatureKiloMarkerData } from './graphics/CurvatureKiloMarkerInteraction';
import { Curvature, CurvatureTemplate } from 'src/graphics/curvature/Curvature';
import { CurvatureData } from './graphics/CurvatureInteraction';
import { CurvatureDraw } from 'src/graphics/curvature/CurvatureAssistant';
// export function fromStoragePoint(p: graphicData.Point): Point { // export function fromStoragePoint(p: graphicData.Point): Point {
// return new Point(p.x, p.y); // return new Point(p.x, p.y);
@ -213,7 +221,10 @@ const showType = [
EsbButton.Type, EsbButton.Type,
Transponder.Type, Transponder.Type,
TrainWindow.Type, TrainWindow.Type,
SlopeKiloMarker.Type,
Slope.Type, Slope.Type,
CurvatureKiloMarker.Type,
Curvature.Type,
]; ];
export const drawLayerList = [ export const drawLayerList = [
// 图层列表 // 图层列表
@ -263,6 +274,8 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
| SlopeKiloMarkerDrawAssistant | SlopeKiloMarkerDrawAssistant
| SlopeDraw | SlopeDraw
| LinkDraw | LinkDraw
| CurvatureKiloMarkerDrawAssistant
| CurvatureDraw
)[] = []; )[] = [];
if (draftType === 'Line') { if (draftType === 'Line') {
drawAssistants = [ drawAssistants = [
@ -314,6 +327,11 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
), ),
new SlopeDraw(app, new SlopeTemplate(new SlopeData())), new SlopeDraw(app, new SlopeTemplate(new SlopeData())),
new LinkDraw(app, new LinkTemplate(new LinkData())), new LinkDraw(app, new LinkTemplate(new LinkData())),
new CurvatureKiloMarkerDrawAssistant(
app,
new CurvatureKiloMarkerTemplate(new CurvatureKiloMarkerData())
),
new CurvatureDraw(app, new CurvatureTemplate(new CurvatureData())),
]; ];
DrawSignalInteraction.init(app); DrawSignalInteraction.init(app);
DrawStopPositionInteraction.init(app); DrawStopPositionInteraction.init(app);
@ -482,6 +500,14 @@ export function saveDrawDatas(app: JlDrawApp) {
} else if (Slope.Type === g.type) { } else if (Slope.Type === g.type) {
const slopeData = (g as Slope).saveData(); const slopeData = (g as Slope).saveData();
storage.slopes.push((slopeData as SlopeData).data); storage.slopes.push((slopeData as SlopeData).data);
} else if (CurvatureKiloMarker.Type === g.type) {
const curvatureKiloMarkerData = (g as CurvatureKiloMarker).saveData();
storage.curvatureKiloMarker.push(
(curvatureKiloMarkerData as CurvatureKiloMarkerData).data
);
} else if (Curvature.Type === g.type) {
const curvatureData = (g as Curvature).saveData();
storage.curvatures.push((curvatureData as CurvatureData).data);
} }
}); });
const base64 = fromUint8Array(storage.serialize()); const base64 = fromUint8Array(storage.serialize());
@ -622,9 +648,15 @@ export async function loadDrawDatas(app: GraphicApp) {
storage.slopeKiloMarker.forEach((slopeKiloMarker) => { storage.slopeKiloMarker.forEach((slopeKiloMarker) => {
datas.push(new SlopeKiloMarkerData(slopeKiloMarker)); datas.push(new SlopeKiloMarkerData(slopeKiloMarker));
}); });
storage.curvatureKiloMarker.forEach((curvatureKiloMarker) => {
datas.push(new CurvatureKiloMarkerData(curvatureKiloMarker));
});
storage.slopes.forEach((slope) => { storage.slopes.forEach((slope) => {
datas.push(new SlopeData(slope)); datas.push(new SlopeData(slope));
}); });
storage.curvatures.forEach((curvature) => {
datas.push(new CurvatureData(curvature));
});
await app.loadGraphic(datas); await app.loadGraphic(datas);
} else { } else {
app.loadGraphic([]); app.loadGraphic([]);

View File

@ -289,6 +289,9 @@ export async function loadLineDatas(app: GraphicApp) {
storage.transponders.forEach((transponder) => { storage.transponders.forEach((transponder) => {
datas.push(new TransponderData(transponder)); datas.push(new TransponderData(transponder));
}); });
storage.slopeKiloMarker.forEach((slopeKilometer) => {
datas.push(new SlopeKiloMarkerData(slopeKilometer));
});
await app.loadGraphic(datas); await app.loadGraphic(datas);
const alllGraphic = (lineApp as GraphicApp).queryStore.getAllGraphics(); const alllGraphic = (lineApp as GraphicApp).queryStore.getAllGraphics();

View File

@ -0,0 +1,107 @@
import { Graphics, IPointData } from 'pixi.js';
import {
GraphicData,
JlGraphic,
JlGraphicTemplate,
VectorText,
calculateLineMidpoint,
} from 'src/jl-graphic';
import { KiloMarkerConsts } from '../kilometerMarker/KilometerMarker';
export interface ICurvatureData extends GraphicData {
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
get curvatureNumber(): number; // 曲度的值
set curvatureNumber(v: number);
get refDeviceId(): string[]; // 曲度关联的设备id
set refDeviceId(v: string[]);
clone(): ICurvatureData;
copyFrom(data: ICurvatureData): void;
eq(other: ICurvatureData): boolean;
}
export const CurvatureConsts = {
lineColor: '0xffffff',
lineWidth: 2,
};
export class Curvature extends JlGraphic {
static Type = 'Curvature';
lineGraphic: Graphics;
curvatureNumber: VectorText;
constructor() {
super(Curvature.Type);
this.lineGraphic = new Graphics();
this.curvatureNumber = new VectorText();
this.curvatureNumber.name = 'curvatureNumber';
const vectorTexts = [this.curvatureNumber];
vectorTexts.forEach((vectorText) => {
vectorText.setVectorFontSize(14);
vectorText.anchor.set(0.5);
vectorText.style.fill = '0xffffff';
vectorText.transformSave = true;
});
this.transformSave = true;
this.addChild(this.lineGraphic);
this.addChild(this.curvatureNumber);
}
get datas(): ICurvatureData {
return this.getDatas<ICurvatureData>();
}
doRepaint(): void {
if (this.datas.points.length < 2) {
throw new Error('Curvature坐标数据异常');
}
this.lineGraphic.clear();
this.lineGraphic.lineStyle(
CurvatureConsts.lineWidth,
CurvatureConsts.lineColor
);
let distanceY = 0;
if (this.datas.curvatureNumber !== 0) {
distanceY =
this.datas.curvatureNumber > 0
? -KiloMarkerConsts.size / 2
: KiloMarkerConsts.size / 2;
}
this.datas.points.forEach((p, i) => {
if (i !== 0) {
this.lineGraphic.lineTo(p.x, p.y + distanceY);
} else {
this.lineGraphic.moveTo(p.x, p.y + distanceY);
}
});
//曲度值
const text = Math.abs(this.datas.curvatureNumber);
this.curvatureNumber.text = text ? `R-${text}` : '';
const centerPos = calculateLineMidpoint(
this.datas.points[0],
this.datas.points[this.datas.points.length - 1]
);
this.curvatureNumber.position.set(
centerPos.x,
centerPos.y + distanceY - 15
);
}
loadRelations() {
if (this.datas.refDeviceId.length) {
this.datas.refDeviceId.forEach((id) => {
const curvatureKiloMarker = this.queryStore.queryById(id);
this.relationManage.addRelation(this, curvatureKiloMarker);
});
}
}
}
export class CurvatureTemplate extends JlGraphicTemplate<Curvature> {
constructor(dataTemplate: ICurvatureData) {
super(Curvature.Type, {
dataTemplate,
});
}
new(): Curvature {
const curvature = new Curvature();
curvature.loadData(this.datas);
return curvature;
}
}

View File

@ -0,0 +1,157 @@
import { FederatedPointerEvent, IHitArea, Point } from 'pixi.js';
import {
GraphicDrawAssistant,
GraphicIdGenerator,
GraphicInteractionPlugin,
JlDrawApp,
JlGraphic,
pointBox,
} from 'src/jl-graphic';
import { ICurvatureData, Curvature, CurvatureTemplate } from './Curvature';
import { CurvatureKiloMarker } from '../curvatureKiloMarker/CurvatureKiloMarker';
export interface ICurvatureDrawOptions {
newData: () => ICurvatureData;
}
export class CurvatureDraw extends GraphicDrawAssistant<
CurvatureTemplate,
ICurvatureData
> {
codeGraph: Curvature;
constructor(app: JlDrawApp, template: CurvatureTemplate) {
super(app, template, 'sym_o_circle', '不展示');
this.codeGraph = this.graphicTemplate.new();
this.container.addChild(this.codeGraph);
CurvatureInteraction.init(app);
}
bind(): void {
super.bind();
this.codeGraph.loadData(this.graphicTemplate.datas);
this.codeGraph.doRepaint();
}
clearCache(): void {
//this.codeGraph.destroy();
}
onLeftDown(e: FederatedPointerEvent): void {
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(true);
}
redraw(p: Point): void {
this.container.position.copyFrom(p);
}
prepareData(data: ICurvatureData): boolean {
data.transform = this.container.saveTransform();
return true;
}
draw(graphics: CurvatureKiloMarker[], map: Map<string, number>) {
if (
map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`)
)
return;
map.set(`${graphics[0].id}+${graphics[1].id}`, 1);
const curvature = new Curvature();
curvature.loadData(this.graphicTemplate.datas);
curvature.datas.points = [graphics[0].position, graphics[1].position];
curvature.id = GraphicIdGenerator.next();
curvature.datas.refDeviceId = [graphics[0].id, graphics[1].id];
this.storeGraphic(curvature);
curvature.loadRelations();
}
oneGenerates() {
const map = new Map();
for (let dirSlop = 0; dirSlop < 2; dirSlop++) {
const curvatures = this.app.queryStore
.queryByType<Curvature>(Curvature.Type)
.filter((g) => {
let refCurvatureKiloMarker;
try {
refCurvatureKiloMarker = this.app.queryStore.queryById(
g.datas.refDeviceId[0]
) as CurvatureKiloMarker;
} catch (error) {
this.app.deleteGraphics(g);
}
return (
refCurvatureKiloMarker?.datas.kilometerSystem[0].direction ==
dirSlop
);
});
const curvatureKiloMarkers = this.app.queryStore
.queryByType<CurvatureKiloMarker>(CurvatureKiloMarker.Type)
.filter((g) => g.datas.kilometerSystem[0]?.direction == dirSlop);
curvatureKiloMarkers.sort((a, b) => a.position.x - b.position.x);
const curvatureKiloMarkersPos = curvatureKiloMarkers.map(
(g) => g.position.x
);
//检验曲度有效性--是否有增加和删除
curvatures.forEach((curvature) => {
const pS = curvature.datas.points[0].x;
const mapS = curvatureKiloMarkersPos.findIndex((x) => x == pS);
const pE = curvature.datas.points[1].x;
const mapE = curvatureKiloMarkersPos.findIndex((x) => x == pE);
if (mapS !== -1 && mapE !== -1 && mapE - mapS == 1) {
map.set(
`${curvature.datas.refDeviceId[0]}+${curvature.datas.refDeviceId[1]}`,
1
);
} else {
this.app.deleteGraphics(curvature);
}
});
for (let i = 0; i < curvatureKiloMarkers.length - 1; i++) {
this.draw([curvatureKiloMarkers[i], curvatureKiloMarkers[i + 1]], map);
}
}
}
}
class CurvatureGraphicHitArea implements IHitArea {
curvature: Curvature;
constructor(curvature: Curvature) {
this.curvature = curvature;
}
contains(x: number, y: number): boolean {
let contains = false;
const p = new Point(x, y);
const r = this.curvature.getLocalBounds();
contains = pointBox(p, r);
return contains;
}
}
export class CurvatureInteraction extends GraphicInteractionPlugin<Curvature> {
static Name = 'Curvature_transform';
constructor(app: JlDrawApp) {
super(CurvatureInteraction.Name, app);
}
static init(app: JlDrawApp) {
return new CurvatureInteraction(app);
}
filter(...grahpics: JlGraphic[]): Curvature[] | undefined {
return grahpics
.filter((g) => g.type === Curvature.Type)
.map((g) => g as Curvature);
}
bind(g: Curvature): void {
g.eventMode = 'static';
g.cursor = 'pointer';
g.scalable = true;
g.draggable = false;
g.transformSave = true;
g.lineGraphic.eventMode = 'static';
g.lineGraphic.cursor = 'pointer';
g.lineGraphic.hitArea = new CurvatureGraphicHitArea(g);
}
unbind(g: Curvature): void {
g.eventMode = 'none';
g.lineGraphic.eventMode = 'none';
g.lineGraphic.draggable = false;
g.lineGraphic.selectable = false;
g.lineGraphic.transformSave = false;
}
}

View File

@ -0,0 +1,50 @@
import { JlGraphic, JlGraphicTemplate } from 'src/jl-graphic';
import {
IKiloMarkerData,
KiloMarkerConsts,
KilometerMarker,
} from '../kilometerMarker/KilometerMarker';
export class CurvatureKiloMarker extends JlGraphic {
static Type = 'CurvatureKiloMarker';
graphic: KilometerMarker;
size = KiloMarkerConsts.size;
constructor() {
super(CurvatureKiloMarker.Type);
this.graphic = new KilometerMarker();
this.addChild(this.graphic);
}
get datas(): IKiloMarkerData {
return this.getDatas<IKiloMarkerData>();
}
doRepaint(): void {
this.graphic.paint();
}
getPoint(position: 'up' | 'down' | 'mid') {
const p = this.transform.position.clone();
if (position === 'up') {
p.y -= this.size;
return p;
} else if (position === 'down') {
p.y += this.size;
return p;
} else if (position === 'mid') {
return p;
}
}
}
export class CurvatureKiloMarkerTemplate extends JlGraphicTemplate<CurvatureKiloMarker> {
constructor(dataTemplate: IKiloMarkerData) {
super(CurvatureKiloMarker.Type, {
dataTemplate,
});
}
new(): CurvatureKiloMarker {
const curvatureKiloMarker = new CurvatureKiloMarker();
curvatureKiloMarker.loadData(this.datas);
return curvatureKiloMarker;
}
}

View File

@ -0,0 +1,102 @@
import {
GraphicApp,
GraphicDrawAssistant,
GraphicInteractionPlugin,
JlDrawApp,
JlGraphic,
linePoint,
} from 'src/jl-graphic';
import { FederatedMouseEvent, IHitArea, Point } from 'pixi.js';
import { IKiloMarkerData } from '../kilometerMarker/KilometerMarker';
import {
CurvatureKiloMarker,
CurvatureKiloMarkerTemplate,
} from './CurvatureKiloMarker';
export class KilometerMarkerHitArea implements IHitArea {
kiloMarker: CurvatureKiloMarker;
constructor(kiloMarker: CurvatureKiloMarker) {
this.kiloMarker = kiloMarker;
}
contains(x: number, y: number): boolean {
const { position } = this.kiloMarker.transform;
return linePoint(
this.kiloMarker.canvasToLocalPoint({ x: position.x, y: position.y - 50 }),
this.kiloMarker.canvasToLocalPoint({ x: position.x, y: position.y + 50 }),
{ x, y },
2
);
}
}
export class CurvatureKiloMarkerDrawAssistant extends GraphicDrawAssistant<
CurvatureKiloMarkerTemplate,
IKiloMarkerData
> {
curvatureKiloMarker: CurvatureKiloMarker;
constructor(app: JlDrawApp, template: CurvatureKiloMarkerTemplate) {
super(app, template, 'sym_o_golf_course', '曲度公里标');
this.curvatureKiloMarker = this.graphicTemplate.new();
this.container.addChild(this.curvatureKiloMarker);
CurvatureKiloMarkerInteractionPlugin.init(app);
}
onLeftDown(e: FederatedMouseEvent): void {
this.createAndStore(true);
}
redraw(cp: Point): void {
const list = this.app.queryStore.queryByType<CurvatureKiloMarker>(
CurvatureKiloMarker.Type
);
const ys = list.reduce<number[]>((prev, curr, i) => {
const currentY = curr.datas.transform.position.y;
if (!prev.includes(currentY)) {
return [currentY, ...prev];
} else {
return prev;
}
}, []);
if (list.length) {
const matchY = ys.find(
(y) => Math.abs(cp.y - y) <= this.curvatureKiloMarker.size
);
if (matchY) {
this.container.position.set(cp.x, matchY);
return;
}
}
this.container.position.set(cp.x, cp.y);
}
prepareData(data: IKiloMarkerData): boolean {
data.transform = this.container.saveTransform();
return true;
}
}
export class CurvatureKiloMarkerInteractionPlugin extends GraphicInteractionPlugin<CurvatureKiloMarker> {
static Name = 'CurvatureKiloMarkerInteraction';
constructor(app: GraphicApp) {
super(CurvatureKiloMarkerInteractionPlugin.Name, app);
}
static init(app: GraphicApp) {
return new CurvatureKiloMarkerInteractionPlugin(app);
}
filter(...grahpics: JlGraphic[]): CurvatureKiloMarker[] | undefined {
return grahpics.filter(
(g): g is CurvatureKiloMarker => g instanceof CurvatureKiloMarker
);
}
bind(g: CurvatureKiloMarker): void {
g.graphic.eventMode = 'static';
g.graphic.cursor = 'pointer';
g.graphic.selectable = true;
g.graphic.draggable = false;
g.graphic.hitArea = new KilometerMarkerHitArea(g);
}
unbind(g: CurvatureKiloMarker): void {
console.log(g);
}
}

View File

@ -1,8 +1,25 @@
import { Graphics } from 'pixi.js'; import { Graphics } from 'pixi.js';
import { KilometerSystem } from '../signal/Signal';
import { GraphicData } from 'src/jl-graphic';
export const KiloMarkerConsts = {
size: 50,
};
export interface IKiloMarkerData extends GraphicData {
get code(): string; // 编号
set code(v: string);
get kilometerSystem(): KilometerSystem[];
set kilometerSystem(v: KilometerSystem[]);
clone(): IKiloMarkerData;
copyFrom(data: IKiloMarkerData): void;
eq(other: IKiloMarkerData): boolean;
}
export class KilometerMarker extends Graphics { export class KilometerMarker extends Graphics {
constructor() { constructor() {
super(); super();
this.paint();
} }
paint() { paint() {
this.clear().lineStyle(1, '#fff').moveTo(0, -50).lineTo(0, 50); this.clear().lineStyle(1, '#fff').moveTo(0, -50).lineTo(0, 50);

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

@ -19,12 +19,20 @@ import { SignalCode } from './SignalCode';
import { Section, SectionPort } from '../section/Section'; import { Section, SectionPort } from '../section/Section';
import { Turnout, TurnoutPort } from '../turnout/Turnout'; import { Turnout, TurnoutPort } from '../turnout/Turnout';
export enum Direction {
LEFT = 0,
RIGHT = 1,
}
export interface KilometerSystem { export interface KilometerSystem {
get coordinateSystem(): string; get coordinateSystem(): string;
set coordinateSystem(v: string); set coordinateSystem(v: string);
get kilometer(): number; get kilometer(): number;
set kilometer(v: number); set kilometer(v: number);
get direction(): Direction;
set direction(v: Direction);
} }
export interface ISignalData extends GraphicData { export interface ISignalData extends GraphicData {
get code(): string; // 编号 get code(): string; // 编号
set code(v: string); set code(v: string);

View File

@ -6,6 +6,8 @@ import {
VectorText, VectorText,
calculateLineMidpoint, calculateLineMidpoint,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { SlopeKiloMarker } from '../slopeKiloMarker/SlopeKiloMarker';
import { KiloMarkerConsts } from '../kilometerMarker/KilometerMarker';
export interface ISlopeData extends GraphicData { export interface ISlopeData extends GraphicData {
get points(): IPointData[]; // 线坐标点 get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]); set points(points: IPointData[]);
@ -21,7 +23,6 @@ export interface ISlopeData extends GraphicData {
export const SlopeConsts = { export const SlopeConsts = {
lineColor: '0xffffff', lineColor: '0xffffff',
lineWidth: 2, lineWidth: 2,
height: 40,
}; };
export class Slope extends JlGraphic { export class Slope extends JlGraphic {
@ -62,8 +63,8 @@ export class Slope extends JlGraphic {
if (this.datas.slopeNumber !== 0) { if (this.datas.slopeNumber !== 0) {
distanceY = distanceY =
this.datas.slopeNumber > 0 this.datas.slopeNumber > 0
? -SlopeConsts.height / 2 ? -KiloMarkerConsts.size
: SlopeConsts.height / 2; : KiloMarkerConsts.size;
} }
this.datas.points.forEach((p, i) => { this.datas.points.forEach((p, i) => {
if (i !== 0) { if (i !== 0) {
@ -73,7 +74,9 @@ export class Slope extends JlGraphic {
} }
}); });
//坡度值 //坡度值
this.slopeNumber.text = parseFloat(this.datas.slopeNumber / 1000 + ''); this.slopeNumber.text = Math.abs(
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;
@ -90,7 +93,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.refDeviceId[1]; 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[0]?.kilometer -
slopeKiloMarkerL.datas.kilometerSystem[0]?.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;
@ -104,19 +115,11 @@ export class Slope extends JlGraphic {
this.slopeLong.position.set(centerPos.x, centerPos.y + 15); this.slopeLong.position.set(centerPos.x, centerPos.y + 15);
} }
} }
get linePoints(): IPointData[] {
return this.datas.points;
}
set linePoints(points: IPointData[]) {
const old = this.datas.clone();
old.points = points;
this.updateData(old);
}
loadRelations() { loadRelations() {
if (this.datas.refDeviceId.length) { if (this.datas.refDeviceId.length) {
this.datas.refDeviceId.forEach((id) => { this.datas.refDeviceId.forEach((id) => {
const section = this.queryStore.queryById(id); const slopeKiloMarker = this.queryStore.queryById(id);
this.relationManage.addRelation(this, section); this.relationManage.addRelation(this, slopeKiloMarker);
}); });
} }
} }

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,29 +61,46 @@ 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); let refSlopeKiloMarker;
const axleCountingsPos = axleCountings.map((g) => g.position.x); try {
//检验坡度有效性--是否有增加和删除 refSlopeKiloMarker = this.app.queryStore.queryById(
slopes.forEach((slope) => { g.datas.refDeviceId[0]
const pS = slope.datas.points[0].x; ) as SlopeKiloMarker;
const mapS = axleCountingsPos.findIndex((x) => x == pS); } catch (error) {
const pE = slope.datas.points[1].x; this.app.deleteGraphics(g);
const mapE = axleCountingsPos.findIndex((x) => x == pE); }
if (mapS !== -1 && mapE !== -1 && mapE - mapS == 1) {
map.set( return (
`${slope.datas.refDeviceId[0]}+${slope.datas.refDeviceId[1]}`, refSlopeKiloMarker?.datas.kilometerSystem[0].direction == dirSlop
1 );
); });
} else { const slopeKiloMarkers = this.app.queryStore
this.app.deleteGraphics(slope); .queryByType<SlopeKiloMarker>(SlopeKiloMarker.Type)
.filter((g) => g.datas.kilometerSystem[0]?.direction == dirSlop);
slopeKiloMarkers.sort((a, b) => a.position.x - b.position.x);
const slopeKiloMarkersPos = slopeKiloMarkers.map((g) => g.position.x);
//检验坡度有效性--是否有增加和删除
slopes.forEach((slope) => {
const pS = slope.datas.points[0].x;
const mapS = slopeKiloMarkersPos.findIndex((x) => x == pS);
const pE = slope.datas.points[1].x;
const mapE = slopeKiloMarkersPos.findIndex((x) => x == pE);
if (mapS !== -1 && mapE !== -1 && mapE - mapS == 1) {
map.set(
`${slope.datas.refDeviceId[0]}+${slope.datas.refDeviceId[1]}`,
1
);
} else {
this.app.deleteGraphics(slope);
}
});
for (let i = 0; i < slopeKiloMarkers.length - 1; i++) {
this.draw([slopeKiloMarkers[i], slopeKiloMarkers[i + 1]], map);
} }
});
for (let i = 0; i < axleCountings.length - 1; i++) {
this.draw([axleCountings[i], axleCountings[i + 1]], map);
} }
} }
} }
@ -119,6 +136,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,39 +1,43 @@
import { GraphicData, JlGraphic, JlGraphicTemplate } from 'src/jl-graphic'; import { JlGraphic, JlGraphicTemplate } from 'src/jl-graphic';
import { KilometerMarker } from '../kilometerMarker/KilometerMarker'; import {
import { KilometerSystem } from '../signal/Signal'; IKiloMarkerData,
import { graphicData } from 'src/protos/stationLayoutGraphics'; KiloMarkerConsts,
KilometerMarker,
export interface ISlopeKiloMarkerData extends GraphicData { } from '../kilometerMarker/KilometerMarker';
get code(): string; // 编号
set code(v: string);
get direction(): graphicData.Direction;
set direction(v: graphicData.Direction);
get kilometerSystem(): KilometerSystem;
set kilometerSystem(v: KilometerSystem);
clone(): ISlopeKiloMarkerData;
copyFrom(data: ISlopeKiloMarkerData): void;
eq(other: ISlopeKiloMarkerData): boolean;
}
export class SlopeKiloMarker extends JlGraphic { export class SlopeKiloMarker extends JlGraphic {
static Type = 'SlopeKiloMarker'; static Type = 'SlopeKiloMarker';
graphic: KilometerMarker; graphic: KilometerMarker;
size = KiloMarkerConsts.size;
constructor() { constructor() {
super(SlopeKiloMarker.Type); super(SlopeKiloMarker.Type);
this.graphic = new KilometerMarker(); this.graphic = new KilometerMarker();
this.addChild(this.graphic); this.addChild(this.graphic);
} }
get datas(): ISlopeKiloMarkerData { get datas(): IKiloMarkerData {
return this.getDatas<ISlopeKiloMarkerData>(); return this.getDatas<IKiloMarkerData>();
} }
doRepaint(): void { doRepaint(): void {
this.graphic.paint(); this.graphic.paint();
} }
getPoint(position: 'up' | 'down' | 'mid') {
const p = this.transform.position.clone();
if (position === 'up') {
p.y -= this.size;
return p;
} else if (position === 'down') {
p.y += this.size;
return p;
} else if (position === 'mid') {
return p;
}
}
} }
export class SlopeKiloMarkerTemplate extends JlGraphicTemplate<SlopeKiloMarker> { export class SlopeKiloMarkerTemplate extends JlGraphicTemplate<SlopeKiloMarker> {
constructor(dataTemplate: ISlopeKiloMarkerData) { constructor(dataTemplate: IKiloMarkerData) {
super(SlopeKiloMarker.Type, { super(SlopeKiloMarker.Type, {
dataTemplate, dataTemplate,
}); });

View File

@ -6,12 +6,9 @@ import {
JlGraphic, JlGraphic,
linePoint, linePoint,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { import { SlopeKiloMarker, SlopeKiloMarkerTemplate } from './SlopeKiloMarker';
ISlopeKiloMarkerData,
SlopeKiloMarker,
SlopeKiloMarkerTemplate,
} from './SlopeKiloMarker';
import { FederatedMouseEvent, IHitArea, Point } from 'pixi.js'; import { FederatedMouseEvent, IHitArea, Point } from 'pixi.js';
import { IKiloMarkerData } from '../kilometerMarker/KilometerMarker';
export class KilometerMarkerHitArea implements IHitArea { export class KilometerMarkerHitArea implements IHitArea {
kiloMarker: SlopeKiloMarker; kiloMarker: SlopeKiloMarker;
@ -31,25 +28,45 @@ export class KilometerMarkerHitArea implements IHitArea {
export class SlopeKiloMarkerDrawAssistant extends GraphicDrawAssistant< export class SlopeKiloMarkerDrawAssistant extends GraphicDrawAssistant<
SlopeKiloMarkerTemplate, SlopeKiloMarkerTemplate,
ISlopeKiloMarkerData IKiloMarkerData
> { > {
slopeKiloMarker: SlopeKiloMarker; slopeKiloMarker: SlopeKiloMarker;
constructor(app: JlDrawApp, template: SlopeKiloMarkerTemplate) { constructor(app: JlDrawApp, template: SlopeKiloMarkerTemplate) {
super(app, template, 'sym_o_golf_course', '坡度公里标'); super(app, template, 'sym_o_golf_course', '坡度公里标');
this.slopeKiloMarker = this.graphicTemplate.new(); this.slopeKiloMarker = this.graphicTemplate.new();
this.container.addChild(this.slopeKiloMarker);
SlopeKiloMarkerInteractionPlugin.init(app); SlopeKiloMarkerInteractionPlugin.init(app);
} }
onLeftDown(e: FederatedMouseEvent): void { onLeftDown(e: FederatedMouseEvent): void {
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(true); this.createAndStore(true);
} }
redraw(cp: Point): void { redraw(cp: Point): void {
this.slopeKiloMarker.position.copyFrom(cp); const list = this.app.queryStore.queryByType<SlopeKiloMarker>(
SlopeKiloMarker.Type
);
const ys = list.reduce<number[]>((prev, curr, i) => {
const currentY = curr.datas.transform.position.y;
if (!prev.includes(currentY)) {
return [currentY, ...prev];
} else {
return prev;
}
}, []);
if (list.length) {
const matchY = ys.find(
(y) => Math.abs(cp.y - y) <= this.slopeKiloMarker.size
);
if (matchY) {
this.container.position.set(cp.x, matchY);
return;
}
}
this.container.position.set(cp.x, cp.y);
} }
prepareData(data: ISlopeKiloMarkerData): boolean { prepareData(data: IKiloMarkerData): boolean {
data.transform = this.container.saveTransform(); data.transform = this.container.saveTransform();
return true; return true;
} }

View File

@ -136,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)) {
@ -144,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,

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;

View File

@ -49,6 +49,9 @@
<q-item clickable v-close-popup @click="oneClickGenerateLink"> <q-item clickable v-close-popup @click="oneClickGenerateLink">
<q-item-section>一键生成Link</q-item-section> <q-item-section>一键生成Link</q-item-section>
</q-item> </q-item>
<q-item clickable v-close-popup @click="oneClickCurvature">
<q-item-section>一键生成曲度</q-item-section>
</q-item>
</q-list> </q-list>
</q-menu> </q-menu>
</q-btn> </q-btn>
@ -256,6 +259,8 @@ import { useQuasar } from 'quasar';
import LayerControlDialog from 'src/components/draw-app/dialogs/LayerControlDialog.vue'; import LayerControlDialog from 'src/components/draw-app/dialogs/LayerControlDialog.vue';
import { drawLayerList } from 'src/drawApp/index'; import { drawLayerList } from 'src/drawApp/index';
import { useLineStore } from 'src/stores/line-store'; import { useLineStore } from 'src/stores/line-store';
import { Curvature } from 'src/graphics/curvature/Curvature';
import { CurvatureDraw } from 'src/graphics/curvature/CurvatureAssistant';
const $q = useQuasar(); const $q = useQuasar();
const route = useRoute(); const route = useRoute();
@ -446,6 +451,13 @@ function oneClickSlope() {
.getDrawAssistant(Slope.Type) as SlopeDraw; .getDrawAssistant(Slope.Type) as SlopeDraw;
slopeDraw.oneGenerates(); slopeDraw.oneGenerates();
} }
function oneClickCurvature() {
//
const curvatureDraw = drawStore
.getDrawApp()
.getDrawAssistant(Curvature.Type) as CurvatureDraw;
curvatureDraw.oneGenerates();
}
function oneClickLink() { function oneClickLink() {
drawStore.oneClickType = 'SectionLink'; drawStore.oneClickType = 'SectionLink';
const draw = drawStore const draw = drawStore