import Group from 'zrender/src/container/Group'; import ETextName from '../element/ETextName'; // 名称文字 (共有) import ERelease from './ERelease'; // 线段 (共有) import ELimitLines from './ELimitLines'; // 区段限速 (私有) import ELines from './ELines'; // 创建多线条 曲线 (私有) import ESeparator from './ESeparator'; // 分隔符 (私有) import EMouse from './EMouse'; import { EAxle } from './EAxle'; // 创建计轴 (私有) import { EBackArrow, EBackArrowTriangle } from './EBackArrow'; // 折返进路箭头 import ELimitName from './ELimitName'; // 成都三号线 限速名称 import JTriangle from '../../utils/JTriangle'; import router from '@/router'; import {drawSectionStyle} from '../../config/defaultStyle'; /** 区段*/ export default class Section extends Group { constructor(model, style) { super(); this._code = model.code; this._type = model._type; this.zlevel = model.zlevel; this.z = 5 + parseInt(model.layer || 0); this.model = model; this.style = style; this.selected = false; // 绘图选中状态 this.selectedType = ''; // 绘图批量选中状态 this.create(); this.createMouseEvent(); this.setState(model); this.checkIsDrawMap(); } create() { const model = this.model; // 01:计轴区段;02逻辑区段;03道岔区段 04道岔计轴区段 this.createSectionText(); // 创建区段文字 if ((model.type === '01' || model.type === '03') && ( model.logicSectionNum.length <= 0 || model.logicSectionNum.length == 1 && model.logicSectionNum[0] == 0) || model.type === '02' ) { this.createSection(); // 创建区段 this.creatRelease(); // 创建延时释放 this.createSeparator(); // 创建分隔符 this.createTurnBack(); // 创建成都三号线 折返箭头 if (model.type === '01' && model.type === '03') { this.createAxles(); // 创建计轴 } } } createMouseEvent() { // 鼠标事件 if (this.style.Section.mouseOverStyle) { this.mouseEvent = new EMouse(this, this.model.relSwitchCode); this.add(this.mouseEvent); this.on('mouseout', (e) => { this.mouseEvent.mouseout(e); }); this.on('mouseover', (e) => { this.mouseEvent.mouseover(e); }); } } /** 创建区段*/ createSection() { const model = this.model; const style = this.style; // 创建区段 this.section = new ELines({ zlevel: this.zlevel, z: this.z, isSwitchSection: model.switchSection, isCurve: model.curve, points: model.points, style: style }); this.add(this.section); } // 折返箭头 createTurnBack() { const model = this.model; const style = this.style; if (model.reentryTrack && style.Section.shuttleBack) { const radius = 3; model.drict = 1; // 箭头朝向 (是折返轨加一个方向选择) 目前在区段右边 const width = style.Section.line.width * 2; const height = style.Section.line.width * 1; const turnBackDistance = style.Section.shuttleBack.distance + radius * 4; const points = model.points; let x = -model.drict * width * 1.2; let y = -turnBackDistance; if (model.drict < 0) { x += points[0].x; y += points[0].y; } else { x += points[points.length - 1].x; y += points[points.length - 1].y; } this.turnBack = new EBackArrow({ zlevel: this.zlevel, z: this.z + 10, shape: { drict: model.drict, width: width, height: height, points: { x: x, y: y } }, style: { lineWidth: style.Section.separator.width, stroke: style.Section.separator.color, fill: 'rgba(0, 0, 0, 0)' } }); this.turnBackriangle = new EBackArrowTriangle({ zlevel: this.zlevel, z: this.z + 10, shape: { drict: model.drict, width: width, height: height, points: { x: x, y: y } }, style: { lineWidth: style.Section.separator.width, stroke: style.Section.separator.color, fill: style.Section.separator.color } }); this.add(this.turnBack); this.add(this.turnBackriangle); this.turnBack.hide(); this.turnBackriangle.hide(); } } // 创建延时释放 (需要在创建) creatRelease() { const model = this.model; const style = this.style; const traingle = new JTriangle(model.points[0], model.points[model.points.length - 1]); this.release = new ERelease({ zlevel: this.zlevel, z: this.z, shape: { x1: model.points[0].x + traingle.getCos(traingle.absz / 3), y1: model.points[0].y + traingle.getSin(traingle.absz / 3), x2: model.points[0].x + traingle.getCos(traingle.absz / 3 * 2), y2: model.points[0].y + traingle.getSin(traingle.absz / 3 * 2) }, lineWidth: style.Section.line.width, stroke: style.Section.line.spareColor }); this.add(this.release); } // 创建限速线 (需要在创建) creatSpeedLimit() { const model = this.model; const style = this.style; const traingle = new JTriangle(model.points[0], model.points[model.points.length - 1]); let x = traingle.drictx * (style.Section.speedLimit.distance) * traingle.getSinRate(); let y = traingle.dricty * (style.Section.speedLimit.distance) * traingle.getCosRate(); if (x == Infinity) { x = 0; } if (y == Infinity) { y = 0; } if (!this.speedLimitLeft && !this.speedLimitRight) { this.speedLimitLeft = new ELimitLines({ zlevel: this.zlevel, z: this.z, position: [x, -y], style: style, switch: model.switch, isSwitchSection: model.switchSection, relSwitchCode: model.relSwitchCode, isCurve: model.curve, // 是否曲线 points: model.points }); this.speedLimitRight = new ELimitLines({ zlevel: this.zlevel, z: this.z, position: [-x, y], style: style, switch: model.switch, isSwitchSection: model.switchSection, relSwitchCode: model.relSwitchCode, isCurve: model.curve, // 是否曲线 points: model.points }); if (style.Section.speedLimit.nameShow) { // 开头 起点位置 this.speedLimitNameLeft = new ELimitName({ zlevel: this.zlevel, z: this.z + 10, drict: -1, x: model.points[0].x, y: model.points[0].y - 15, style: style }); // 终点位置 this.speedLimitNameRight = new ELimitName({ zlevel: this.zlevel, z: this.z + 10, drict: 1, x: model.points[model.points.length - 1].x, y: model.points[model.points.length - 1].y - 15, style: style }); this.add(this.speedLimitNameLeft); this.add(this.speedLimitNameRight); } } this.add(this.speedLimitLeft); this.add(this.speedLimitRight); } // 创建区段名称 createSectionText() { const model = this.model; const style = this.style; if (model && style) { // 计算区段坐标位置 const x = Math.min(model.points[0].x, model.points[model.points.length - 1].x) + Math.abs(model.points[model.points.length - 1].x - model.points[0].x) / 2; const y = Math.min(model.points[0].y, model.points[model.points.length - 1].y) + Math.abs(model.points[model.points.length - 1].y - model.points[0].y) / 2; const traingle = new JTriangle(model.points[0], model.points[model.points.length - 1]); const drict = model.trainPosType != '01' ? 1 : -1; /** 区段名称 (逻辑区段名称 或 物理区段名称 是否显示)*/ let tempx = x; let tempy = y; if (model.type == '01') { if (style.Section.text.show) { const opposite = style.Section.text.opposite ? -1 : 1; tempx += traingle.getSin(style.Section.text.distance); tempy += traingle.getCos(style.Section.text.distance) * (style.Section.text.position || opposite * drict); this.name = new ETextName({ zlevel: this.zlevel, z: this.z + 2, style: this.style, silent: false, x: tempx + model.namePosition.x, y: tempy + model.namePosition.y, fontWeight: style.Section.text.fontWeight, fontSize: style.Section.text.fontSize, fontFamily: style.fontFamily, text: model.name, textFill: style.Section.text.fontColor, textAlign: style.Section.text.textAlign, textPosition: style.Section.text.textPosition, textVerticalAlign: style.Section.text.textVerticalAlign }); this.add(this.name); } } else if (model.type == '02') { if (style.Section.logicText.show) { const opposite = style.Section.logicText.opposite ? -1 : 1; tempx += traingle.getSin(style.Section.logicText.distance); tempy += traingle.getCos(style.Section.logicText.distance) * (style.Section.logicText.position || opposite * drict); this.name = new ETextName({ zlevel: this.zlevel, z: this.z + 2, style: this.style, silent: false, x: tempx + model.namePosition.x, y: tempy + model.namePosition.y, fontWeight: style.Section.logicText.fontWeight, fontSize: style.Section.logicText.fontSize, fontFamily: style.fontFamily, text: model.name, textFill: style.Section.logicText.fontColor, textAlign: style.Section.logicText.textAlign, textPosition: style.Section.logicText.textPosition, textVerticalAlign: style.Section.logicText.textVerticalAlign }); this.add(this.name); } } else if (model.type == '03') { if (style.Section.switchText.show) { this.name = new ETextName({ zlevel: this.zlevel, z: this.z + 2, style: this.style, silent: false, x: tempx + model.namePosition.x, y: tempy + model.namePosition.y + style.Section.text.distance * drict, fontWeight: style.Section.text.fontWeight, fontSize: style.Section.text.fontSize, fontFamily: style.fontFamily, text: model.name, textFill: style.Section.text.fontColor, textAlign: style.Section.text.textAlign, textPosition: style.Section.text.textPosition, textVerticalAlign: style.Section.text.textVerticalAlign }); this.add(this.name); } } else if (model.type == '04') { if (router.currentRoute.path.startsWith('/design/usermap/map/draw') && router.currentRoute.path.endsWith('/draft') ) { this.name = new ETextName({ zlevel: this.zlevel, z: this.z + 2, style: this.style, silent: false, x: tempx + model.namePosition.x, y: tempy + model.namePosition.y + style.Section.text.distance * drict, fontWeight: style.Section.text.fontWeight, fontSize: style.Section.text.fontSize, fontFamily: style.fontFamily, text: model.name, textFill: style.Section.text.fontColor, textAlign: style.Section.text.textAlign, textPosition: style.Section.text.textPosition, textVerticalAlign: style.Section.text.textVerticalAlign }); this.add(this.name); } } /** 站台轨名称*/ if (model.standTrack && model.standTrackNameShow && style.Section.standText.show) { const opposite = style.Section.standText.opposite ? -1 : 1; const tempx = x + traingle.getSin(style.Section.standText.distance); const tempy = y + traingle.getCos(style.Section.standText.distance) * (style.Section.standText.position || opposite * drict); this.standTrackText = new ETextName({ zlevel: this.zlevel, z: this.z + 2, silent: false, x: tempx + model.standTrackNamePosition.x, y: tempy + model.standTrackNamePosition.y, fontWeight: style.Section.standText.fontWeight, fontSize: style.Section.standText.fontSize, fontFamily: style.fontFamily, text: model.standTrackName, textFill: style.Section.standText.fontColor, textAlign: style.Section.standText.textAlign, textPosition: style.Section.standText.textPosition, textVerticalAlign: style.Section.standText.textVerticalAlign }); this.add(this.standTrackText); } /** 折返轨名称*/ if (model.reentryTrack && model.reentryTrackNameShow && style.Section.reentryText.show) { const opposite = style.Section.reentryText.opposite ? -1 : 1; const tempx = x + traingle.getSin(style.Section.reentryText.distance); const tempy = y + traingle.getCos(style.Section.reentryText.distance) * (style.Section.reentryText.position || opposite * drict); this.reentryTrackText = new ETextName({ zlevel: this.zlevel, z: this.z + 2, silent: false, x: tempx + model.reentryTrackNamePosition.x, y: tempy + model.reentryTrackNamePosition.y, fontWeight: style.Section.reentryText.fontWeight, fontSize: style.Section.reentryText.fontSize, fontFamily: style.fontFamily, text: model.reentryTrackName, textFill: style.Section.reentryText.fontColor, textAlign: style.Section.reentryText.textAlign, textPosition: style.Section.reentryText.textPosition, textVerticalAlign: style.Section.reentryText.textVerticalAlign }); this.add(this.reentryTrackText); } /** 转换轨名称*/ if (model.transferTrack && model.transferTrackNameShow && style.Section.transferText.show) { const opposite = style.Section.transferText.opposite ? -1 : 1; const tempx = x + traingle.getSin(style.Section.transferText.distance); const tempy = y + traingle.getCos(style.Section.transferText.distance) * (style.Section.transferText.position || opposite * drict); this.transferTrackText = new ETextName({ zlevel: this.zlevel, z: this.z + 2, silent: false, x: tempx + model.transferTrackNamePosition.x, y: tempy + model.transferTrackNamePosition.y, fontWeight: style.Section.transferText.fontWeight, fontSize: style.Section.transferText.fontSize, fontFamily: style.fontFamily, text: model.transferTrackName, textFill: style.Section.transferText.fontColor, textAlign: style.Section.transferText.textAlign, textPosition: style.Section.transferText.textPosition, textVerticalAlign: style.Section.transferText.textVerticalAlign }); this.add(this.transferTrackText); } /** 目的码名称*/ if (model.destinationCode && style.Section.destinationText.show) { const opposite = style.Section.destinationText.opposite ? -1 : 1; const tempx = x + traingle.getSin(style.Section.destinationText.distance); const tempy = y + traingle.getCos(style.Section.destinationText.distance) * (style.Section.destinationText.position || opposite * drict); this.destinationText = new ETextName({ zlevel: this.zlevel, z: this.z + 2, silent: false, x: tempx + model.destinationCodePoint.x, y: tempy + model.destinationCodePoint.y, fontWeight: style.Section.destinationText.fontWeight, fontSize: style.Section.destinationText.fontSize, fontFamily: style.fontFamily, text: model.destinationCode, textFill: style.Section.destinationText.fontColor, textAlign: style.Section.destinationText.textAlign, textPosition: style.Section.destinationText.textPosition, textVerticalAlign: style.Section.destinationText.textVerticalAlign }); this.add(this.destinationText); } } } // 创建计轴 (需要在创建) createAxles() { const model = this.model; const style = this.style; /** 创建四个计轴*/ let traingle = null; if (model && style && model.axleShow && model.points && model.points.length > 1) { traingle = new JTriangle(model.points[0], model.points[1]); this.lUpAxle = new EAxle({ zlevel: this.zlevel, z: this.z + 5, // 层级大于道岔z 否则会压住显示完整 shape: { point: { x: model.points[0].x, y: model.points[0].y }, drictx: 1, dricty: -1, traingle: traingle, style: style }, style: { GBaseLineWidth: 1, stroke: style.Section.axle.color } }); this.lBottomAxle = new EAxle({ zlevel: this.zlevel, z: this.z + 5, // 层级大于道岔z 否则会压住显示完整 shape: { point: { x: model.points[0].x, y: model.points[0].y }, drictx: 1, dricty: 1, traingle: traingle, style: style }, style: { GBaseLineWidth: 1, stroke: style.Section.axle.color } }); traingle = new JTriangle(model.points[model.points.length - 2], model.points[model.points.length - 1]); this.rUpAxle = new EAxle({ zlevel: this.zlevel, z: this.z + 5, // 层级大于道岔z 否则会压住显示完整 shape: { point: { x: model.points[model.points.length - 1].x, y: model.points[model.points.length - 1].y }, drictx: -1, dricty: -1, traingle: traingle, style: style }, style: { GBaseLineWidth: 1, stroke: style.Section.axle.color } }); this.rBottomAxle = new EAxle({ zlevel: this.zlevel, z: this.z + 5, // 层级大于道岔z 否则会压住显示完整 shape: { point: { x: model.points[model.points.length - 1].x, y: model.points[model.points.length - 1].y }, drictx: -1, dricty: 1, traingle: traingle, style: style }, style: { GBaseLineWidth: 1, stroke: style.Section.axle.color } }); this.add(this.lUpAxle); this.add(this.rUpAxle); this.add(this.lBottomAxle); this.add(this.rBottomAxle); } } // 创建分隔符 (内层需要在创建) createSeparator() { const model = this.model; const style = this.style; let traingle = null; if (model && style && model.points && model.points.length > 1) { /** 创建左侧分隔符*/ traingle = new JTriangle(model.points[0], model.points[1]); this.lPartition = new ESeparator({ style: style, zlevel: this.zlevel, traingle: traingle, point: { x: model.points[0].x, y: model.points[0].y }, sepType: model.sepTypeLeft, drict: -1 // 方向 }); /** 创建右侧分隔符*/ traingle = new JTriangle(model.points[model.points.length - 2], model.points[model.points.length - 1]); this.rPartition = new ESeparator({ style: style, zlevel: this.zlevel, traingle: traingle, point: { x: model.points[model.points.length - 1].x, y: model.points[model.points.length - 1].y }, sepType: model.sepTypeRight, drict: 1 // 方向 }); /** 添加视图*/ this.add(this.lPartition); this.add(this.rPartition); } } /** 设置区段集合显隐*/ setInvisible() { const invisible = this.model.type === '02' && this.model.logicSectionShow; this.eachChild((child) => { child.attr('invisible', invisible); }); } /** 设置区段恢复默认状态*/ recover() { if (this.section) { this.section.stopAnimation(true); this.section.setStyle({ fill: this.style.backgroundColor, stroke: this.style.Section.line.spareColor, lineWidth: this.style.Section.line.width }); if (this.release) { this.release.hide(); } if (this.speedLimitLeft && this.speedLimitRight) { this.remove(this.speedLimitLeft); this.remove(this.speedLimitRight); } } } /** 未定义状态 00*/ undefine() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.undefinedColor, lineWidth: this.style.Section.line.width }); } } /** 空闲状态 01*/ spare() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.spareColor, lineWidth: this.style.Section.line.width }); } } /** 通信车占用状态 02*/ communicationOccupied() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.communicationOccupiedColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** 非通信车占用状态 03*/ unCommunicationOccupied() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.unCommunicationOccupiedColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** 进路锁闭 04*/ routeLock() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.routeLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** 封锁 06*/ block() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.blockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** 故障锁定状态 05*/ faultLock() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.faultLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** atc切除状态 07*/ atcExcision() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.atcExcisionColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** ats切除状态 08*/ atsExcision() { if (this.section) { this.atcExcision(); this.section.animateStyle(true, [ { time: 1000, styles: { stroke: this.style.backgroundColor } }, { time: 2000, styles: { stroke: this.style.Section.line.atsExcisionColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth } } ]); } } /** 保护区段锁闭 09*/ protectiveLock() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.line.protectiveLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** 延时释放 10*/ async timeRelease() { this.section.setStyle({ stroke: this.style.Section.line.routeLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); if (this.release) { this.release.show(); this.release.setStyle({ stroke: this.style.Section.line.routeLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); this.release.animateStyle(true, [ { time: 1000, styles: { stroke: this.style.Section.line.routeLockColor } }, { time: 2000, styles: { stroke: this.style.Section.line.timeReleaseColor } } ]); } } /** 保护区段延时解锁 11*/ protectiveTimeRelease() { this.section.setStyle({ stroke: this.style.Section.line.protectiveLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); this.release && this.release.show(); this.release && this.release.setStyle({ stroke: this.style.Section.line.protectiveLockColor, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); this.release && this.release.animateStyle(true, [ { time: 1000, styles: { stroke: this.style.Section.line.protectiveLockColor } }, { time: 2000, styles: { stroke: this.style.Section.line.protectiveTimeReleaseColor } } ]); } /** 区段切除*/ sectionCutOff() { const lineWidth = this.style.Section.line.width + (this.model.status != '01' ? this.style.Section.line.beyondWidth : 0); if (this.section) { this.section.animateStyle(true, [ { time: 0, styles: { lineWidth: lineWidth } }, { time: 1000, styles: { stroke: this.style.backgroundColor } }, { time: 2000, styles: { lineWidth: lineWidth } } ]); } } /** 设置限速*/ setSpeedUpperLimit() { if (this.section) { this.creatSpeedLimit(); } } /** 计轴预复位 12*/ axleReset() { if (this.release) { this.release.show(); this.release && this.release.setStyle({ stroke: this.style.Section.axle.resetColor, fill: 'green' }); } } /** 计轴失效 13*/ alxeFailure() { if (this.section) { this.section.setStyle({ stroke: this.style.Section.axle.Failure, lineWidth: this.style.Section.line.width + this.style.Section.line.beyondWidth }); } } /** 设置状态*/ setState(model) { this.recover(); if (model.status == '01' || model.status == '00' || model.status == undefined) { if (this.name && this.style.Section.active.routeColor) { this.name.setStyle({textFill: this.style.Section.text.fontColor}); } } else { if (this.name && this.style.Section.active.routeColor) { this.name.setStyle({textFill: 'green'}); } } switch (model.status) { case '00': /** 未定义*/ this.undefine(); break; case '01': /** 空闲*/ this.spare(); // 空闲状态下 名称白色 其他条件为绿色 break; case '02': /** 通信车占用*/ this.communicationOccupied(); break; case '03': /** 非通信车占用*/ this.unCommunicationOccupied(); break; case '04': /** 进路锁闭*/ this.routeLock(); break; case '05': /** 故障锁闭*/ this.faultLock(); break; case '06': /** 封锁*/ this.block(); break; case '07': /** ATC切除*/ this.atcExcision(); break; case '08': /** ATS切除*/ this.atsExcision(); break; case '09': /** 保护区段锁闭 */ this.protectiveLock(); break; case '10': /** 延时释放 */ this.timeRelease(); break; case '11': /** 保护区段延时解锁*/ this.protectiveTimeRelease(); break; case '12': /** 计轴预复位*/ this.axleReset(); break; case '13': /** ARB出清检测错误状态*/ break; case '14': /** 计轴失效*/ this.alxeFailure(); break; } /** 区段切除*/ if (model.cutOff) { this.sectionCutOff(); } /** 是否限速*/ if (model.speedUpperLimit >= 0) { this.setSpeedUpperLimit(); } } /** 计算提示位置*/ getShapeTipPoint() { let rect = this.getBoundingRect(); let distance = this.style.Section.line.width / 2; if (this.section) { rect = this.section.getBoundingRect(); if (this.model.type !== '02' && this.model.nameShow) { if (this.model.trainPosType == '01') { distance = distance + this.style.Section.text.distance + this.style.Section.text.fontSize; } } } return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2.7 - distance }; } getBoundingRect() { if (this.section) { return this.section.getBoundingRect(); } else { return super.getBoundingRect(); } } drawSelected(selected) { this.selected = selected; if (selected) { !this.selectedType && this.section && this.section.setStyle({stroke: 'rgba(0,255,255,0.6)'}); } else { !this.selectedType && this.section && this.section.setStyle({stroke: this.style.Section.line.spareColor }); } } drawBatchSelected(selected, type) { if (this.selectedType === type) { return; } if (selected && !this.selectedType) { this.section && this.section.setStyle({stroke: drawSectionStyle[type]}); } else { this.section && this.section.setStyle({stroke: this.style.Section.line.spareColor }); } this.selectedType = type; } checkIsDrawMap() { const path = window.location.href; if (path.includes('/map/draw')) { this.on('mouseout', () => { !this.selectedType && !this.selected && this.section && this.section.setStyle({stroke: this.style.Section.line.spareColor }); }); this.on('mouseover', () => { !this.selectedType && this.section && this.section.setStyle({stroke: 'rgba(0,255,255,0.6)'}); }); } } mouseout() { this.drawSelected(false); } mouseover() { this.section && this.section.setStyle({stroke: 'rgba(255,255,255,0.8)'}); } }