diff --git a/src/jmap/config/deviceRender.js b/src/jmap/config/deviceRender.js index b5f0384fc..2f526e8bf 100644 --- a/src/jmap/config/deviceRender.js +++ b/src/jmap/config/deviceRender.js @@ -44,4 +44,14 @@ deviceRender[deviceType.StationControl] = { progressive: 4, } +/** TrainWindow渲染配置*/ +deviceRender[deviceType.TrainWindow] = { + zlevel: 5, + progressive: 4, +}; +/** Train渲染配置*/ +deviceRender[deviceType.TRain] = { + zlevel: 6, + progressive: 4, +}; export default deviceRender; diff --git a/src/jmap/config/deviceStyle.js b/src/jmap/config/deviceStyle.js index 530bec33e..6b5199bf1 100644 --- a/src/jmap/config/deviceStyle.js +++ b/src/jmap/config/deviceStyle.js @@ -166,7 +166,167 @@ fuzhouSkin[deviceType.Signal] = { /** 信号灯蓝色*/ signalLampBlueColor: '#0000FF' }; +fuzhouSkin[deviceType.StationStand] = { + /** 站台空闲颜色*/ + stationStandSpareColor: '#74747C', + /** 列车边线颜色*/ + trainSidelineColor: '#C0C0C0', + + /** 站台和屏蔽门之间的距离*/ + stationStandDistance: 8, + + /** 站台无人折返*/ + stationStandNoHumanReentryColor: '#0F16DA', + + /** 站台首端字体大小*/ + stationStandHeadFontSize: 10, + + /** 中心扣车颜色*/ + stationStandCenterDetainTrainColor: '#FFFFFF', + + /** 默认字体 族类*/ + textFontFormat: '宋体', //consolas + + /** 默认背景 颜色*/ + backgroundColor: '#000000', + + /** 默认字体 大小*/ + textFontSize: 8.2, + + /** 停站时间字体颜色*/ + stationStandTimeTextColor: '#FFFFFF', + + /** 站台紧急关闭颜色*/ + stationStandEmergentCloseColor: '#F61107', + + /** 站台屏蔽门高度*/ + statonStandSafeHeight: 1.6, + + /** 屏蔽门默认颜色*/ + stationStandDoorDefaultColor: '#4DD43F', + + /** 站台列车停站颜色*/ + stationStandStopColor: '#FEFE00', + + /** 站台指定列车跳停颜色*/ + stationStandDesignatedJumpStopColor: 'lightSkyBlue', + + /** 站台跳停颜色*/ + stationStandJumpStopColor: '#9A99FF', + + /** 车站扣除文字颜色*/ + stationstandDetainTrainTextColor: '#E4EF50', + + /** 屏蔽门切除颜色*/ + stationStandSplitDoorColor: '#F61107', + + /** 站台自动换端*/ + stationStandAutoChangeEndsColor: '#0BF400', + + /** 默认border文字背景色*/ + borderContextBackgroundColor: '#00FFFF', + + /** 默认边线 颜色*/ + sidelineColor: '#FFFFFF', + +}; + +fuzhouSkin[deviceType.TrainWindow] = { + /** 车次窗高度*/ + trainWindowWidth: 40, + + /** 车次窗高度*/ + trainWindowHeight: 15, + + /** 车次窗颜色*/ + trainWindowColor: '#4DD43F', + + /** 透明填充 颜色*/ + transparentColor: 'rgba(0,0,0,0)', + +}; + +fuzhouSkin[deviceType.Train] = { + /** 列车长度*/ + trainWidth: 76, + + /** 列车高度*/ + trainHeight: 17, + + /** 列车字号*/ + trainTextFontSize: 15, + + // 列车文字间距 + trainTextSpaceBetween: 27, + + + /** 列车HDSA字号*/ + trainHSDATextFontSize: 8, + + /** 列车信号的半径*/ + trainConflictR: 3, + + /** 列车信号距离车的距离*/ + trainConflictDistance: 5, + + /** 列车车头比车身高出的长度,上下相比车体伸出去的边框*/ + trainMoreLength: 1, + + /** 列车和车头之间的间距*/ + trainHeadDistance: 2, + + /** 列车竖杠的宽度*/ + trainConntWidth: 4, + + /** 列车竖杠和方向之间的间隔*/ + trainPadding: 1, + + /** 列车方向的宽度*/ + trainArrowWidth: 6, + + /** 列车和区段之间的距离*/ + trainDistance: 18, + + /** 列车背景*/ + trainBackground: 'rgba(0,0,0,0)', + + /** 列车边线颜色*/ + trainSidelineColor: '#C0C0C0', + + /** 列车文字颜色*/ + trainTextColor: '#ffffff', + + /** 列车 灰色*/ + trainGrayColor: '#C0C0C0', + + /** 列车 白色*/ + trainWitheColor: '#FFFFFF', + + /** 列车 棕色*/ + trainBrownColor: '#9B4A09', + + /** 列车 黄色*/ + trainYellowColor: '#FFFF00', + + /** 列车 绿色*/ + trainGreenColor: '#00AF50', + + /** 列车 蓝色*/ + trainBlueColor: '#3265FF', + + /** 列车 红色*/ + trainRedColor: '#EF0C08', + + /** 列车 橘色*/ + trainOrangeColor: '#EA700D', + + /** 列车 紫色*/ + trainPurpleColor: 'purple', + + /** 列车 粉色*/ + trainPinkColor: 'pink', +}; /** 皮肤配置*/ const deviceSkin = { '03': fuzhouSkin, diff --git a/src/jmap/config/deviceType.js b/src/jmap/config/deviceType.js index be865826b..ebde09373 100644 --- a/src/jmap/config/deviceType.js +++ b/src/jmap/config/deviceType.js @@ -4,7 +4,9 @@ const deviceType = { Signal: 'Signal', Station: 'Station', StationControl: 'StationControl', - StationStand: 'StationStand' + StationStand: 'StationStand', + TrainWindow:'TrainWindow', + Train:'Train', }; export default deviceType; diff --git a/src/jmap/shape/StationStand.js b/src/jmap/shape/StationStand.js new file mode 100644 index 000000000..b8a6e74c3 --- /dev/null +++ b/src/jmap/shape/StationStand.js @@ -0,0 +1,528 @@ +/**/ +import Group from 'zrender/src/container/Group'; +import Text from 'zrender/src/graphic/Text'; +import Rect from 'zrender/src/graphic/shape/Rect'; +import Isogon from 'zrender/src/graphic/shape/Isogon'; +import Polygon from 'zrender/src/graphic/shape/Polygon'; +import { flashlight } from './libs/ShapePoints'; + +class StationStand extends Group { + constructor({ _code, _type, zlevel, model, state }, style){ + super(); + this._code = _code; + this._type = _type; + this.zlevel = zlevel; + this.model = model; + this.state = state; + this.style = style; + this.z = 40; + this.doors = new Group(); + this._create(model); + } + _create(model) { + // 方向值 + let drict = model.doorLocationType == '01' ? 1 : -1; + + this.stationStand = new Rect({ + zlevel: this.zlevel, + z: this.z, + shape: { + x: model.position.x - model.width / 2, + y: 0, + width: model.width, + height: model.height + }, + style: { + lineWidth: 0, + stroke: this.style.sidelineColor, + fill: this.style.stationStandSpareColor + } + }); + /** 站台折返策略*/ + let beyond = 4; + let height = 5; + let width = 10; + let offsetx = (model.width - width / 2); + let offsety = (model.height + height + this.style.stationStandDistance) / 2; + + this.reentry = new Polygon({ + zlevel: this.zlevel, + z: this.z, + shape: { + points: flashlight(model.position.x, model.position.y, drict, width, height, offsetx, offsety, beyond) + }, + style: { + lineWidth: 0, + fill: this.style.stationStandNoHumanReentryColor + } + }); + this.add(this.reentry); + + /** 站台扣车*/ + let distance = 0; + let textX = model.position.x + drict * (model.width / 2 + model.textFontSize + distance); + this.text = new Text({ + zlevel: this.zlevel, + z: this.z + 2, + position: [0, 0], + style: { + x: textX, + y: 0, + text: 'H', + textAlign: 'middle', + textVerticalAlign: 'top', + fontSize: this.style.stationStandHeadFontSize + 'px ' + this.style.textFontFormat, + textFill: this.style.stationStandCenterDetainTrainColor, + textStroke: this.style.backgroundColor, + } + }); + this.add(this.text); + + // 停站时间 + let textLevelT = [0, 0]; + if (model.doorLocationType == '02') { + textLevelT = [0, 5]; + } + let timeX = model.position.x - drict * (model.width / 2 + this.style.textFontSize + distance); + this.time = new Text({ + zlevel: this.zlevel, + z: this.z + 2, + position: textLevelT, + style: { + x: timeX, + y: 0, + text: model.parkingTime, + textFill: this.style.stationStandTimeTextColor, + textAlign: 'middle', + textFont: this.style.textFontSize + 'px ' + this.style.textFontFormat + } + }); + this.add(this.time); + + // 区间运行时间 + let textLevelP = [0, 2]; + if (model.doorLocationType == '01') { + textLevelP = [0, 15]; + } + let levelX = model.position.x - drict * (model.width / 2 + this.style.textFontSize + distance); + this.level = new Text({ + zlevel: this.zlevel, + z: this.z + 2, + position: textLevelP, + style: { + x: levelX, + y: 0, + text: model.intervalRunTime, + textFill: this.style.stationStandTimeTextColor, + textAlign: 'middle', + textFont: this.style.textFontSize + 'px ' + this.style.textFontFormat + } + }); + this.add(this.level); + + /** 站台紧急关闭*/ + this.emergent = new Isogon({ + zlevel: this.zlevel, + z: this.z, + shape: { + x: model.position.x, + y: 0, + r: this.style.stationStandDistance / 2, + n: 4, + }, + style: { + lineWidth: 0, + stroke: this.style.stationStandEmergentCloseColor, + fill: this.style.stationStandEmergentCloseColor + } + }); + this.doors.add(this.emergent); + + /** 屏蔽门*/ + let padding = 0.1; + //屏蔽门高度福州没有 北京有 + this.safeDoorL = new Rect({ + zlevel: this.zlevel, + z: this.z, + shape: { + x: model.position.x - model.width / 2 - padding, + y: model.position.y, + width: model.width / 4 + padding, + height: this.style.statonStandSafeHeight + }, + style: { + lineWidth: 0, + stroke: this.style.stationStandDoorDefaultColor, + fill: this.style.stationStandDoorDefaultColor + } + }); + + this.safeDoorC = new Rect({ + zlevel: this.zlevel, + z: this.z + 1, + shape: { + x: model.position.x - model.width / 4 - padding, + y: model.position.y, + width: model.width / 2 + padding * 2, + height: this.style.statonStandSafeHeight + }, + style: { + lineWidth: 0, + stroke: this.style.stationStandDoorDefaultColor, + fill: this.style.stationStandDoorDefaultColor + } + }); + + this.safeDoorR = new Rect({ + zlevel: this.zlevel, + z: this.z, + shape: { + x: model.position.x + model.width / 4, + y: model.position.y, + width: model.width / 4 + padding, + height: this.style.statonStandSafeHeight + }, + style: { + lineWidth: 0, + stroke: this.style.stationStandDoorDefaultColor, + fill: this.style.stationStandDoorDefaultColor + } + }); + + this.setHasSafeDoor(model.hasDoor); + this.setDrict(model.doorLocationType); + this.setVisible(model.visible); + this.setState(model); + this.mouseStatusRecover(); + } + setDrict(doorLocationType) { + let model = this.model; + let style = this.style; + if (doorLocationType === '01') { + let distance = model.position.y + style.stationStandDistance + style.statonStandSafeHeight; + this.text.setStyle('y', distance + model.height / 2 - style.stationStandHeadFontSize / 2); + this.time.setStyle('y', distance + model.height - style.textFontSize); + this.level.setStyle('y', distance - model.height + style.textFontSize / 1.2); + this.emergent.setShape('y', distance - style.stationStandDistance / 2); + this.stationStand.setShape('y', distance); + } else { + let distance = model.position.y - style.stationStandDistance; + this.text.setStyle('y', distance - model.height / 2 - style.stationStandHeadFontSize / 2); + this.time.setStyle('y', distance - model.height + style.textFontSize); + this.level.setStyle('y', distance - model.height - style.textFontSize / 2); + this.emergent.setShape('y', distance + style.stationStandDistance / 2); + this.stationStand.setShape('y', distance - model.height); + } + this.add(this.doors); + this.add(this.stationStand); + + + let rect = this.stationStand.getBoundingRect(); + rect.union(this.doors.getBoundingRect()); + this.standBorder = new Rect({ + zlevel: this.model.zlevel, + silent: true, + z: this.z - 1, + shape: rect, + style: { + lineDash: [3, 3], + stroke: style.borderColor, + fill: style.transparentColor + } + }); + this.add(this.standBorder); + } + setHasSafeDoor(hasDoor) { + if (hasDoor) { + this.doors.add(this.safeDoorL); + this.doors.add(this.safeDoorC); + this.doors.add(this.safeDoorR); + } else { + this.doors.remove(this.safeDoorL); + this.doors.remove(this.safeDoorC); + this.doors.remove(this.safeDoorR); + } + } + + setVisible(visible) { + if (visible) { + this.eachChild((it) => { + it.show(); + }); + } else { + this.eachChild((it) => { + it.hide(); + }); + } + } + + //恢复初始状态 + recover() { + this.time.hide(); + this.level.hide(); + this.text.hide(); + this.emergent.hide(); + this.reentry.hide(); + if (this.model.visible) { this.safeDoorC.show(); } + this.safeDoorL.setStyle('fill', this.style.stationStandDoorDefaultColor); + this.safeDoorC.setStyle('fill', this.style.stationStandDoorDefaultColor); + this.safeDoorR.setStyle('fill', this.style.stationStandDoorDefaultColor); + } + + //空闲 + spare() { + this.stationStand.setStyle('fill', this.style.stationStandSpareColor); + } + + //列车停站 + stop() { + this.stationStand.setStyle('fill', this.style.stationStandStopColor); + } + + //指定列车跳站 + designatedJumpStop() { + this.stationStand.setStyle('fill', this.style.stationStandDesignatedJumpStopColor); + } + + //站台紧急关闭 + emergentClose() { + this.stationStand.setStyle('fill', this.style.stationStandSpareColor); + this.emergent.show(); + } + + //未设置跳停 + unJumpStop() { + } + + //站台跳停 + jumpStop() { + this.stationStand.setStyle('fill', this.style.stationStandJumpStopColor); + } + + //未设置扣车 + unDetainTrain() { + this.text.hide(); + } + + //车站扣车 + standDetainTrain() { + this.text.show(); + this.text.setStyle('textFill', this.style.stationStandDetainTrainTextColor); + } + + //中心扣车 + centerDetainTrain() { + this.text.show(); + this.text.setStyle('textFill', this.style.stationStandCenterDetainTrainColor); + } + + //中心+车站扣车 + standAndCenterDetainTrain() { + this.text.show(); + } + + //人工设置停战时间 + setManuallyArmisticeTime(val) { + this.time.show(); + this.time.attr({ + style: { + text: val + }, + }); + } + + //人工设置运行等级 + setManuallyOperationLevel(val) { + this.level.show(); + this.level.attr({ + style: { + text: val + }, + }); + } + + //开门 + openDoor() { + this.safeDoorC.hide(); + } + + //关门 + closeDoor() { + if (this.model.model.visible) { this.safeDoorC.show(); } + } + + //屏蔽门正常 + doorNormal() { + this.safeDoorL.setStyle('fill', this.style.stationStandDoorDefaultColor); + this.safeDoorC.setStyle('fill', this.style.stationStandDoorDefaultColor); + this.safeDoorR.setStyle('fill', this.style.stationStandDoorDefaultColor); + } + + //屏蔽门故障 + doorFault() { + this.safeDoorL.setStyle('fill', this.style.stationStandSplitDoorColor); + this.safeDoorC.setStyle('fill', this.style.stationStandSplitDoorColor); + this.safeDoorR.setStyle('fill', this.style.stationStandSplitDoorColor); + } + + //屏蔽门切除 + doorSplit() { + this.safeDoorL.setStyle('fill', this.style.stationStandSplitDoorColor); + this.safeDoorC.setStyle('fill', this.style.stationStandSplitDoorColor); + this.safeDoorR.setStyle('fill', this.style.stationStandSplitDoorColor); + } + + //无折返(默认) + noReentry() { + this.reentry.hide(); + } + + //无人折返 + noHumanReentry() { + this.reentry.show(); + this.reentry.setStyle('fill', this.style.stationStandNoHumanReentryColor); + } + //自动换端 + autoChangeEnds() { + this.reentry.show(); + this.reentry.setStyle('fill', this.style.stationStandAutoChangeEndsColor); + } + + setState(model) { + this.recover(); + switch (model.status) { + case '01': { //空闲 + this.spare(); + } break; + case '02': { //列车停站 + this.stop(); + } break; + case '03': { //站台紧急关闭 + this.emergentClose(); + } break; + } + + if (Number(model.parkingTime) >= 0) { + this.setManuallyArmisticeTime(model.parkingTime); + } + + if (Number(model.intervalRunTime) > 0) { + this.setManuallyOperationLevel(model.intervalRunTime); // 运行等级显示 + } + + /** 设置跳停*/ + if (model.status == '01') { + switch (model.jumpStopStatus) { + case '01': { //未设置跳停 + this.unJumpStop(); + } break; + case '02': { //指定站台跳停 + this.designatedJumpStop(); + } break; + case '03': { //站台全部跳停 + this.jumpStop(); + } + } + } + + /** 设置扣车*/ + switch (model.holdStatus) { + case '01': { //未设置扣车 + this.unDetainTrain(); + } break; + case '02': { //车站扣车 + this.standDetainTrain(); + } break; + case '03': { //中心扣车 + this.centerDetainTrain(); + } break; + case '04': { //中心+车站扣车 + this.standAndCenterDetainTrain(); + } break; + } + + /** 设置屏蔽门开关*/ + switch (model.screenDoorOpenStatus) { + case '01': { + this.closeDoor(); //关门 + } break; + case '02': { + this.openDoor(); //开门 + } break; + } + + /** 设置屏蔽门状态*/ + switch (model.screenDoorStatus) { + case '01': { + this.doorNormal(); //正常 + } break; + case '02': { + this.doorFault(); //故障 + } break; + case '03': { + this.doorSplit(); //切除 + } + } + + /** 设置折返策略*/ + switch (model.reentryStrategy) { + case '04': //默认 + case '01': { + this.noReentry(); //无折返策略 + } break; + case '02': { + this.noHumanReentry(); //无人折返 + } break; + case '03': { + this.autoChangeEnds(); //自动换端 + } break; + } + } + + getShapeTipPoint() { + let rect = this.stationStand.getBoundingRect(); + if (rect) { + return { + x: rect.x + rect.width / 2, + y: rect.y + }; + } + return null; + } + + mouseStatusVisible() { + this.standBorder.show(); + //福州无 + this.stationStand.setStyle({ fill: this.style.borderContextBackgroundColor }) + } + + mouseStatusRecover() { + this.standBorder.hide(); + this.stationStand.setStyle({ fill: this.style.stationStandSpareColor }) + this.setState(this.model); + } + + mouseclick(e) { + if ([3].includes(e.which)) { + this.selected = !this.selected; + if (this.selected) { + this.mouseStatusRecover(); + this.mouseStatusVisible(); + } + } + } + + mouseenter(e) { + if (!this.selected) { + this.mouseStatusRecover(); + this.mouseStatusVisible(); + } + } + + mouseleave(e) { + if (!this.selected) { + this.mouseStatusRecover(); + } + } +} +export default StationStand; diff --git a/src/jmap/shape/Train.js b/src/jmap/shape/Train.js new file mode 100644 index 000000000..2f3d85b93 --- /dev/null +++ b/src/jmap/shape/Train.js @@ -0,0 +1,620 @@ +import Group from 'zrender/src/container/Group'; +import Text from 'zrender/src/graphic/Text'; +import Rect from 'zrender/src/graphic/shape/Rect'; +import Polygon from 'zrender/src/graphic/shape/Polygon'; +import BoundingRect from 'zrender/src/core/BoundingRect'; +//import ModelType from '@/jlmap/model/ModelType'; +import store from '@/store'; + +/** 车身*/ +class TrainBody extends Group { + constructor(model) { + super(); + this.model = model; + this._create(model); + } + + _create(model) { + let textFont = model.style.trainTextFontSize + 'px ' + model.style.textFontFormat; + let TextFontHSDA = model.style.trainHSDATextFontSize + 'px ' + model.style.textFontFormat; + + let destinationText = ''; + switch (model.model.destinationStatus) { + case '01': destinationText = '准点'; break; + case '02': destinationText = '早点'; break; + case '03': destinationText = '严重早点'; break; + case '04': destinationText = '晚点'; break; + case '05': destinationText = '严重晚点'; break; + default: destinationText = '未知'; break; + } + + // 文字描述 + this.arrowText = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: model.point.x + 50, + y: model.point.y + 25, + text: `列车类型: 计划车\n表\0\0\0\0号: ${model.model.serviceNumber}\n车\0次\0号: ${model.model.tripNumber}\n目的地号: ${model.model.targetCode ? model.model.targetCode : ''}\n车\0组\0号: ${model.model.groupNumber}\n早\0晚\0点: ${destinationText}\n运行方向: ${model.model.directionType == '02' ? '上行' : '下行'}\n乘务组号: \n起点站名: \n终点站名: \n占用轨道: ${model.model.sectionModel ? model.model.sectionModel.trackName : ''}\n所在车站: \n车地通信: 正常\n运行等级: 4\n扣车状态: ${model.model.runControlStatus == '01' ? '正常' : model.model.runControlStatus == '03' ? '跳停' : '扣车'}\n停稳状态: ${model.model.runStatus == '02' ? '未停稳' : '停稳'}\n阻塞状态: 无\n列车速度: ${model.model.speed || 0} km/h\n列车移动授权距离: ${model.model.maLen || 0} m`, + textFill: '#000', + textAlign: 'letf', + textFont: 10 + 'px consolas', + textPadding: 3, + textBackgroundColor: this.model.style.tipBackgroundColor, + } + }); + + this.train = new Rect({ + zlevel: model.zlevel, + z: model.z, + shape: { + x: model.point.x, + y: model.point.y, + width: model.style.trainWidth, + height: model.style.trainHeight + }, + style: { + lineWidth: 0.1, + stroke: model.style.trainSidelineColor, + fill: model.style.trainBrown1Color + }, + cursor: 'pointer' + }); + + let lrPadding = 3; //两边间隔 + let upPadding = 4; //上边距离 + let beginX = (model.point.x + lrPadding); + let beginY = (model.point.y - model.style.trainHSDATextFontSize - upPadding); + let margin = (model.style.trainWidth - lrPadding * 2) / 4; + this.textH = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: parseInt(beginX + margin * 0), + y: parseInt(beginY), + text: 'H', + textFill: model.style.trainYellowColor, + textFont: TextFontHSDA, + textAlign: 'middle', + textVerticalAlign: 'top', + } + }); + + this.textS = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: parseInt(beginX + margin * 1), + y: parseInt(beginY), + text: 'S', + textFill: model.style.trainBlueColor, + textFont: TextFontHSDA, + textAlign: 'middle', + textVerticalAlign: 'top', + } + }); + + this.textD = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: parseInt(beginX + margin * 2), + y: parseInt(beginY), + text: 'D', + textFill: model.style.trainGreenColor, + textFont: TextFontHSDA, + textAlign: 'middle', + textVerticalAlign: 'top', + } + }); + + this.textA = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: parseInt(beginX + margin * 3), + y: parseInt(beginY), + text: 'A', + textFill: model.style.trainRedColor, + textFont: TextFontHSDA, + textAlign: 'middle', + textVerticalAlign: 'top', + } + }); + + lrPadding = 4; //两边间隔 + upPadding = 4; //上边距离 + let serviceNumber = model.model.serviceNumber || 'AA'; + let tripNumber = model.model.tripNumber || 'DDD'; + + serviceNumber = '00' + serviceNumber; + tripNumber = '000' + tripNumber; + this.textTrainServer = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: parseInt(model.point.x + lrPadding), + y: parseInt(model.point.y + upPadding), + text: serviceNumber.substring(serviceNumber.length - 2), + textFill: model.style.trainBrownColor, + textFont: textFont, + textAlign: 'left', + textVerticalAlign: 'top', + } + }); + + this.textTrainTarget = new Text({ + zlevel: model.zlevel, + z: model.z, + style: { + x: parseInt(model.point.x + model.style.trainWidth - lrPadding), + y: parseInt(model.point.y + upPadding), + text: tripNumber.substring(tripNumber.length - 3), + textFill: model.style.trainYellowColor, + textFont: textFont, + textAlign: 'right', + textVerticalAlign: 'top', + } + }); + this.add(this.train); + this.add(this.textH); + this.add(this.textS); + this.add(this.textD); + this.add(this.textA); + this.add(this.textTrainServer); + this.add(this.textTrainTarget); + } + setMouseOver() { + store.dispatch('map/setTrainDetails', this.model); + this.details = store.state.map.trainDetails; + this.add(this.arrowText); + this.arrowText.attr({ + style: { + x: this.details.point.x + 50, + y: this.details.point.y + 25, + } + }); + } + setMouseOut() { + this.remove(this.arrowText); + store.dispatch('map/setTrainDetails', null); + } + setTrainColor(color) { + this.train && this.train.setStyle('fill', color); + } + setTextTrainServerColor(color) { + this.textTrainServer.setStyle('textFill', color); + this.textTrainServer.setStyle('textStroke', color); + } + setTextTrainTargetColor(color) { + this.textTrainTarget.setStyle('textFill', color); + this.textTrainTarget.setStyle('textStroke', color); + } + setHShow(isShow) { + isShow ? this.textH.show() : this.textH.hide(); + } + setSShow(isShow) { + isShow ? this.textS.show() : this.textS.hide(); + } + setDShow(isShow) { + isShow ? this.textD.show() : this.textD.hide(); + } + setAShow(isShow) { + isShow ? this.textA.show() : this.textA.hide(); + } + +} + +/** 车头*/ +class TrainHead extends Group { + constructor(model) { + super(); + this.model = model; + this._create(model); + } + _create(model) { + let baseMargin = (model.drect === -1 ? 1 : 0); + this.line = new Rect({ + zlevel: model.zlevel, + z: model.z, + shape: { + x: model.point.x - baseMargin * (model.style.trainConntWidth), + y: model.point.y, + width: model.style.trainConntWidth, + height: model.style.trainHeight + 2 * model.style.trainMoreLength + }, + style: { + lineWidth: 0.1, + stroke: model.style.trainSidelineColor, + fill: model.style.trainBackground + } + }); + + let arrowMargin = model.style.trainPadding + model.style.trainConntWidth; + this.arrow = new Polygon({ + zlevel: model.zlevel, + z: model.z, + shape: { + points: [ + [model.point.x + model.drect * (arrowMargin), model.point.y + 1 - model.style.trainMoreLength], + [model.point.x + model.drect * (arrowMargin + model.style.trainArrowWidth), model.point.y + (model.style.trainHeight + model.style.trainMoreLength) / 2], + [model.point.x + model.drect * (arrowMargin), model.point.y - 1 + model.style.trainHeight + model.style.trainMoreLength] + ] + }, + style: { + lineWidth: 0.1, + stroke: model.style.trainSidelineColor, + fill: model.style.trainBackground + } + }); + + this.add(this.line); + this.add(this.arrow); + } + setColor(color) { + this.line && this.line.setStyle('fill', color); + this.arrow && this.arrow.setStyle('fill', color); + } + setLineShow(isShow) { + isShow ? this.line.show() : this.line.hide(); + } + setArrowShow(isShow) { + isShow ? this.arrow.show() : this.arrow.hide(); + } + setInvisible(invisible) { + this.eachChild((child) => { + child.attr('invisible', invisible); + }); + } +} +/** 列车 */ +export default class Train extends Group { + constructor({ _code, _type, zlevel, model, state }, style) { + super(); + this._code = _code; + this._type = _type; + this.zlevel = zlevel; + this.model = model; + this.state = state; + this.style = style; + this.z = 40; + this.section = null; + this.selected = false; + this.fontSize = model.nameFontSize || style.trainTextFontSize; + this.newScale = this.fontSize / style.trainTextFontSize; + this._create(model, style); + this.on('mousedown', this.mouseclick); + this.on('mouseout', this.mouseleave); + this.on('mouseover', this.mouseenter); + } + + _computed(model, style) { + if (model.trainWindowModel) { + this.point = { + x: model.trainWindowModel.point.x, + y: model.trainWindowModel.point.y + }; + + switch (model.directionType) { + case '01': { //未知方向 + this.point.x = this.point.x + model.trainWindowModel.width / 2 + Math.abs((style.trainWidth - model.trainWindowModel.width) / 2); + } break; + case '02': { //从左向右 + this.point.x = this.point.x + model.trainWindowModel.width / 2 - style.trainConntWidth * this.newScale - style.trainWidth; + } break; + case '03': { //从右向左 + this.point.x = this.point.x - model.trainWindowModel.width / 2 + style.trainConntWidth * this.newScale; + } break; + } + } else { + this.point = model.position; + this.traingle = null; + } + } + + _create(model, style) { + //计算画图坐标点 + this._computed(model, style); + + //画图 + if (this.point) { + // body + this.trainB = new TrainBody({ + model: model, + style: style, + zlevel: this.zlevel, + z: this.z, + point: this.point + }); + // left 头 + this.trainL = new TrainHead({ + style: style, + zlevel: this.zlevel, + z: this.z, + point: { + x: this.point.x - style.trainHeadDistance, + y: this.point.y + }, + drect: -1 + }); + // right 头 + this.trainR = new TrainHead({ + style: style, + zlevel: this.zlevel, + z: this.z, + point: { + x: this.point.x + style.trainWidth + style.trainHeadDistance, + y: this.point.y + }, + drect: 1 + }); + this.add(this.trainB); + this.add(this.trainL); + this.add(this.trainR); + + let rect = Object.assign({}, this.getBoundingRect()); + rect.x -= style.trainWidth / 2; + rect.y -= 5; + rect.width += style.trainWidth; + rect.height += 10; + + this.trainBorder = new Rect({ + zlevel: model.zlevel, + z: this.z, + silent: true, + shape: rect, + style: { + lineDash: [3, 3], + stroke: style.borderColor, + fill: style.transparentColor + } + }) + + this.add(this.trainBorder); + this.setStatus(model); + this.mouseStatusRecover(); + } + } + getShapeTipPoint() { + return { + x: (this.train.shape.x), + y: (this.train.shape.y) + }; + } + //恢复颜色状态 + recover() { + this.trainB.setHShow(false); + this.trainB.setSShow(false); + this.trainB.setDShow(false); + this.trainB.setAShow(false); + this.trainL.setLineShow(false); + this.trainR.setLineShow(false); + this.trainL.setArrowShow(false); + this.trainR.setArrowShow(false); + } + //设置服务号状态类型 + setServerNoType(type) { + switch (type) { + case '01': { //显示服务号 计划车 + this.trainB.setTextTrainServerColor(this.style.trainWitheColor); + } break; + case '02': { //显示车组号: 头码车与人工车 + this.trainB.setTextTrainServerColor(this.style.trainYellowColor); + } break; + default: { + this.trainB.setTextTrainServerColor(this.style.backgroundColor); + } + } + } + //设置目的地状态 + setDestinationStatus(status) { + switch (status) { + case '01': { //准点 + this.trainB.setTextTrainTargetColor(this.style.trainWitheColor); + } break; + case '02': { //早点 + this.trainB.setTextTrainTargetColor(this.style.trainGreenColor); + } break; + case '03': { //晚点 + this.trainB.setTextTrainTargetColor(this.style.trainBrownColor); + } break; + case '04': { //头码车 + this.trainB.setTextTrainTargetColor(this.style.trainYellowColor); + } break; + default: { + this.trainB.setTextTrainTargetColor(this.style.backgroundColor); + } + } + } + //设置运行方向状态类型 + setDirectionType(type) { + switch (type) { + case '01': { //未知方向 + this.trainL.setLineShow(true); + this.trainR.setLineShow(true); + } break; + case '02': { //从左往右 上行 + this.trainR.setLineShow(true); + this.trainR.setArrowShow(true); + } break; + case '03': { //从右往左 下行 + this.trainL.setLineShow(true); + this.trainL.setArrowShow(true); + } break; + } + } + // 设置列车停止方向类型 + setDirectionStopType(type) { + switch (type) { + case '01': { //未知方向 + } break; + case '02': { //从左往右 上行 + this.trainR.setLineShow(true); + } break; + case '03': { //从右往左 下行 + this.trainL.setLineShow(true); + } break; + } + } + //设置运行状态 + setRunStatus(status) { + switch (status) { + case '01': { //停止 + this.setDirectionStopType(this.model.directionType); //设置运行方向状态类型 + } break; + case '02': { //运行 + this.setDirectionType(this.model.directionType); //设置运行方向状态类型 + } break; + } + + } + //设置运行模式 + setRunMode(status) { + switch (status) { + case '01': { //未知 + this.trainL.setColor(this.style.trainWitheColor); + this.trainR.setColor(this.style.trainWitheColor); + } break; + case '02': { //ATO自动驾驶模式 AM + this.trainL.setColor(this.style.trainGreenColor); + this.trainR.setColor(this.style.trainGreenColor); + } break; + case '03': { //ATP监控下的人工驾驶模式 CM + this.trainL.setColor(this.style.trainYellowColor); + this.trainR.setColor(this.style.trainYellowColor); + } break; + case '04': { //限制人工驾驶模式 RM + this.trainL.setColor(this.style.trainBrownColor); + this.trainR.setColor(this.style.trainBrownColor); + } break; + case '05': { //非限制人工驾驶模式 RM + this.trainL.setColor(this.style.trainBrownColor); + this.trainR.setColor(this.style.trainBrownColor); + } break; + } + } + + //设置运行控制状态类型 + setRunControlStatus(status) { + switch (status) { + case '01': { //正常 + this.trainB.setHShow(false); + this.trainB.setSShow(false); + } break; + case '02': { //扣车 + this.trainB.setHShow(true); + } break; + case '03': { //跳停 + this.trainB.setSShow(true); + } break; + } + } + //设置车门状态类型 + setDoorStatus(status) { + switch (status) { + case '01': { //关门 + this.trainB.setDShow(false); + } break; + case '02': { //开门 + this.trainB.setDShow(true); + } break; + } + } + //设置通信状态类型 + setCommunicationStatus() { + switch (status) { + case '01': { //正常 + this.trainB.setTrainColor(this.style.trainBrown1Color); + } break; + case '02': { //故障 + this.trainB.setTrainColor(this.style.trainGrayColor); + } break; + } + } + //设置报警状态 + setAlarmStatus(status) { + switch (status) { + case '01': { //不报警 + this.trainB.setAShow(false); + } break; + case '02': { //报警 + this.trainB.setAShow(true); + } break; + } + } + + //设置状态 + setStatus(model) { + if (model) { + this.recover(); + this.setServerNoType(model.serverNoType); //设置服务号状态类型 + this.setDestinationStatus(model.destinationStatus); //设置目的地状态 + this.setRunStatus(model.runStatus); //设置运行状态 + this.setRunMode(model.runMode); //设置运行模式 + this.setRunControlStatus(model.runControlStatus); //设置运行控制状态类型 + this.setDoorStatus(model.doorStatus); //设置车门状态类型 + this.setCommunicationStatus(model.communicationStatus); //设置通信状态类型 + this.setAlarmStatus(model.alarmStatus); //设置报警状态 + } + } + + //获取列车包围框 + getBoundingRect() { + let list = [this.trainB, this.trainL, this.trainR]; + let rect = null; + + list.forEach(elem => { + if (elem) { + let tempRect = elem.getBoundingRect(); + if (tempRect.x && tempRect.y && tempRect.width && tempRect.height) { + if (rect) { + rect.union(tempRect); + } else { + rect = tempRect; + } + } + } + }); + + return rect || new BoundingRect(0, 0, 0, 0); + } + + setSectionBorderShow(show) { + /* let section = store.getters['map/getViewInstanceByDevice']({ _type: ModelType.Section, _code: this.model.sectionCode }); + show && section && section.mouseStatusVisible(); + show || section && section.mouseStatusRecover();*/ + } + + mouseStatusVisible() { + this.trainBorder.show(); + this.setSectionBorderShow(true); + this.trainB.setMouseOver(); + } + + mouseStatusRecover() { + this.trainBorder.hide(); + this.setSectionBorderShow(false); + this.trainB.setMouseOut(); + } + + mouseclick(e) { + if ([3].includes(e.which)) { + this.selected = !this.selected; + if (this.selected) { + this.mouseStatusVisible(); + } + } + } + + mouseenter(e) { + if (!this.selected) { + this.mouseStatusVisible(); + } + } + + mouseleave(e) { + if (!this.selected) { + this.mouseStatusRecover(); + } + } +} diff --git a/src/jmap/shape/TrainWindow.js b/src/jmap/shape/TrainWindow.js new file mode 100644 index 000000000..6956a2791 --- /dev/null +++ b/src/jmap/shape/TrainWindow.js @@ -0,0 +1,129 @@ +/*车次窗*/ +import Polygon from 'zrender/src/graphic/shape/Polygon'; +import Group from 'zrender/src/container/Group'; +//import ModelType from '@/jlmap/model/ModelType'; +import store from '@/store'; + +class TrainWindow extends Group { + constructor({ _code, _type, zlevel, model, state }, style){ + super(); + this._code = _code; + this._type = _type; + this.zlevel = zlevel; + this.model = model; + this.state = state; + this.style = style; + this.z = 1; + this.selected = false; + this._create(model); + this.on('mousedown', this.mouseclick); + this.on('mouseout', this.mouseleave); + this.on('mouseover', this.mouseenter); + } + _create(model) { + let prdType = '02'//store.state.map.prdType; + if (prdType !== '01') { + this.createTrainWindow(); + this.setTrainWindowEventShow(model.trainWindowShow); + this.setState(model); + this.mouseStatusRecover(); + } + } + + /** 创建车次窗*/ + createTrainWindow() { + let model = this.model; + let point = model.point||model.position; + this.trainRect = new Polygon({ + _subType: 'TrainWindow', + zlevel: this.zlevel - 1, + z: this.z, + shape: { + smooth: 0.01, + points: [ + [point.x - model.width / 2, point.y], + [point.x + model.width / 2, point.y], + [point.x + model.width / 2, point.y + model.height], + [point.x - model.width / 2, point.y + model.height], + ] + }, + style: { + lineDash: [3, 3], + lineWidth: 1, + stroke: this.style.trainWindowColor, + fill: this.style.transparentColor + } + }); + this.add(this.trainRect); + } + + setTrainWindowEventShow(show) { + let lineWidth = show ? 1 : 0; + this.trainRect && this.trainRect.setStyle('lineWidth', lineWidth); + } + + isPop(e) { + for (var i = 0; i < this.childCount(); i++) { + var rect = this.childAt(i).getBoundingRect(); + if (rect.contain(e.offsetX, e.offsetY) && this.childAt(i).pop) { + return true; + } + } + } + + //设置状态 + setState(model) { + } + + getShapeTipPoint() { + if (this.stationControl) { + var distance = 2; + var rect = this.stationControl.getBoundingRect(); + return { + x: rect.x + rect.width / 2, + y: rect.y - distance, + }; + } + return null; + } + + setSectionEventShow(e, show) { + /*let section = store.getters['map/getViewInstanceByDevice']({ _type: ModelType.Section, _code: this.model.sectionCode }); + + show && section && section.mouseStatusVisible(e); + show || section && section.mouseStatusRecover(e);*/ + } + + mouseStatusRecover(e) { + this.setTrainWindowEventShow(false); + this.setSectionEventShow(e, false); + } + + mouseStatusVisible(e) { + this.setTrainWindowEventShow(true); + this.setSectionEventShow(e, true); + } + + mouseclick(e) { + if ([3].includes(e.which)) { + this.selected = !this.selected; + if (this.selected) { + this.mouseStatusVisible(e); + } + } + } + + mouseenter(e) { + if (!this.selected) { + this.mouseStatusVisible(e); + } + } + + mouseleave(e) { + if (!this.selected) { + this.mouseStatusRecover(e); + } + } +} + +export default TrainWindow; diff --git a/src/jmap/shape/factory.js b/src/jmap/shape/factory.js index e452a7551..880295485 100644 --- a/src/jmap/shape/factory.js +++ b/src/jmap/shape/factory.js @@ -2,12 +2,18 @@ import deviceType from '../config/deviceType'; import Link from './Link'; import Section from './section'; import Signal from './Signal'; +import StationStand from "./StationStand"; +import TrainWindow from "./TrainWindow"; +import Train from "./Train"; /** 图库*/ const mapShape = {}; mapShape[deviceType.Link] = Link; mapShape[deviceType.Section] = Section; mapShape[deviceType.Signal] = Signal; +mapShape[deviceType.StationStand] = StationStand; +mapShape[deviceType.TrainWindow] = TrainWindow; +mapShape[deviceType.Train] = Train; function shapefactory(type, device, style) { const shape = mapShape[type]; diff --git a/src/jmap/utils/parser.js b/src/jmap/utils/parser.js index cca121379..ce6833084 100644 --- a/src/jmap/utils/parser.js +++ b/src/jmap/utils/parser.js @@ -19,12 +19,22 @@ export function parser(data, defaultStateDict) { // zrUtil.each(data.linkList || [], (elem) => { // mapDevice[elem.code] = deviceFactory(deviceType.Link, defaultStateDict, elem); // }); + console.log('data',data); zrUtil.each(data.sectionList || [], (elem) => { mapDevice[elem.code] = deviceFactory(deviceType.Section, defaultStateDict, elem); }); zrUtil.each(data.signalList || [], (elem) => { mapDevice[elem.code] = deviceFactory(deviceType.Signal, defaultStateDict, elem); }); + zrUtil.each(data.stationStandList || [],(elem) => { + mapDevice[elem.code] = deviceFactory(deviceType.StationStand, defaultStateDict, elem); + }); + zrUtil.each(data.trainWindowList || [],(elem) => { + mapDevice[elem.code] = deviceFactory(deviceType.TrainWindow, defaultStateDict, elem); + }); + zrUtil.each(data.trainList || [],(elem) => { + mapDevice[elem.code] = deviceFactory(deviceType.TrainWindow, defaultStateDict, elem); + }); } return mapDevice;