317 lines
8.6 KiB
Markdown
317 lines
8.6 KiB
Markdown
# 地图模块-抽吸规则与参数说明
|
||
|
||
## 1. 文档目的
|
||
|
||
本文档用于记录当前地图点位“抽吸”功能的现行实现、默认参数、分层级显示规则和后续调参方式。
|
||
本文件描述的是**当前已经落地并验证通过**的规则,适合作为后续维护和继续调参的依据。
|
||
|
||
相关文档:
|
||
|
||
- `docs/地图模块-详细说明.md`:地图整体架构说明
|
||
- `docs/地图模块-OpenLayers抽吸与碰撞分析.md`:问题成因与改造分析
|
||
|
||
## 2. 当前实现范围
|
||
|
||
当前抽吸逻辑运行在 OpenLayers 主链路中,核心文件如下:
|
||
|
||
1. `src/modules/map/domain/nearby-point-rules.ts`
|
||
2. `src/store/modules/map.ts`
|
||
3. `src/components/gis/map.ol.ts`
|
||
4. `src/components/gis/ol/point-layer-manager.ts`
|
||
|
||
各文件职责:
|
||
|
||
- `nearby-point-rules.ts`
|
||
- 近邻点规则入口
|
||
- 自动识别配置入口
|
||
- 近邻点运行时元数据挂载
|
||
- `map.ts`
|
||
- 点位数据加载完成后,统一触发近邻点分组和元数据写回
|
||
- `map.ol.ts`
|
||
- 决定某个点在当前缩放级别是否显示
|
||
- 决定文字是否允许显示
|
||
- 承担图标与文字的手工碰撞控制
|
||
- `point-layer-manager.ts`
|
||
- 负责展开阶段的几何偏移
|
||
- 负责把同组点位按扇形/环形布局散开
|
||
|
||
## 3. 当前抽吸规则
|
||
|
||
### 3.1 近邻点自动识别
|
||
|
||
当前采用自动识别近邻点,不再靠固定站名手工枚举。
|
||
|
||
识别原则:
|
||
|
||
- 只在同一 `layerKey` 内做近邻识别
|
||
- 按点位空间距离自动聚组
|
||
- 满足最小组大小后,才认为是近邻组
|
||
- 组内自动生成显示优先级 `priority`
|
||
|
||
这样做的目的:
|
||
|
||
- 避免跨图层混组
|
||
- 避免后续新增点位还要手工补名字
|
||
- 让抽吸能力可以覆盖整批业务点
|
||
|
||
### 3.2 分层级显示规则
|
||
|
||
当前显示规则以 `replaceAtZoom` 和 `expandAtZoom` 为核心:
|
||
|
||
1. `zoom < replaceAtZoom`
|
||
- 只显示组内主点
|
||
- 即 `priority = 1`
|
||
2. `replaceAtZoom <= zoom < expandAtZoom`
|
||
- 显示组内前两个点
|
||
- 即 `priority <= 2`
|
||
- 当前这样设计是为了避免主点在放大过程中突然消失
|
||
3. `zoom >= expandAtZoom`
|
||
- 同组点全部显示
|
||
- 同时进入展开布局阶段
|
||
|
||
补充规则:
|
||
|
||
- 如果某个点配置了 `showZoomMin` 或 `showZoomMax`,则先受这两个值约束
|
||
- 没有进入近邻组的点,不受抽吸规则影响
|
||
|
||
### 3.3 文字显示规则
|
||
|
||
当前文字显示必须依赖点位显示。
|
||
|
||
也就是说:
|
||
|
||
- 点不显示,文字一定不显示
|
||
- 点显示后,文字还要继续通过碰撞判断才会显示
|
||
|
||
当前文字碰撞规则:
|
||
|
||
- 文字要避让已保留的图标占位盒
|
||
- 文字要避让已保留的其他文字
|
||
- 图标与文字不再分别交给 OpenLayers 的 `declutter` 自动处理
|
||
- 当前走的是项目内的手工碰撞控制
|
||
|
||
## 4. 当前默认参数
|
||
|
||
当前默认参数集中维护在:
|
||
|
||
- `src/modules/map/domain/nearby-point-rules.ts`
|
||
|
||
当前采用统一配置对象:
|
||
|
||
```ts
|
||
type NearbyPointConfig = {
|
||
autoRule: NearbyPointAutoRule;
|
||
layoutRule: NearbyPointLayoutRule;
|
||
densityDisplayRules: NearbyPointDensityDisplayRule[];
|
||
};
|
||
```
|
||
|
||
其中:
|
||
|
||
- `autoRule`:控制近邻点自动识别、缩放切换和基础展开半径
|
||
- `layoutRule`:控制展开阶段的单圈容量、扇形角度和外圈间距
|
||
- `densityDisplayRules`:控制 `distance` 密度分档在不同缩放级别的基础显示资格
|
||
|
||
### 4.1 自动识别与缩放阶段参数
|
||
|
||
当前值如下:
|
||
|
||
| 参数 | 当前值 | 作用 |
|
||
|---|---:|---|
|
||
| `distanceThresholdMeters` | `9000` | 近邻点自动识别距离阈值 |
|
||
| `replaceAtZoom` | `10.5` | 进入“主点 + 次点”阶段的缩放级别 |
|
||
| `expandAtZoom` | `12.2` | 进入“全部显示并展开”阶段的缩放级别 |
|
||
| `expandOffsetPx` | `48` | 第一圈展开的基础偏移半径 |
|
||
| `angleStepDeg` | `55` | 默认角度步长参考值 |
|
||
| `minGroupSize` | `2` | 最小成组数量 |
|
||
|
||
### 4.2 展开布局参数
|
||
|
||
当前值如下:
|
||
|
||
| 参数 | 当前值 | 作用 |
|
||
|---|---:|---|
|
||
| `ringSize` | `5` | 单圈最多容纳的次点数量 |
|
||
| `fanAngleForTwoDeg` | `110` | 单圈剩余 `2` 个点时的扇形总角度 |
|
||
| `fanAngleForFourDeg` | `150` | 单圈剩余 `3` 到 `4` 个点时的扇形总角度 |
|
||
| `fanAngleForManyDeg` | `180` | 单圈剩余 `5` 个及以上点时的扇形总角度 |
|
||
| `ringGapPx` | `22` | 外圈最小增量半径 |
|
||
| `ringGapFactor` | `0.85` | 外圈相对基础半径的增量系数 |
|
||
|
||
### 4.3 密度分档显示参数
|
||
|
||
这里的 `distance` 不是物理距离,而是点位密度分档值。
|
||
数值越大表示越稀疏,越早参与显示候选;数值越小表示越密集,需要更高缩放级别才参与显示。
|
||
|
||
当前值如下:
|
||
|
||
| `minDensityValue` | `minZoom` | 作用 |
|
||
|---:|---:|---|
|
||
| `1500000` | `0` | 很稀疏的点,从小缩放级别就可参与显示 |
|
||
| `800000` | `6.1` | 稍密集的点,从中低缩放开始参与显示 |
|
||
| `400000` | `8.1` | 中密度点,需要进一步放大 |
|
||
| `50000` | `10.6` | 高密度点,需要较高缩放级别 |
|
||
| `0` | `12.2` | 极密集点,只有更高缩放才进入候选 |
|
||
|
||
## 5. 当前展开布局
|
||
|
||
展开阶段由 `point-layer-manager.ts` 控制。
|
||
|
||
### 5.1 布局特点
|
||
|
||
当前布局不是简单把点随机散开,而是按以下方式处理:
|
||
|
||
- 主点保留原位置
|
||
- 同组其他点围绕主点展开
|
||
- 展开方向优先偏下方
|
||
- 单圈数量由 `ringSize` 控制
|
||
- 点数较多时进入第二圈
|
||
- 第二圈半径按 `ringGapPx` 和 `ringGapFactor` 继续增大,避免继续叠在一起
|
||
|
||
### 5.2 为什么优先向下展开
|
||
|
||
当前优先向下展开,主要是为了:
|
||
|
||
- 尽量给上方文字留空间
|
||
- 降低文字压住上方点的概率
|
||
- 让地图上的抽吸形态更稳定
|
||
|
||
## 6. 当前实现的几个关键约束
|
||
|
||
### 6.1 不使用淡入淡出动画
|
||
|
||
目前已移除点和文字的淡入淡出动画。
|
||
|
||
原因:
|
||
|
||
- 抽吸状态切换和动画叠加时,容易让点和文字出现闪烁
|
||
- 会干扰对“当前到底该不该显示”的判断
|
||
|
||
当前阶段优先保证:
|
||
|
||
- 显示规则稳定
|
||
- 点和文字状态一致
|
||
- 放大缩小时不出现明显错位
|
||
|
||
### 6.2 不再依赖 OL 的自动 declutter 决定图标命运
|
||
|
||
当前图标和文字都设置为 `declutterMode: 'none'`,由项目内逻辑统一控制。
|
||
|
||
这样做的原因:
|
||
|
||
- 避免图标和文字落在两套碰撞体系里
|
||
- 避免出现“文字先出来、点没出来”
|
||
- 避免文字压住其他点却仍然显示
|
||
|
||
## 7. 常见现象与调参建议
|
||
|
||
### 7.1 成组太少
|
||
|
||
表现:
|
||
|
||
- 相近点仍然容易互相盖住
|
||
- 进入展开前看起来还是压在一起
|
||
|
||
优先调整:
|
||
|
||
- 增大 `distanceThresholdMeters`
|
||
|
||
### 7.2 成组太多
|
||
|
||
表现:
|
||
|
||
- 距离并不算近的点也被当成一组
|
||
- 放大后过早进入抽吸关系
|
||
|
||
优先调整:
|
||
|
||
- 减小 `distanceThresholdMeters`
|
||
|
||
### 7.3 展开太晚
|
||
|
||
表现:
|
||
|
||
- 放大到较深层级前仍然挤在一起
|
||
|
||
优先调整:
|
||
|
||
- 减小 `expandAtZoom`
|
||
|
||
### 7.4 展开太早
|
||
|
||
表现:
|
||
|
||
- 中等缩放时地图上就出现较明显散开效果
|
||
|
||
优先调整:
|
||
|
||
- 增大 `expandAtZoom`
|
||
|
||
### 7.5 展开后间距不够
|
||
|
||
表现:
|
||
|
||
- 虽然已经展开,但图标还是比较挤
|
||
|
||
优先调整:
|
||
|
||
- 增大 `expandOffsetPx`
|
||
- 或增大 `ringGapPx`
|
||
- 或增大 `ringGapFactor`
|
||
|
||
### 7.6 单圈散开角度不合适
|
||
|
||
表现:
|
||
|
||
- 次点虽然已经展开,但仍然集中在一侧
|
||
- 或者扇形过大,展开形态显得太散
|
||
|
||
优先调整:
|
||
|
||
- 调整 `fanAngleForTwoDeg`
|
||
- 调整 `fanAngleForFourDeg`
|
||
- 调整 `fanAngleForManyDeg`
|
||
|
||
### 7.7 主点在放大过程中突然消失
|
||
|
||
当前已经通过 `replaceAtZoom <= zoom < expandAtZoom` 阶段显示 `priority <= 2` 进行修正。
|
||
如果后续又出现类似现象,优先检查:
|
||
|
||
- `map.ol.ts` 中 `shouldRenderNearbyFeature()` 的阶段逻辑
|
||
- 是否误改成只显示 `priority = 2`
|
||
|
||
### 7.8 明明周围看起来空,文字还是不显示
|
||
|
||
优先检查:
|
||
|
||
- 图标碰撞盒是否过大
|
||
- 文字碰撞盒是否过于保守
|
||
- 候选集是否发生重复统计
|
||
|
||
相关代码主要在:
|
||
|
||
- `src/components/gis/map.ol.ts`
|
||
|
||
## 8. 后续维护建议
|
||
|
||
建议后续继续保持以下约定:
|
||
|
||
1. 抽吸参数继续统一放在 `nearby-point-rules.ts`
|
||
2. 显示决策继续集中在 `map.ol.ts`
|
||
3. 几何偏移继续集中在 `point-layer-manager.ts`
|
||
4. 后续调参优先改 `DEFAULT_NEARBY_POINT_CONFIG`,不要直接把数值散落回业务代码
|
||
5. 如果继续加动画,必须放在抽吸状态机完全稳定之后
|
||
6. 如果继续优化 popup,也要同步遵循“点先于文字”的显示原则
|
||
|
||
## 9. 当前结论
|
||
|
||
当前这版抽吸实现已经形成了比较稳定的主线:
|
||
|
||
- 自动识别近邻点
|
||
- 统一缩放阶段显示规则
|
||
- 展开阶段几何偏移
|
||
- 文字依赖点显示
|
||
- 文字避让图标与文字
|
||
|
||
后续如果继续调优,建议先从参数层开始,不要先动主逻辑结构。
|