|
|
@@ -56,7 +56,7 @@ export default {
|
|
|
{ name: "特殊控制", start: [116.6820, 39.9215], end: [116.6825, 39.8815], color: "#A26218" }, // 临河里路
|
|
|
{ name: "离线", start: [116.6415, 39.9235], end: [116.6850, 39.9240], color: "#7A7A7A" }, // 北关大街-潞苑
|
|
|
{ name: "降级", start: [116.6365, 39.8850], end: [116.6800, 39.8860], color: "#D9C13B" }, // 万盛南街段
|
|
|
- { name: "故障", start: [116.6950, 39.9150], end: [116.6955, 39.8850], color: "#FF3938" } // 潞通大街
|
|
|
+ { name: "故障", start: [116.6950, 39.9150], end: [116.6955, 39.885], color: "#FF3938" } // 潞通大街
|
|
|
]
|
|
|
};
|
|
|
},
|
|
|
@@ -123,21 +123,6 @@ export default {
|
|
|
path = [config.start, config.end];
|
|
|
}
|
|
|
|
|
|
- // --- 【关键修改】:注释掉以下 Polyline 的定义 ---
|
|
|
- /*
|
|
|
- const polyline = new AMap.Polyline({
|
|
|
- path: path,
|
|
|
- strokeColor: config.color,
|
|
|
- strokeWeight: 8,
|
|
|
- strokeOpacity: 0.8,
|
|
|
- showDir: false,
|
|
|
- lineJoin: 'round',
|
|
|
- zIndex: 15,
|
|
|
- map: null
|
|
|
- });
|
|
|
- */
|
|
|
-
|
|
|
- // 1. 只有“干线协调”和“勤务路线”才创建路线对象
|
|
|
let polyline = null;
|
|
|
const needRouteLine = ["干线协调", "勤务路线"].includes(config.name);
|
|
|
|
|
|
@@ -154,24 +139,29 @@ export default {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- // 2. 在路径上分布点 (保持原样)
|
|
|
- // 修改 points 的采样逻辑,例如每隔 10 个坐标点取一个点
|
|
|
const points = [];
|
|
|
const step = 10; // 步长越大,点越稀疏
|
|
|
for (let i = 0; i < path.length; i += step) {
|
|
|
points.push(path[i]);
|
|
|
}
|
|
|
+
|
|
|
// 确保终点也被加上
|
|
|
if ((path.length - 1) % step !== 0) {
|
|
|
points.push(path[path.length - 1]);
|
|
|
}
|
|
|
|
|
|
- // const points = path.length > 2
|
|
|
- // ? [path[0], path[Math.floor(path.length / 2)], path[path.length - 1]]
|
|
|
- // : [path[0], path[1]];
|
|
|
+ // 临时逻辑,有真实接口后可以删除
|
|
|
+ points.forEach((pos, idx) => {
|
|
|
+ if (index === 8 && idx === 0) {
|
|
|
+ localStorage.setItem('pos1', pos);
|
|
|
+ }
|
|
|
+ if (index === 9 && idx === 0) {
|
|
|
+ localStorage.setItem('pos2', pos);
|
|
|
+ }
|
|
|
+ if (index === 10 && idx === 0) {
|
|
|
+ localStorage.setItem('pos3', pos);
|
|
|
+ }
|
|
|
|
|
|
- points.forEach(pos => {
|
|
|
markers.push(this.createTrafficLightMarker(pos, config));
|
|
|
});
|
|
|
|
|
|
@@ -179,12 +169,6 @@ export default {
|
|
|
const overlays = [...markers, polyline].filter(Boolean);
|
|
|
this.routeGroups[config.name] = overlays;
|
|
|
|
|
|
- // if (this.activeLegends.includes(config.name)) {
|
|
|
- // this.map.add(overlays);
|
|
|
- // // 这里的 setFitView 会根据点的位置自动聚焦
|
|
|
- // this.map.setFitView(overlays, false, [60, 60, 60, 60]);
|
|
|
- // }
|
|
|
-
|
|
|
if (this.activeLegends.includes(config.name)) {
|
|
|
this.map.add(overlays);
|
|
|
}
|
|
|
@@ -212,6 +196,7 @@ export default {
|
|
|
offset: new this.AMap.Pixel(-10, -10),
|
|
|
extData: {
|
|
|
...config,
|
|
|
+ position: [lng, lat],
|
|
|
statusColor: config.color, // 统一弹窗小圆点颜色
|
|
|
statusLabel: displayStatus, // 统一弹窗状态文字
|
|
|
road: '北京路与南京路',
|
|
|
@@ -223,35 +208,7 @@ export default {
|
|
|
return marker;
|
|
|
},
|
|
|
|
|
|
- // openLightInfo(data, position) {
|
|
|
- // const content = `
|
|
|
- // <div class="traffic-window">
|
|
|
- // <div class="window-header" style="background: ${data.lightDetail.color}">
|
|
|
- // <span class="title">路口信号机: ${data.name}</span>
|
|
|
- // </div>
|
|
|
- // <div class="window-body">
|
|
|
- // <div class="data-row"><span class="label">设备序列:</span><span>${data.lightDetail.sn}</span></div>
|
|
|
- // <div class="data-row">
|
|
|
- // <span class="label">当前相位:</span>
|
|
|
- // <span style="color: ${data.lightDetail.color}; font-weight:bold">${data.lightDetail.status}</span>
|
|
|
- // </div>
|
|
|
- // <div class="data-row"><span class="label">相位余时:</span><span class="highlight">${data.lightDetail.timeLeft}s</span></div>
|
|
|
- // <div class="data-row"><span class="label">运行模式:</span><span>智能感应</span></div>
|
|
|
- // <div class="progress-container">
|
|
|
- // <div class="progress-bar" style="width: ${(data.lightDetail.timeLeft / 60) * 100}%; background: ${data.lightDetail.color}"></div>
|
|
|
- // </div>
|
|
|
- // </div>
|
|
|
- // </div>
|
|
|
- // `;
|
|
|
-
|
|
|
- // if (!this.infoWindow) {
|
|
|
- // this.infoWindow = new this.AMap.InfoWindow({ isCustom: true, offset: new this.AMap.Pixel(0, -20) });
|
|
|
- // }
|
|
|
- // this.infoWindow.setContent(content);
|
|
|
- // this.infoWindow.open(this.map, position);
|
|
|
- // },
|
|
|
openLightInfo(data, position) {
|
|
|
- // 在 openLightInfo 内部
|
|
|
const content = `
|
|
|
<div class="custom-info-card">
|
|
|
<div class="close-btn" onclick="window.closeMapInfoWindow()">✕</div>
|
|
|
@@ -290,20 +247,6 @@ export default {
|
|
|
this.infoWindow.open(this.map, position);
|
|
|
},
|
|
|
|
|
|
- // 全选/全不选逻辑
|
|
|
- // toggleAll() {
|
|
|
- // if (this.isAllSelected) {
|
|
|
- // // 如果当前是全选,则清空激活列表,并隐藏地图上所有组
|
|
|
- // this.activeLegends = [];
|
|
|
- // Object.values(this.routeGroups).forEach(group => group && group.hide());
|
|
|
- // if (this.infoWindow) this.infoWindow.close();
|
|
|
- // } else {
|
|
|
- // // 如果当前不是全选,则填充所有图例名称,并显示地图上所有组
|
|
|
- // this.activeLegends = this.legendConfig.map(item => item.name);
|
|
|
- // Object.values(this.routeGroups).forEach(group => group && group.show());
|
|
|
- // }
|
|
|
- // },
|
|
|
-
|
|
|
// 全选/全不选逻辑修正版
|
|
|
toggleAll() {
|
|
|
const targetState = !this.isAllSelected; // 获取点击后的目标状态(true为全选,false为全不选)
|
|
|
@@ -338,20 +281,6 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- // 保留你原有的单个切换方法,但确保逻辑一致
|
|
|
- // toggleRouteVisible(name) {
|
|
|
- // const group = this.routeGroups[name];
|
|
|
- // const index = this.activeLegends.indexOf(name);
|
|
|
- // if (index > -1) {
|
|
|
- // this.activeLegends.splice(index, 1);
|
|
|
- // group && group.hide();
|
|
|
- // this.infoWindow && this.infoWindow.close();
|
|
|
- // } else {
|
|
|
- // this.activeLegends.push(name);
|
|
|
- // group && group.show();
|
|
|
- // }
|
|
|
- // },
|
|
|
-
|
|
|
toggleRouteVisible(name) {
|
|
|
const overlays = this.routeGroups[name] || []; // 获取的是数组
|
|
|
const index = this.activeLegends.indexOf(name);
|
|
|
@@ -363,6 +292,37 @@ export default {
|
|
|
this.activeLegends.push(name);
|
|
|
this.map.add(overlays); // 改用 add
|
|
|
}
|
|
|
+ },
|
|
|
+
|
|
|
+ // 其他组件点击定位到地图指定的点
|
|
|
+ focusByLocation(targetPos) {
|
|
|
+ if (!targetPos || targetPos.length !== 2) return;
|
|
|
+
|
|
|
+ let foundMarker = null;
|
|
|
+
|
|
|
+ // 1. 遍历所有路线组
|
|
|
+ Object.values(this.routeGroups).forEach(group => {
|
|
|
+ // 2. 在组内寻找 Marker
|
|
|
+ const marker = group.find(item => {
|
|
|
+ if (!(item instanceof this.AMap.Marker)) return false;
|
|
|
+ const pos = item.getExtData().position;
|
|
|
+ // 3. 坐标比对(考虑到浮点数精度,建议使用 AMap 自带的几何工具或简单比对)
|
|
|
+ return pos[0] === targetPos[0] && pos[1] === targetPos[1];
|
|
|
+ });
|
|
|
+ if (marker) foundMarker = marker;
|
|
|
+ });
|
|
|
+
|
|
|
+ if (foundMarker) {
|
|
|
+ // 4. 定位并打开弹窗
|
|
|
+ const finalPos = foundMarker.getPosition();
|
|
|
+ this.map.setZoomAndCenter(17, finalPos, false, 500); // 17级视角,平滑移动
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ this.openLightInfo(foundMarker.getExtData(), finalPos);
|
|
|
+ }, 600);
|
|
|
+ } else {
|
|
|
+ console.warn("未在地图上找到该坐标对应的点位:", targetPos);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
@@ -396,9 +356,6 @@ export default {
|
|
|
}
|
|
|
|
|
|
::v-deep .pure-light-node span {
|
|
|
- display: inline-block;
|
|
|
- width: 16px;
|
|
|
- height: 16px;
|
|
|
display: flex;
|
|
|
transform: scale(0.75);
|
|
|
align-items: center;
|
|
|
@@ -478,10 +435,9 @@ export default {
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
margin-right: 8px;
|
|
|
- font-size: 11px;
|
|
|
- color: #000;
|
|
|
- /* 图标内文字为黑色 */
|
|
|
- font-weight: bold;
|
|
|
+ font-size: 12px;
|
|
|
+ padding: 16px;
|
|
|
+ box-sizing: border-box;
|
|
|
}
|
|
|
|
|
|
::v-deep .status-dot span {
|