/* * 道岔 */ import Line from 'zrender/src/graphic/shape/Line'; import Group from 'zrender/src/container/Group'; import Text from 'zrender/src/graphic/Text'; import Rect from 'zrender/src/graphic/shape/Rect'; import JTriangle from '../../utils/JTriangle'; import ESwName from './ESwName.js'; import ESwLocal from './ESwLocal.js'; import ESwLnversion from './ESwLnversion'; import ELockRect from './ELockRect'; import ELockArc from './ELockArc'; import EMouse from './EMouse'; import EHighlight from '../element/EHighlight'; import ERhomboid from './ERhomboid'; import ETriangle from './ETriangle'; import store from '@/store/index_APP_TARGET'; import Vue from 'vue'; export default class Switch extends Group { constructor(model, style) { super(); this._code = model.code; this._type = model._type; this.model = model; this.style = style; this.zlevel = model.zlevel; this.z = 6; this.isShowShape = true; this.triangle = new JTriangle(model.intersection, model.skew); this.create(); this.createLockRect(); // 创建单锁矩形框显示 this.createMouseEvent(); this.setState(model); this.checkIsDrawMap(); } createMouseEvent() { // 鼠标事件 if (this.style.Switch.mouseOverStyle) { this.mouseEvent = new EMouse(this); this.add(this.mouseEvent); this.on('mouseout', (e) => { this.mouseEvent.mouseout(e); }); this.on('mouseover', (e) => { this.mouseEvent.mouseover(e); }); } } create() { const model = this.model; const style = this.style; const switchWidth = style.Section.line.width + style.Section.line.beyondWidth * 2; // 超出宽度多少 const swPadding = style.Switch.core.length; const directx = this.triangle.drictx; const directy = this.triangle.dricty; const direct = -this.triangle.drictx * this.triangle.dricty; const coverLength = switchWidth * 1.5; const switchWidth1 = style.Section.line.width / 2; const width1 = switchWidth1 * this.triangle.getSinRate(); const height1 = switchWidth1 * this.triangle.getCosRate(); const width2 = (height1 + switchWidth1) / this.triangle.getTanRate(); const width3 = (style.Section.line.width / this.triangle.getSinRate()) - width2 - width1; const detailWidth = 0.2; // 调整定位模糊宽度 const point1 = [model.intersection.x - directx * width3 - directx * detailWidth, model.intersection.y + directy * switchWidth1]; const point2 = [model.intersection.x + directx * (width2 + width1) + directx * detailWidth, point1[1]]; const point3 = [point2[0] + directx * this.triangle.getCotRate() * swPadding, point2[1] + directy * swPadding]; const point4 = [point3[0] + direct * this.triangle.getSin(switchWidth) - directx * 2 * detailWidth, point3[1] - direct * this.triangle.getCos(switchWidth)]; this.locShelter = new ESwLocal({ // 定位 覆盖形状 A zlevel: this.zlevel, z: this.z, style: style, shelterPoints: [point1, point2, point3, point4], cursor: 'pointer', triangle: this.triangle, onmouseover: () => { this.name.getArrowText().show(); }, onmouseout: () => { this.name.getArrowText().hide(); } }); const rpoint1 = [model.intersection.x + directx * width3, model.intersection.y - directy * switchWidth1]; const rpoint2 = [rpoint1[0] + directx * (width2 + width1) - directx * width3, model.intersection.y + directy * switchWidth1]; const rpoint3 = [rpoint2[0] + directx * 10, rpoint2[1]]; const rpoint4 = [rpoint2[0] + directx * 10, rpoint1[1]]; this.relocShelter = new ESwLnversion({ // 反位覆盖形状 B zlevel: this.zlevel, z: this.z, style: style, shelterPoints: [rpoint1, rpoint2, rpoint3, rpoint4], cursor: 'pointer', onmouseover: () => { this.name.getArrowText().show(); }, onmouseout: () => { this.name.getArrowText().hide(); } }); const spoint1 = [model.intersection.x + directx * width3, model.intersection.y - directy * switchWidth1]; const spoint2 = [spoint1[0] - directx * (width2 + width1) - directx * width3, spoint1[1]]; const spoint3 = [model.intersection.x - directx * width3, model.intersection.y + directy * switchWidth1]; const spoint4 = [spoint1[0] + directx * (width2 + width1) - directx * width3, spoint3[1]]; this.rhomboid = new ERhomboid({ // 岔芯 平行四边形 C zlevel: this.zlevel, z: this.z, style: style, sectionPoints: [spoint1, spoint2, spoint3, spoint4], cursor: 'pointer', onmouseover: () => { this.name.getArrowText().show(); }, onmouseout: () => { this.name.getArrowText().hide(); } }); if (this.style.Switch.text.lossRect) { const lossRect = this.locShelter.getLocal().getBoundingRect(); this.lossShow = new Rect({ zlevel: this.zlevel, z: this.z + 1, shape: { x: lossRect.x - 5, y: lossRect.y - 5, width: lossRect.width + 10, height: lossRect.height + 10 }, style: { fill: 'rgba(0, 0, 0, 1)', lineDash: [3, 3], stroke: '#F00', lineWidth: 2 } }); this.add(this.lossShow); this.lossShow.hide(); } const trapezoidWidth = this.style.Switch.jointImg.trapezoidLength; const Tspoint1 = [model.intersection.x + directx * width3 + directx * (width2 + width1) - directx * width3, model.intersection.y + directy * switchWidth1]; const Tspoint2 = [Tspoint1[0] - directx * trapezoidWidth, Tspoint1[1]]; const Tspoint3 = [Tspoint1[0] - directx * trapezoidWidth, model.intersection.y - directy * switchWidth1]; const Tspoint4 = [model.intersection.x + directx * width3, Tspoint3[1]]; const Tspoint5 = [Tspoint1[0], Tspoint1[1]]; this.sheltertriangle = new ETriangle({ // 岔芯 直角梯形 (用于'挤岔') D zlevel: this.zlevel, z: this.z, style: style, sectionPoints: [Tspoint1, Tspoint2, Tspoint3, Tspoint4, Tspoint5], cursor: 'pointer', onmouseover: () => { this.name.getArrowText().show(); }, onmouseout: () => { this.name.getArrowText().hide(); } }); this.releaseBackground = new Line({ zlevel: this.zlevel, z: this.z, shape: { x1: model.intersection.x - (coverLength * this.triangle.getCotRate()), y1: model.intersection.y, x2: model.intersection.x + (coverLength * this.triangle.getCotRate()), y2: model.intersection.y }, style: { lineWidth: style.Section.line.width + style.Section.line.beyondWidth + 1, stroke: style.backgroundColor } }); const arrowTextX = model.intersection.x + 10; const arrowTextY = model.intersection.y + 15; const nameTextX = model.namePosition.x + model.intersection.x + directx * (style.Section.line.width * 3 + style.Switch.text.offset.x) * this.triangle.getCotRate(); const nameTextY = model.namePosition.y + model.intersection.y + style.Switch.text.offset.y * (style.Switch.text.position || directy); this.name = new ESwName({ // 道岔名称 zlevel: this.zlevel, z: this.z, style: style, arrowTextX: arrowTextX, arrowTextY: arrowTextY, nameTextX: nameTextX, nameTextY: nameTextY, sectionName: model.sectionName, name: model.name, nameShow: style.Switch.text.show, triangle: this.triangle }); this.enabledName = new Text({ // 道岔使能 E 西安二号线独有 zlevel: this.zlevel, z: this.z + 6, _subType: 'enabled', // 标识 style: { x: nameTextX, y: nameTextY + directy * 20, fontSize: 12, text: 'E', textAlign: 'center', textVerticalAlign: 'middle', textFill: 'yellow' } }); this.add(this.locShelter); this.add(this.relocShelter); this.add(this.rhomboid); this.add(this.sheltertriangle); this.add(this.releaseBackground); this.add(this.name); this.add(this.enabledName); style.Switch.text.show && model.nameShow ? this.name.show() : this.name.hide(); } createLockRect() { let offsetX = this.model.locateType == '01' ? 3 : 0; let offsetY = 0; if (this.style.Switch.rectLock.offset) { const directx = this.triangle.drictx; const directy = this.triangle.dricty; offsetX = directx * this.style.Switch.rectLock.offset.x; offsetY = directy * this.style.Switch.rectLock.offset.y; } this.lockRect = new ELockRect({ // 锁定矩形 zlevel: this.zlevel, z: this.z + 6, x: this.model.intersection.x - this.style.Switch.rectLock.rectWidth / 2 + offsetX, y: this.model.intersection.y - this.style.Switch.rectLock.rectWidth / 2 + offsetY, width: this.style.Switch.rectLock.rectWidth, lineWidth: 1.8, stroke: this.style.Switch.rectLock.rectBorderColor, fill: this.style.transparentColor }); this.add(this.lockRect); this.lockRect.hide(); if (this.style.Switch.arcBlcok) { this.lockArc = new ELockArc({ // 锁定矩形 圆形 zlevel: this.zlevel, z: this.z + 6, x: this.model.intersection.x, y: this.model.intersection.y, lineWidth: 1.2, stroke: this.style.Switch.arcBlcok.arcBorderColor, fill: this.style.transparentColor }); this.add(this.lockArc); this.lockArc.hide(); } } setCiConfirm() { this.enabledName && this.enabledName.show(); this.enabledName.animateStyle(true) .when(0, { textFill: this.style.backgroundColor }) .when(1000, { textFill: 'yellow' }) .when(2000, { textFill: this.style.backgroundColor }) .start(); } /** 名称动画*/ nameTextAnimation() { this.name.getNameText().animateStyle(true) .when(0, { textFill: this.style.backgroundColor }) .when(1000, { textFill: this.style.Switch.text.lossColor }) .when(2000, { textFill: this.style.backgroundColor }) .start(); this.name.getTextRect().animateStyle(true) .when(0, { textFill: this.style.backgroundColor }) .when(1000, { textFill: this.style.Switch.text.borderColor }) .when(2000, { textFill: this.style.backgroundColor }) .start(); } /** 设置道岔文字颜色*/ setTextColor(color) { this.name.getNameText().setStyle({ textFill: color }); } /** 设置道岔背景颜色*/ setTextStyle(style) { this.name.getNameText().setStyle(style); } /** 设置道岔文字边框颜色 (道岔封锁) */ setHasTextBorder(width) { this.name.getTextRect().setStyle({ lineWidth: width }); } /** 恢复状态*/ recover() { this.lockRect.hide(); // 矩形包围框 this.lockArc.hide(); // 圆形单锁框 this.name.getNameText().stopAnimation(false); this.sheltertriangle.hide(); // 直角梯形覆盖图形 this.rhomboid.stopAnimation(false); // 平行四边形 this.releaseBackground.hide(); this.setHasTextBorder(0); this.locShelter.hide(); // 定位覆盖图形 this.relocShelter.hide(); // 反位覆盖图形 this.enabledName.hide(); // 使能隐藏 this.lossShow && this.lossShow.hide(); // 道岔失去矩形 this.lossShow && this.lossShow.stopAnimation(false); } /** 定位*/ setLocationAction() { if (this.style.Switch.core.splice) { this.locShelter.hide(); } else { this.locShelter.show(); } this.relocShelter.hide(); this.rhomboid.hide(); if (this.style.Switch.core.graphShow) { // 佛山线路显示 this.relocShelter.show(); this.rhomboid.show(); this.relocShelter.setColor('#00FF00'); this.rhomboid.setColor('#00FF00'); } this.setTextColor(this.style.Switch.text.locateColor); } /** 反位*/ setInversionAction() { this.setTextColor(this.style.Switch.text.inversionColor); if (this.style.Switch.core.splice) { this.relocShelter.hide(); } else { this.relocShelter.show(); // 反位 } this.locShelter.hide(); // 定位 this.rhomboid.show(); // 平行四边形 this.setSectionState(this.rhomboid.getSection(), 'fill', this.model); if (this.style.Switch.core.graphShow) { // 佛山线路显示 this.locShelter.show(); this.locShelter.setColor('#FFFF00'); this.rhomboid.setColor('#FFFF00'); } } /** 失去*/ setLossAction() { this.locShelter.show(); this.relocShelter.show(); this.rhomboid.hide(); this.sheltertriangle.show(); this.sheltertriangle.setColor(this.style.backgroundColor); this.setTextColor(this.style.Switch.text.lossColor); this.style.Switch.text.faultFlashing && this.nameTextAnimation(); this.lossShow && this.lossShow.show(); this.lossShow && this.lossShow.animateStyle(true) .when(0, { stroke: this.style.backgroundColor }) .when(500, { stroke: '#F00' }) .when(1000, { stroke: this.style.backgroundColor }) .start(); } setSwitchFault(split) { if (this.style.Switch.jointImg.faultStatus && split) { this.setForkAction(); // 道岔挤岔 宁波线失表状态 } else { if (this.model.switchFaultCode && split) { const switchFault = store.getters['map/getDeviceByCode'](this.model.switchFaultCode); switchFault.instance.setControlColor('#F00', true); } else if (this.model.switchFaultCode && !split) { const switchFault = store.getters['map/getDeviceByCode'](this.model.switchFaultCode); switchFault.instance.setControlColor(this.style.backgroundColor, false); } } } /** 挤叉*/ setForkAction() { this.rhomboid.hide(); // 平行四边形 if (this.style.Switch.jointImg.fork) { this.recover(); this.relocShelter.show(); this.relocShelter.animateStyle(item => { item.animateStyle(true) .when(0, { fill: this.style.backgroundColor }) .when(1000, { fill: 'red' }) .when(2000, { fill: this.style.backgroundColor }) .start(); }); this.sheltertriangle.show(); // 宁波线路挤叉特殊显示 this.sheltertriangle.animateStyle(item => { item.animateStyle(true) .when(0, { fill: this.style.backgroundColor }) .when(1000, { fill: 'red' }) .when(2000, { fill: this.style.backgroundColor }) .start(); }); this.locShelter.show(); this.locShelter.animateStyle(item => { item.animateStyle(true) .when(0, { fill: this.style.backgroundColor }) .when(1000, { fill: 'red' }) .when(2000, { fill: this.style.backgroundColor }) .start(); }); this.setTextColor('red'); } } /** 单锁*/ setMonolock() { if (this.style.Switch.rectLock.monolock) { // 判断单锁矩形是否显示 this.lockRect.show(); if (this.style.Switch.rectLock.rectBorderFillColor) { this.lockRect.setStyle({ stroke: this.style.Switch.rectLock.rectBorderColor, fill: this.style.Switch.rectLock.rectBorderFillColor }); } } if (this.style.Switch.text.monolock) { // 单锁显示名称包围框 this.setHasTextBorder(1); } if (this.style.Switch.arcBlcok.show) { // 圆形单锁是否显示 this.lockArc.show(); this.model.normalPosition && this.lockArc.setStyle({ stroke: this.style.Switch.arcBlcok.locationColor }); !this.model.normalPosition && this.lockArc.setStyle({ stroke: this.style.Switch.aBrclcok.inversionColor }); } this.model.normalPosition && this.setTextColor(this.style.Switch.text.monolockLocationColor); // 定位 设置道岔名称颜色 this.model.reversePosition && this.setTextColor(this.style.Switch.text.monolockInversionColor); // 反位 设置道岔名称颜色 } /** 封锁 */ block() { if (this.style.Switch.jointImg.block) { this.relocShelter.show(); this.relocShelter.animateStyle(item => { item.animateStyle(true) .when(0, { fill: this.style.backgroundColor }) .when(1000, { fill: this.style.Switch.jointImg.flashingColors }) .when(2000, { fill: this.style.backgroundColor }) .start(); }); this.sheltertriangle.show(); this.sheltertriangle.animateStyle(item => { item.animateStyle(true) .when(0, { fill: this.style.backgroundColor }) .when(1000, { fill: this.style.Switch.jointImg.flashingColors }) .when(2000, { fill: this.style.backgroundColor }) .start(); }); this.locShelter.show(); this.locShelter.animateStyle(item => { item.animateStyle(true) .when(0, { fill: this.style.backgroundColor }) .when(1000, { fill: this.style.Switch.jointImg.flashingColors }) .when(2000, { fill: this.style.backgroundColor }) .start(); }); } if (this.style.Switch.text.block) { this.setHasTextBorder(1); } if (this.style.Switch.jointImg.trapezoidBlock && this.model.reversePosition) { // 范围且封锁时显示 this.sheltertriangle.show(); this.sheltertriangle.getSection().setStyle('fill', '#000080'); } if (this.style.Switch.rectLock.block) { this.lockRect.show(); this.lockRect.setStyle({ stroke: this.style.Switch.rectLock.blockColor }); if (this.style.Switch.rectLock.blockFillColor) { this.lockRect.setStyle({ stroke: this.style.Switch.rectLock.blockColor, fill: this.style.Switch.rectLock.blockFillColor }); } } } blockMonolock() { if (this.style.Switch.rectLock.block && this.style.Switch.rectLock.monolock) { if (this.style.Switch.rectLock.blockFillColor && this.style.Switch.rectLock.rectBorderFillColor) { this.lockRect.show(); this.lockRect.setStyle({ stroke: 'rgba(0,0,0,0)', fill: this.style.Switch.rectLock.blockMonolockFillColor }); } } } /** 延时释放*/ timeRelease() { this.releaseBackground.show(); } /** 设置道岔切除*/ setSwitchCutOff() { if (this.model.normalPosition) { this.releaseBackground.hide(); /** 定位*/ } else if (this.model.reversePosition) { this.relocShelter && this.relocShelter.getSection().animateStyle(true) .when(1000, { fill: this.style.backgroundColor }) .start(); this.rhomboid && this.rhomboid.getSection().animateStyle(true) .when(1000, { fill: this.style.backgroundColor }) .start(); /** 反位*/ } } sectionCutOff(section) { const lineWidth = this.style.Section.line.width; if (section) { section.animateStyle(true, [ { time: 0, styles: { lineWidth: lineWidth } }, { time: 1000, styles: { stroke: this.style.backgroundColor } }, { time: 2000, styles: { lineWidth: lineWidth } } ]); } } setSectionState(section, style, state) { if (section && !section.animators.length) { const sectionA = store.getters['map/getDeviceByCode'](state.sectionACode); /** 空闲 */ section.setStyle(style, this.style.Section.line.spareColor); /** 道岔保护区段锁闭 */ if (sectionA.overlapLock) { section.setStyle(style, this.style.Section.line.protectiveLockColor); } /** 空闲锁闭或者叫进路锁闭 */ if (sectionA.routeLock) { section.setStyle(style, this.style.Section.line.routeLockColor); } /** 非CBTC车占用 */ if (sectionA.nctOccupied) { section.setStyle(style, this.style.Section.line.unCommunicationOccupiedColor); } /** CBTC车占用 */ if (sectionA.ctOccupied) { section.setStyle(style, this.style.Section.line.communicationOccupiedColor); } if (state.cutOff) { this.sectionCutOff(section); } } } setState(model) { if (!this.isShowShape) return; this.recover(); // console.log('定位>', model.normalPosition, '反位>', model.reversePosition); if (model.normalPosition) { this.setLocationAction(model); /** 定位*/ } else if (model.reversePosition) { this.setInversionAction(model); /** 反位*/ } else { this.setLossAction(); // 失去 } model.singleLock && this.setMonolock(); // 道岔单锁 model.blockade && this.block(); // 道岔封锁 model.singleLock && model.blockade && this.blockMonolock(); // 单锁&锁闭状态 // this.setForkAction(); // 道岔挤岔 model.isCiConfirm && this.setCiConfirm(); // 道岔使能显示 this.setSwitchFault(model.split); model.cutOff && this.setSwitchCutOff(); if (this.style.Switch.sectionAction.flag) { // 哈尔滨线路处理道岔相关区段颜色 const switchModel = Vue.prototype.$jlmap.mapDevice[model.code]; if (switchModel.normalPosition != 0) { // 定位情况 const sectionC = Vue.prototype.$jlmap.mapDevice[switchModel.sectionCCode]; sectionC && sectionC.instance && sectionC.instance.setState(sectionC); } else if (switchModel.normalPosition == 0) { // 反位情况 const sectionB = Vue.prototype.$jlmap.mapDevice[switchModel.sectionBCode]; sectionB && sectionB.instance && sectionB.instance.setState(sectionB); } } } getBoundingRect() { return this.name.getBoundingRect(); } getShapeTipPoint() { const text = this.name.getNameText(); if (text) { const rect = text.getBoundingRect(); return { x: rect.x + rect.width / 2, y: rect.y }; } return null; } drawSelected(selected) { this.highlight && this.highlight.drawSelected(selected); } checkIsDrawMap() { const path = window.location.href; if (path.includes('/map/draw')) { this.highlight = new EHighlight(this); this.add(this.highlight); this.on('mouseout', () => { this.highlight.mouseout(); }); this.on('mouseover', () => { this.highlight.mouseover(); }); } } setShowMode() {} setShowStation(stationCode) { if (!stationCode || this.model.stationCode === stationCode) { this.eachChild(item => { item.show(); }); if (this.name) { this.style.Switch.text.show && this.model.nameShow ? this.name.show() : this.name.hide(); } this.isShowShape = true; this.setState(this.model); } else { this.eachChild(item => { item.hide(); }); this.isShowShape = false; } } }