openatc-components 0.4.19 → 0.4.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openatc-components",
3
- "version": "0.4.19",
3
+ "version": "0.4.20",
4
4
  "description": "A Vue.js project",
5
5
  "author": "openatc developer",
6
6
  "private": false,
@@ -309,6 +309,7 @@ export default {
309
309
  crossStatusData: {
310
310
  handler: function (val, oldVal) {
311
311
  // 路口状态数据
312
+ this.compareIsChangedPhase(val, oldVal) // 比较相位状态决定是否更新相位图标(解决虚相位显示问题,虚相位图标不显示)
312
313
  this.statusData = JSON.parse(JSON.stringify(val))
313
314
  // 默认显示相位数据(包括黄闪、全红、关灯状态下,或者匝道,均不做比对跟随相位的处理)
314
315
  this.drawDefaultPhaseIcon()
@@ -389,10 +390,26 @@ export default {
389
390
  top: '1px'
390
391
  },
391
392
  isHasCountdown: false,
392
- contrloType: 'ring'
393
+ contrloType: 'ring',
394
+ isMphaseStatusDataReturnMap: new Map() // 每个跟随相位的母相位是否返回了相位状态数据
393
395
  }
394
396
  },
395
397
  methods: {
398
+ compareIsChangedPhase (newCrossStatus, oldCrossStatus) {
399
+ // 返回的相位状态改变后,按照返回的相位状态更新路口相位显示(下个周期生效)
400
+ let newPhaseIds = newCrossStatus.phase.map(item => item.id)
401
+ let oldPhaseIds = oldCrossStatus.phase.map(item => item.id)
402
+ if (!this.isArraysEqual(newPhaseIds, oldPhaseIds)) { // 通过比较相位id是否完全一致
403
+ this.getIntersectionInfo()
404
+ }
405
+ },
406
+ isArraysEqual (arr1, arr2) {
407
+ if (arr1.length !== arr2.length) return false
408
+ for (let i = 0; i < arr1.length; i++) {
409
+ if (arr1[i] !== arr2[i]) return false
410
+ }
411
+ return true
412
+ },
396
413
  handleTempCrossStatus (val) {
397
414
  // 模版路口图状态数据
398
415
  this.phaseStatusList = val.phase
@@ -423,6 +440,7 @@ export default {
423
440
  this.curStage = val.current_stage
424
441
  this.isHasPhase = true
425
442
  this.createPhaseStatusMap()
443
+ this.createOverlapPhaseStatusMap()
426
444
  // 正常情况下,获取车道相位、车道跟随相位、相位倒计时、行人相位、行人跟随相位 的状态
427
445
  this.getPhaseStatus()
428
446
  this.getOverlapPhaseStatus()
@@ -558,6 +576,7 @@ export default {
558
576
  },
559
577
  createPhaseStatusMap () {
560
578
  // 生成相位id和相位状态对应数据结构
579
+ this.phaseStatusMap = new Map()
561
580
  this.phaseStatusList.map(phase => {
562
581
  let phaseId = phase.id
563
582
  let phaseInfo = {
@@ -638,20 +657,38 @@ export default {
638
657
  // 如果有相同direction,处理后会改变原数组长度,导致第二次无法正确比较状态,因此需要中间变量存储
639
658
  this.comdirePhaseData = JSON.parse(JSON.stringify(this.CrossDiagramMgr.compareRepeatDirection(this.LanePhaseData, 'type', 'phase')))
640
659
  },
660
+ createOverlapPhaseStatusMap () {
661
+ // 处理跟随相位的母相位设置为忽略相位后的情况(如果跟随相位的母相位包含忽略相位,过滤掉跟随相位的状态数据,参照相位状态数据处理)
662
+ let isMphaseStatusDataReturn = false
663
+ let reset = false
664
+ this.overlapStatusList = this.overlapStatusList.filter(ele => {
665
+ let phaseids = this.phaseStatusList.map(item => item.id)
666
+ let mphase = ele.mphase
667
+ const phaseidsSet = new Set(phaseids)
668
+ isMphaseStatusDataReturn = mphase.every(value => phaseidsSet.has(value))
669
+ console.log(`跟随相位${ele.id}的母相位状态数据是否均返回?`, isMphaseStatusDataReturn)
670
+ if (isMphaseStatusDataReturn !== this.isMphaseStatusDataReturnMap.get(ele.id) && !reset) {
671
+ this.getIntersectionInfo()
672
+ reset = true
673
+ }
674
+ this.isMphaseStatusDataReturnMap = this.isMphaseStatusDataReturnMap.set(ele.id, isMphaseStatusDataReturn)
675
+ return isMphaseStatusDataReturn
676
+ })
677
+ // 得到跟随相位状态Map数据
678
+ this.overlapPhaseStatusMap = new Map()
679
+ this.overlapStatusList.map(phase => {
680
+ let phaseId = phase.id
681
+ let phaseInfo = {
682
+ type: phase.type,
683
+ phaseCountdown: phase.countdown,
684
+ pedtype: phase.pedtype
685
+ }
686
+ this.overlapPhaseStatusMap.set(phaseId, phaseInfo)
687
+ })
688
+ },
641
689
  getOverlapPhaseStatus () {
642
690
  // 得到车道跟随相位状态(颜色)
643
691
  this.comdireOverlapPhaseData = []
644
- if (this.overlapStatusList) {
645
- this.overlapStatusList.map(phase => {
646
- let phaseId = phase.id
647
- let phaseInfo = {
648
- type: phase.type,
649
- phaseCountdown: phase.countdown,
650
- pedtype: phase.pedtype
651
- }
652
- this.overlapPhaseStatusMap.set(phaseId, phaseInfo)
653
- })
654
- }
655
692
  let curLanePhaseData = []
656
693
  for (let i = 0; i < this.overlapLanePhaseData.length; i++) {
657
694
  let curPhaseStatus = this.overlapPhaseStatusMap.get(this.overlapLanePhaseData[i].phaseid)
@@ -704,13 +741,23 @@ export default {
704
741
  countdownObj.phaseCountdownColor = this.ColorMap.get(phaseInfo.type)
705
742
  let curphasedir = this.phaseDirMap.get(phaseInfo.id)
706
743
  if (curphasedir !== undefined) {
707
- countdownObj.showlist = curphasedir.direction.map(dir => {
744
+ if (curphasedir.direction && curphasedir.direction.length > 0) {
745
+ countdownObj.showlist = curphasedir.direction.map(dir => {
708
746
  return {
709
747
  id: dir,
710
748
  peddirection: this.getshowped(curphasedir.peddirection),
711
749
  color: '#fff'
712
750
  }
713
751
  })
752
+ } else {
753
+ countdownObj.showlist = [
754
+ {
755
+ id: '',
756
+ peddirection: this.getshowped(curphasedir.peddirection),
757
+ color: '#fff'
758
+ }
759
+ ]
760
+ }
714
761
  } else {
715
762
  countdownObj.showlist = []
716
763
  }
@@ -1084,11 +1131,11 @@ export default {
1084
1131
  let curPhaseStatus = this.overlapPhaseStatusMap.get(this.overlapsidewalkPhaseData[i].phaseid)
1085
1132
  if (!curPhaseStatus) {
1086
1133
  // 无状态的行人道,也显示出来
1087
- const data = {
1088
- ...this.overlapsidewalkPhaseData[i],
1089
- pedtype: undefined
1090
- }
1091
- curPedStatus.push(data)
1134
+ // const data = {
1135
+ // ...this.overlapsidewalkPhaseData[i],
1136
+ // pedtype: undefined
1137
+ // }
1138
+ // curPedStatus.push(data)
1092
1139
  continue
1093
1140
  }
1094
1141
  const data = {
@@ -13,6 +13,8 @@ let errorCodeMap = new Map([
13
13
  [112, '所有环不能同时配一个相位'],
14
14
  [113, '环索引应从1开始配置'],
15
15
  [114, '环索引应连续配置'],
16
+ [115, '绿脉冲时间应该大于绿闪时间'],
17
+ [116, '行人绿脉冲应该大于行人清空时间'],
16
18
  [201, '跟随相位数量超出限值'],
17
19
  [202, '跟随相位的母相位为空'],
18
20
  [203, '跟随相位配置未知母相位'],
@@ -101,6 +103,8 @@ let errorCodeMapEn = new Map([
101
103
  [112, 'All rings cannot be equipped with only one phase'],
102
104
  [113, 'The ring index should be configured from 1'],
103
105
  [114, 'The ring index shall be configured continuously'],
106
+ [115, 'The green pulse time should be greater than the green flash time'],
107
+ [116, 'The pedestrian green pulse should be greater than the pedestrian clearing time'],
104
108
  [201, 'The number of following phases exceeds the limit'],
105
109
  [202, 'The mother phase following the phase is null'],
106
110
  [203, 'Follow the phase configuration with an agnostic phase'],
@@ -162,12 +162,12 @@ export default {
162
162
  return {
163
163
  roadDirection: 'right',
164
164
  // reqUrl: 'http://192.168.13.103:10003/openatc',
165
- agentId: '32050101041121000001',
165
+ agentId: 'jmlfql',
166
166
  // agentId: '13013',
167
167
  // agentId: '12007_390',
168
168
  // agentId: '12014',
169
169
  reqUrl: 'http://192.168.13.103:10003/openatc',
170
- Token: 'eyJraWQiOiIxNzMwODU1NTQ1NzA3IiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTczMDg1OTE0NSwiaWF0IjoxNzMwODUxOTQ1fQ.CBl61S3eRifl4qEtTmgVjOZGo2hqNSGQKPxG1bN-utU',
170
+ Token: 'eyJraWQiOiIxNzM5NDEyMzIwNjMxIiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTczOTQxNTkyMCwiaWF0IjoxNzM5NDA4NzIwfQ.QkbGd0aKSZOI3K8zDk_UZOCGtdS6lZBlg97H6GnfxCk',
171
171
  // agentId: '30003-352',
172
172
  // reqUrl: 'https://kints-dev.devdolphin.com/openatc',
173
173
  // Token: 'eyJraWQiOiIxNjUwNTA5MDI2ODk2IiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJzdWIiOiJ4aWFvbWluZyIsImV4cCI6MTczNjkwOTAyNiwiaWF0IjoxNjUwNTA5MDI2fQ.-s4T-uMRmB2zf9yer87USKQXLY1a12Zq5lCOnqjNmfA',
@@ -1,2 +0,0 @@
1
- import OptimizeKanban from './OptimizeKanban.vue'
2
- export default OptimizeKanban
@@ -1,369 +0,0 @@
1
- /**
2
- * Copyright (c) 2020 kedacom
3
- * OpenATC is licensed under Mulan PSL v2.
4
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
5
- * You may obtain a copy of Mulan PSL v2 at:
6
- * http://license.coscl.org.cn/MulanPSL2
7
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
- * See the Mulan PSL v2 for more details.
11
- **/
12
- <template>
13
- <div class="kanbanOptimize">
14
- <div v-if="this.nowNumber === 1" class="optimizetype">
15
- <span>{{$t('openatccomponents.pattern.optimizetype')}}</span>
16
- <el-select v-model="value" clearable :placeholder="$t('openatccomponents.common.select')">
17
- <el-option
18
- v-for="item in typeOptions"
19
- :key="item.value"
20
- :label="$t('openatccomponents.overview.type' + item.value)"
21
- :value="item.value"
22
- >
23
- </el-option>
24
- </el-select>
25
- <span class="optimiNum">{{$t('openatccomponents.pattern.optimizecycle')}}</span>
26
- <el-input v-model="optimizecycle" clearable :placeholder="$t('openatccomponents.common.enter')"></el-input>
27
- <!-- <el-button type="primary" @click="onOptimizeClick()">{{$t('openatccomponents.pattern.inoptimize')}}</el-button> -->
28
- </div>
29
- <div class="common-board-column" :style="{marginTop:this.nowNumber === 1 ? 0 : '50px',marginLeft:this.nowNumber === 1 ? 0 : 0}">
30
- <div class="common-board-column-header">
31
- {{headerText}}
32
- </div>
33
- <div class="openatccomponents-board-table-header">
34
- <el-row :gutter="13">
35
- <el-col :span="4">{{this.$t('openatccomponents.overview.phase')}}
36
- </el-col>
37
- <el-col :span="10">{{this.$t('openatccomponents.overview.flow')}}
38
- </el-col>
39
- <el-col :span="10">{{this.$t('openatccomponents.overview.saturationflow')}}
40
- </el-col>
41
- </el-row>
42
- </div>
43
- <draggable
44
- class="common-board-column-content"
45
- :list="list"
46
- :options="options">
47
- <div class="common-board-item" v-for="element in list" :key="element.id">
48
- <el-row :gutter="13">
49
- <el-col :span="4">
50
- <el-tooltip class="item" effect="dark" placement="left">
51
- <div slot="content">{{element.name}}</div>
52
- <div class="common-phase-description">
53
- <xdrdirselector Width="70px" Height="70px" Widths="58px" Heights="58px" :Datas="styles" :Data="showStyle" :showlist="element.desc" :ISActiveMask="ISActiveMask" :MaskColor="MaskColor"></xdrdirselector>
54
- </div>
55
- </el-tooltip>
56
- </el-col>
57
- <el-col :span="10">
58
- <el-input-number :controls="false" class="col-content" size="small" :step="1" v-model.number="element.flowperhour" ref="type" :disabled="element.mode === 7"></el-input-number>
59
- </el-col>
60
- <el-col :span="10">
61
- <el-input-number :controls="false" class="col-content" size="small" :step="1" v-model.number="element.saturation" ref="types" :disabled="element.mode === 7"></el-input-number>
62
- </el-col>
63
- </el-row>
64
- </div>
65
- </draggable>
66
- </div>
67
- </div>
68
- </template>
69
- <script>
70
- import draggable from 'vuedraggable'
71
- import { getDuration } from '@/api/cross'
72
- import xdrdirselector from '@/components/XRDDirSelector'
73
-
74
- export default {
75
- name: 'patternOptimize',
76
- components: {
77
- draggable,
78
- xdrdirselector
79
- },
80
- data () {
81
- return {
82
- showStyle: {
83
- left: '7px',
84
- top: '0px'
85
- },
86
- styles: {
87
- left: '7px',
88
- top: '0px'
89
- },
90
- typeOptions: [{
91
- value: 'flow-split-opt'
92
- }, {
93
- value: 'cycle-opt'
94
- }],
95
- value: 'flow-split-opt',
96
- optimizecycle: 0
97
- }
98
- },
99
- props: {
100
- headerText: {
101
- type: String,
102
- default: 'Header'
103
- },
104
- id: {
105
- type: Number
106
- },
107
- rings: {
108
- type: Array
109
- },
110
- nowNumber: {
111
- type: Number
112
- },
113
- phaseList: {
114
- type: Array
115
- },
116
- options: {
117
- type: Object,
118
- default () {
119
- return {}
120
- }
121
- },
122
- list: {
123
- type: Array,
124
- default () {
125
- return []
126
- }
127
- },
128
- // index: {
129
- // type: Number
130
- // },
131
- ISActiveMask: {
132
- type: Boolean,
133
- default: true
134
- },
135
- // 当phase的描述为空时,显示的图形颜色。
136
- MaskColor: {
137
- type: String,
138
- default: '#000000'
139
- }
140
- },
141
- created () {
142
- // this.addMinSplit()
143
- this.addMin()
144
- },
145
- computed () {
146
-
147
- },
148
- watch: {
149
- list: {
150
- handler: function () {
151
- // let list = this.$refs.type
152
- // let flow = this.$refs.types
153
- // console.log(this.list, 'list')
154
- // let cycle = 0
155
- // let n = this.index
156
- // for (let i = 0; i < list.length; i++) {
157
- // cycle = cycle + Number(list[i].currentValue)
158
- // }
159
- // const globalParamModel = this.$store.getters.globalParamModel
160
- // // let MaxCycle = globalParamModel.getParamsByType('patternList')[n].cycle
161
- // let pattern = globalParamModel.getParamsByType('patternList')[n]
162
- // globalParamModel.getParamsByType('patternList')[n].cycle = this.getMaxCycle(pattern)
163
- // this.addMinSplit()
164
- // this.$emit('handleSplit', n)
165
- },
166
- deep: true
167
- }
168
- },
169
- methods: {
170
- onOptimizeClick () {
171
- let msg = this.$t('openatccomponents.pattern.algorithmEngineOptimization')
172
- const loading = this.$loading({
173
- lock: true,
174
- text: msg,
175
- spinner: 'el-icon-loading',
176
- background: 'rgba(0, 0, 0, 0.7)'
177
- })
178
- setTimeout(() => {
179
- loading.close()
180
- this.handeleOptimizeClick()
181
- }, 1000)
182
- },
183
- handeleOptimizeClick () {
184
- let newPha = []
185
- for (let i = 0; i < this.rings.length; i++) {
186
- newPha.push(...this.rings[i])
187
- }
188
- let phaseData = newPha.map(item => {
189
- return {
190
- id: item.id,
191
- flowperhour: item.flowperhour,
192
- saturation: item.saturation
193
- }
194
- })
195
- let patternList = this.$store.state.globalParam.tscParam.patternList
196
- let pattern = patternList.filter((item) => item.id === this.id)[0]
197
- let reqData = {
198
- 'type': this.value,
199
- 'optcycle': this.optimizecycle ? this.optimizecycle : 0,
200
- 'phaseList': this.phaseList,
201
- 'pattern': pattern,
202
- 'phases': phaseData
203
- }
204
- let isValidata = []
205
- for (let j = 0; j < newPha.length; j++) {
206
- let comNum = (newPha[j].length / 4) * 1700 * 0.8
207
- isValidata.push(newPha[j].flowperhour > comNum)
208
- }
209
- if (isValidata.includes(true)) {
210
- this.$confirm(this.$t('openatccomponents.overview.maxFlow'),
211
- this.$t('openatccomponents.common.alarm'), {
212
- confirmButtonText: this.$t('eopenatccomponentsdge.common.confirm'),
213
- cancelButtonText: this.$t('openatccomponents.common.cancel'),
214
- type: 'warning'
215
- }).then(() => {
216
- getDuration(reqData).then(data => {
217
- if (data.data.success) {
218
- this.$message({
219
- type: 'success',
220
- message: this.$t('openatccomponents.pattern.success')
221
- })
222
- for (let i = 0; i < this.rings.length; i++) {
223
- for (let j = 0; j < this.rings[i].length; j++) {
224
- for (let h = 0; h < data.data.data.phase.length; h++) {
225
- if (this.rings[i][j].id === data.data.data.phase[h].id) {
226
- this.rings[i][j].value = data.data.data.phase[h].duration
227
- // this.rings[i][j].cycle = data.data.data.phase[h].cycle
228
- }
229
- }
230
- }
231
- }
232
- }
233
- }).catch(error => {
234
- console.log(error)
235
- })
236
- }).catch(() => {
237
- })
238
- } else {
239
- getDuration(reqData).then(data => {
240
- if (data.data.success) {
241
- this.$message({
242
- type: 'success',
243
- message: this.$t('openatccomponents.pattern.success')
244
- })
245
- for (let i = 0; i < this.rings.length; i++) {
246
- for (let j = 0; j < this.rings[i].length; j++) {
247
- for (let h = 0; h < data.data.data.phase.length; h++) {
248
- if (this.rings[i][j].id === data.data.data.phase[h].id) {
249
- this.rings[i][j].value = data.data.data.phase[h].duration
250
- // this.rings[i][j].cycle = data.data.data.phase[h].cycle
251
- }
252
- }
253
- }
254
- }
255
- }
256
- }).catch(error => {
257
- console.log(error)
258
- })
259
- }
260
- },
261
- addMin () {
262
- for (let i of this.list) {
263
- if (!i.flowperhour || !i.saturation) {
264
- i.length = this.list.length
265
- i.flowperhour = 0
266
- i.saturation = 1700
267
- }
268
- }
269
- }
270
- // addMinSplit () {
271
- // const globalParamModel = this.$store.getters.globalParamModel
272
- // let phaseList = globalParamModel.getParamsByType('phaseList')
273
- // for (let ls of this.list) {
274
- // let phase = phaseList.filter((item) => {
275
- // return item.id === ls.id
276
- // })[0]
277
- // if (!phase.redyellow) {
278
- // phase.redyellow = 0
279
- // }
280
- // if (!phase.yellow) {
281
- // phase.yellow = 0
282
- // }
283
- // if (!phase.redclear) {
284
- // phase.redclear = 0
285
- // }
286
- // if (!phase.flashgreen) {
287
- // phase.flashgreen = 0
288
- // }
289
- // if (!phase.phasewalk) {
290
- // phase.phasewalk = 0
291
- // }
292
- // if (!phase.pedclear) {
293
- // phase.pedclear = 0
294
- // }
295
- // // let temp1 = phase.redyellow + phase.yellow + phase.redclear + phase.flashgreen // 绿信比的最小值要大于最小绿+黄灯+全红+绿闪
296
- // // let temp2 = phase.phasewalk + phase.pedclear
297
- // // if (temp1 > temp2) {
298
- // // ls.minSplit = temp1
299
- // // } else {
300
- // // ls.minSplit = temp2
301
- // // }
302
- // // if (ls.mode !== 7 && ls.value < ls.minSplit) {
303
- // // ls.value = ls.minSplit
304
- // // }
305
- // // let temp1 = phase.yellow + phase.redclear + phase.flashgreen // 绿信比的最小值要大于最小绿+黄灯+全红+绿闪
306
- // let temp1 = phase.yellow + phase.redclear + phase.mingreen
307
- // let temp2 = phase.yellow + phase.redclear + phase.phasewalk + phase.pedclear
308
- // ls.minSplit = temp1 > temp2 ? temp1 : temp2
309
- // if (ls.mode !== 7 && ls.value < ls.minSplit) {
310
- // ls.value = ls.minSplit
311
- // this.$message.error(this.$t('openatccomponents.pattern.splitCheckMsg'))
312
- // }
313
- // }
314
- // },
315
- // getMaxCycle (pattern) {
316
- // let rings = pattern.rings
317
- // let maxCycle = 0
318
- // for (let ring of rings) {
319
- // if (ring.length === 0) continue
320
- // let cycle = 0
321
- // for (let r of ring) {
322
- // if (r.mode === 7) { // 忽略相位不计周期
323
- // continue
324
- // }
325
- // cycle = cycle + r.value
326
- // }
327
- // if (cycle > maxCycle) {
328
- // maxCycle = cycle
329
- // }
330
- // }
331
- // return maxCycle
332
- // },
333
- // doChange (val) {
334
- // // if (val.mode === 7) {
335
- // // val.value = 0
336
- // // } else {
337
- // // val.value = 30
338
- // // }
339
- // }
340
- }
341
- }
342
- </script>
343
- <style lang="scss" scoped>
344
- .col-content {
345
- width: 100%;
346
- }
347
- .kanbanOptimize {
348
- .common-board-column {
349
- max-width: unset !important;
350
- }
351
- }
352
- .optimizetype{
353
- // float: left;
354
- font-size: 14PX;
355
- margin:0 0 10PX 0;
356
- .el-input {
357
- width: 80PX;
358
- }
359
- .el-select{
360
- width: 145PX;
361
- }
362
- .el-button {
363
- margin-left: 10PX;
364
- }
365
- .optimiNum {
366
- padding-left: 10PX;
367
- }
368
- }
369
- </style>
@@ -1 +0,0 @@
1
- {}