|
|
@@ -89,6 +89,7 @@ export default {
|
|
|
markerById: {}, // ID → marker 索引,加速 focusById 查找
|
|
|
startEndMarkers: [], // 起点/终点 marker 引用,缩放时需重建
|
|
|
subAreaOverlays: [], // 子区蒙层覆盖物
|
|
|
+ _subAreaParams: null, // 子区绘制参数,缩放时重绘用
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
|
@@ -319,6 +320,8 @@ export default {
|
|
|
if (!this.isComponentDestroyed) {
|
|
|
this.currentZoomSize = this.getDotSizeByZoom();
|
|
|
this.rebuildStartEndMarkers();
|
|
|
+ this.rebuildDotMarkers();
|
|
|
+ this.rebuildSubAreaText();
|
|
|
}
|
|
|
});
|
|
|
} catch (err) {
|
|
|
@@ -348,11 +351,11 @@ export default {
|
|
|
{ start: [116.66325, 39.9171], end: [116.6833, 39.9171], color: "#13C373", trunkId: 'trunk_6', trunkName: '张台路与湖亦路路口' },
|
|
|
],
|
|
|
"勤务路线": [
|
|
|
- { start: [116.6445, 39.8980], end: [116.6850, 39.8980], color: "#BC301D", dutyState: 'pending', taskId: 1 },
|
|
|
- { start: [116.6850, 39.8980], end: [116.7250, 39.8980], color: "#BC301D", dutyState: 'active', progress: 0.45, taskId: 3 },
|
|
|
- { start: [116.7250, 39.8980], end: [116.7650, 39.8980], color: "#BC301D", dutyState: 'done', taskId: 2 },
|
|
|
- { start: [116.6445, 39.9080], end: [116.7050, 39.9080], color: "#BC301D", dutyState: 'done', taskId: 4 },
|
|
|
- { start: [116.6445, 39.8880], end: [116.7050, 39.8880], color: "#BC301D", dutyState: 'pending', taskId: 5 }
|
|
|
+ { start: [116.6400, 39.9270], end: [116.7000, 39.9270], color: "#BC301D", dutyState: 'pending', taskId: 1 },
|
|
|
+ { start: [116.6400, 39.9120], end: [116.7000, 39.9120], color: "#BC301D", dutyState: 'active', progress: 0.45, taskId: 3 },
|
|
|
+ { start: [116.6700, 39.8970], end: [116.7300, 39.8970], color: "#BC301D", dutyState: 'done', taskId: 2 },
|
|
|
+ { start: [116.6400, 39.8820], end: [116.7000, 39.8820], color: "#BC301D", dutyState: 'done', taskId: 4 },
|
|
|
+ { start: [116.6400, 39.8670], end: [116.7000, 39.8670], color: "#BC301D", dutyState: 'pending', taskId: 5 }
|
|
|
]
|
|
|
};
|
|
|
|
|
|
@@ -966,6 +969,31 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ rebuildDotMarkers() {
|
|
|
+ if (!this.map || this.dotMarkers.length === 0) return;
|
|
|
+ const size = this.currentZoomSize;
|
|
|
+ const textDisplay = size >= 14 ? 'flex' : 'none';
|
|
|
+ const textSize = `${Math.max(10, size - 4)}px`;
|
|
|
+ for (const entry of this.dotMarkers) {
|
|
|
+ const { marker, config, isPassed } = entry;
|
|
|
+ if (isPassed) {
|
|
|
+ marker.setContent(`
|
|
|
+ <div class="pure-light-node" style="width: ${size}px; height: ${size}px; background: #5A5A5A; border: 1.5px solid rgba(255,255,255,0.25); box-sizing: border-box; display: flex; justify-content: center; align-items: center; color: #fff; border-radius: 50%; cursor: pointer; opacity: 0.55;">
|
|
|
+ <span style="display: ${textDisplay}; font-weight: bold; font-size: ${textSize};">勤</span>
|
|
|
+ </div>
|
|
|
+ `);
|
|
|
+ } else {
|
|
|
+ const displayText = config.name ? config.name.charAt(0) : '';
|
|
|
+ marker.setContent(`
|
|
|
+ <div class="pure-light-node route-node" style="width: ${size}px; height: ${size}px; background: ${config.color || '#999'}; box-shadow: none; border: none; box-sizing: border-box; display: flex; justify-content: center; align-items: center; color: #fff; border-radius: 50%; cursor: pointer;">
|
|
|
+ <span style="display: ${textDisplay}; font-weight: bold; font-size: ${textSize};">${displayText}</span>
|
|
|
+ </div>
|
|
|
+ `);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 创建交通信号灯标记
|
|
|
* @param {Array<number>|Object} position - 位置坐标
|
|
|
@@ -1001,7 +1029,7 @@ export default {
|
|
|
`;
|
|
|
} else if (isPassed) {
|
|
|
markerContent = `
|
|
|
- <div class="pure-light-node" style="width: var(--dot-size); height: var(--dot-size); background: #5A5A5A; border: 1.5px solid rgba(255,255,255,0.25); box-sizing: content-box; display: flex; justify-content: center; align-items: center; color: #888; border-radius: 50%; cursor: pointer; padding: var(--dot-padding); opacity: 0.55;">
|
|
|
+ <div class="pure-light-node" style="width: var(--dot-size); height: var(--dot-size); background: #5A5A5A; border: 1.5px solid rgba(255,255,255,0.25); box-sizing: border-box; display: flex; justify-content: center; align-items: center; color: #fff; border-radius: 50%; cursor: pointer; opacity: 0.55;">
|
|
|
<span style="display: var(--text-display); font-weight: bold; font-size: var(--text-size);">勤</span>
|
|
|
</div>
|
|
|
`;
|
|
|
@@ -1045,6 +1073,10 @@ export default {
|
|
|
if (isStartEnd) {
|
|
|
this.startEndMarkers.push({ marker, position: [lng, lat], config, type });
|
|
|
}
|
|
|
+ // 记录勤务路线上的圆点 marker(passed + normal route),缩放时需重建
|
|
|
+ if (!isStartEnd && isRoute) {
|
|
|
+ this.dotMarkers.push({ marker, config, type, isPassed });
|
|
|
+ }
|
|
|
|
|
|
marker.on('click', (e) => {
|
|
|
if (this.isComponentDestroyed) return;
|
|
|
@@ -1395,6 +1427,7 @@ export default {
|
|
|
drawSubAreaCircle(leaves, label) {
|
|
|
if (!this.isMapReady() || !leaves || leaves.length === 0) return;
|
|
|
|
|
|
+ this._subAreaParams = { leaves, label };
|
|
|
this.clearSubAreaOverlays();
|
|
|
|
|
|
const pts = leaves.map(n => [Number(n.lng), Number(n.lat)]);
|
|
|
@@ -1436,10 +1469,16 @@ export default {
|
|
|
const bottomRight = this.map.lngLatToContainer([Math.max(...lngs), Math.min(...lats)]);
|
|
|
const pixelW = Math.abs(bottomRight.x - topLeft.x);
|
|
|
const pixelH = Math.abs(bottomRight.y - topLeft.y);
|
|
|
- // 字号以横向宽度为基准,按文字长度均分,确保不超出区域
|
|
|
+ // 字号同时受宽度和高度约束,取较小值确保不超出区域
|
|
|
const charCount = label.length || 1;
|
|
|
- const fontSize = Math.min(Math.max(12, Math.round(pixelW / (charCount + 1))), 48);
|
|
|
+ const sizeByW = Math.round(pixelW * 0.8 / (charCount + 1));
|
|
|
+ const sizeByH = Math.round(pixelH * 0.6);
|
|
|
+ const fontSize = Math.min(Math.max(10, Math.min(sizeByW, sizeByH)), 48);
|
|
|
|
|
|
+ // 缩放过小时隐藏文字
|
|
|
+ if (fontSize < 10) {
|
|
|
+ // 不绘制文字
|
|
|
+ } else {
|
|
|
const text = new this.AMap.Text({
|
|
|
text: label,
|
|
|
position: [cx, cy],
|
|
|
@@ -1452,13 +1491,14 @@ export default {
|
|
|
'font-size': `${fontSize}px`,
|
|
|
'font-weight': 'bold',
|
|
|
'padding': '0',
|
|
|
- 'letter-spacing': '2px',
|
|
|
+ 'letter-spacing': fontSize >= 16 ? '2px' : '0px',
|
|
|
'white-space': 'nowrap',
|
|
|
'pointer-events': 'none',
|
|
|
},
|
|
|
});
|
|
|
this.subAreaOverlays.push(text);
|
|
|
this.map.add(text);
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -1501,6 +1541,13 @@ export default {
|
|
|
/**
|
|
|
* 清除子区圆形蒙层
|
|
|
*/
|
|
|
+ rebuildSubAreaText() {
|
|
|
+ if (!this._subAreaParams) return;
|
|
|
+ const { leaves, label } = this._subAreaParams;
|
|
|
+ // 保留参数,重绘整个子区(包含字号重新计算)
|
|
|
+ this.drawSubAreaCircle(leaves, label);
|
|
|
+ },
|
|
|
+
|
|
|
clearSubAreaOverlays() {
|
|
|
if (this.map && this.subAreaOverlays.length > 0) {
|
|
|
try { this.map.remove(this.subAreaOverlays); } catch (e) { void e; }
|