Trek_CN/docs/superpowers/specs/2026-07-11-amap-single-provider-design.md
jubnl b2883411bc
Some checks are pending
Security Scan / scout (push) Waiting to run
docs: add amap migration design
2026-07-11 15:12:20 +08:00

149 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 高德地图单供应商迁移设计
**状态:** 已确认,待编写实施计划
**日期:** 2026-07-11
## 目标
将 TREK 的所有运行时地图能力收敛到高德地图:前端使用高德 JS API服务端使用高德 Web 服务 API。删除所有其他地图供应商的运行时调用、包依赖、用户配置、CSP 白名单、文案与测试桩。
迁移必须保留既有行程、地点、GPX 与照片数据;不能因删除旧供应商造成数据丢失。
## 非目标
- 不保留运行时多地图供应商切换或故障回退。
- 不实现未经高德授权的离线底图瓦片缓存。
- 不将既有 Google/OSM 供应商专属字段作为迁移的一部分物理删除。
- 不把高德密钥提交到仓库、数据库或前端用户设置。
## 供应商边界
| 能力 | 迁移后实现 | 旧实现(删除) |
| --- | --- | --- |
| 交互地图、标记、聚合、路线图层 | 高德 JS API | Leaflet、Mapbox GL、MapLibre GL |
| 地点搜索、输入提示、详情、编码 | 服务端代理高德 Web 服务 | Google Places、Nominatim、Overpass |
| 地图 POI 浏览 | 服务端代理高德 POI/周边搜索 | Overpass |
| 驾车、步行、骑行路线 | 服务端高德路径规划 | OSRM、FOSSGIS、客户端直连 OSRM |
| 公交规划 | 服务端高德公交路径规划 | Transitous/MOTIS |
| 外部地图打开 | 高德 URI API | Google Maps 外链 |
| Google/Naver 列表导入及 Google URL 解析 | 删除,不提供替代 | Google Maps/Naver 地图 |
高德不支持或无数据的区域、跨境路线以及无法转换的请求,返回明确的“当前区域或路线不受支持”状态;不得调用其他地图供应商回退,也不得把直线伪装成高德路径规划结果。
## 密钥与安全设计
### 配置
部署环境使用以下占位配置,实际密钥后续由部署者填写:
```dotenv
AMAP_WEB_SERVICE_KEY=__TO_BE_FILLED__
VITE_AMAP_JS_API_KEY=__TO_BE_FILLED__
AMAP_JS_SECURITY_CODE=__TO_BE_FILLED__
```
- `AMAP_WEB_SERVICE_KEY` 仅存在于服务端进程环境,用于高德 Web 服务请求。
- `VITE_AMAP_JS_API_KEY` 可被浏览器加载,用于高德 JS API。
- `AMAP_JS_SECURITY_CODE` 仅存在于服务端;高德 JS API 在加载前通过 `window._AMapSecurityConfig.serviceHost` 指向自有服务端反代,不得以 `VITE_*` 变量编译到浏览器。
- 删除 `mapbox_access_token`、`map_provider`、`mapbox_style`、`maplibre_style`、`map_tile_url` 的设置入口和持久化使用。
### 服务端保护
高德 Web 服务请求由服务端统一发起。每个适配器请求必须具有:有限超时、可取消请求、按用户/IP 的限流、短期缓存、上游错误到应用错误的映射,以及不记录密钥的结构化日志。启动时应检测 `AMAP_WEB_SERVICE_KEY`,缺失时地图 API 返回稳定的“未配置”错误。
高德 JS API 的 `serviceHost` 反代只处理安全密钥要求的请求,不透传任意 URL以固定路径、固定目标域名和参数校验避免成为开放代理。CSP 仅放行实际所需的高德脚本、样式、图片和服务端反代来源。
## 坐标体系
### 业务标准
数据库、共享 API、导入/导出、GPX、业务组件和历史数据的标准坐标为 **WGS-84**,格式为内部既有的 `[lat, lng]``{ lat, lng }`
高德 JS API、高德 Web 服务和高德 URI API 的坐标边界统一为 **GCJ-02**,且 URI 参数使用 `lng,lat` 顺序。
### 转换规则
1. 进入高德边界时,对中国大陆内 WGS-84 坐标做 WGS-84 → GCJ-02 转换。
2. 高德搜索、POI、逆地理和路径规划返回的 GCJ-02 坐标进入业务层前,做经过测试的 GCJ-02 → WGS-84 近似逆转换。
3. 中国大陆外坐标不转换,原样传递和存储。
4. 港澳台与跨境请求在适配器中有显式策略:高德不支持时返回受控“不支持”结果,不尝试混合坐标或其他供应商。
5. 高德地图的 marker、polyline、bounds、中心点、地理定位展示、外链和路线几何均只能使用转换后的 GCJ-02 值;不允许把 WGS-84 直接绘制到高德地图。
坐标模块要有境内、境外、边界、往返误差、批量路线几何和经纬顺序测试。
## 前端架构
新增一个单一的高德地图适配层,向业务组件保留当前通用能力:地图就绪、地图点击/长按、视口变化、marker 点击、选择态、聚合、路线、预订连接线、POI、定位、自动缩放和外链。
迁移覆盖下列地图消费者,而不仅是行程规划页:
- 行程规划地图及日程路线。
- Journey 地图、Collection 地图和共享行程页。
- Atlas 地图、GeoJSON 图层和世界/区域展示。
- Mapbox 专用预约 Overlay、指南针、定位组件和样式/3D 辅助组件。
高德不提供与现有 Mapbox 3D/样式自由度一一对应的功能。迁移后只保留高德明确支持的平面地图交互;删除 Mapbox 3D、MapLibre/OpenFreeMap 样式预设、供应商切换与自定义 XYZ 瓦片配置。
离线功能不再预取或缓存第三方 XYZ 地图瓦片。删除离线瓦片预取、缓存、设置页、PWA 配置、文案和测试;如将来获得高德离线能力书面授权,另立设计。
## 后端架构
### 高德地图适配器
将当前 `/api/maps` 的实现重构为高德专属适配器,维持面向客户端的通用响应模型,避免业务 UI 直接依赖高德原始响应。适配器提供:
- 文本 POI 搜索和输入提示。
- POI 详情、地理编码和逆地理编码。
- 当前视口或中心点附近的分类 POI 搜索。
- 用高德 POI 数据映射现有地点字段。
- 高德 URI 外链构建。
高德 POI 分类与 Overpass 分类不等价。分类映射必须显式定义和测试;没有稳定映射的类别显示为不可用,不可假设原有 OSM 标签可原样查询。
Google 的照片、评论、营业时间与高德字段及授权不等价。迁移实施前需以真实高德账户核实可用字段和图片授权;未确认前,界面显示通用地点信息,不能伪造或回退到 Google。
### 路线服务
所有路线请求迁移到鉴权服务端端点,浏览器不再直连 OSRM。
- 驾车、步行、骑行适配成统一的业务路线结果(坐标、距离、时长、分段)。
- 高德请求和响应均通过坐标模块转换。
- 长路径按高德途经点上限分块;每块分别请求,按顺序拼接去重后的几何、距离和时长。
- 请求失败返回受控错误;只有业务明确标识为“估算连线”的现有展示可以显示直线,不得将其标记为路线规划成功。
### 公交服务
删除 Transitous/MOTIS 服务和客户端契约。新增高德公交结果适配器,将高德的多段步行/公交/地铁结果映射为 TREK 所需 itinerary、leg、时刻、站点和几何模型。`transitGeometry` 及公交 UI 使用适配后的内部模型,不读取高德原始字段。
## 数据保留与清理
历史 `google_place_id`、`google_ftid`、旧 Google URL、OSM 标识及已有照片缓存保留为只读遗留数据以确保历史地点、收藏、行程、MCP 输出和迁移兼容。它们不再触发任何运行时 Google/OSM 请求,也不再出现在新增/编辑流程中。
新地点不写入 Google/OSM 专属 ID。如确需持久化高德 POI ID新增供应商中性标识结构而不是复用旧字段其取值和供应商来源必须成对保存。
删除 Google Maps 列表导入、Google URL 解析、Naver 地图导入及对应 API、MCP 工具文案、i18n、撤销记录描述、帮助文档和测试。地图外链统一由名称与业务 WGS-84 坐标转换后生成高德 URI。
## 明确删除的旧集成
- 前端包与代码Leaflet、React Leaflet、Mapbox GL、MapLibre GL、Mapbox/MapLibre 样式、CARTO/OpenFreeMap/其他 XYZ 瓦片。
- 服务端Google Places 和照片、Nominatim、Overpass、OSRM/FOSSGIS、Transitous/MOTIS、Google URL 解析和地图列表导入。
- 配置与安全旧供应商环境变量、用户设置、SSRF/CSP 允许域、离线缓存规则。
- 质量资产:对应 mock、测试、i18n、文档及依赖锁文件条目。
## 验收标准
1. 未配置 Key 时,地图和地图 API 显示一致、可理解的未配置状态;不发生旧供应商回退。
2. 已配置 Key 时地点搜索、输入提示、详情、逆地理、POI、驾车、步行、骑行和公交均通过高德完成。
3. 行程规划、Journey、Collection、共享页和 Atlas 都不再加载 Leaflet、Mapbox 或 MapLibre。
4. 中国大陆的 marker、路线、搜索结果和外链位置正确境外、港澳台和跨境边界行为符合受控不支持策略。
5. 历史行程、地点、GPX 和缓存图片仍能读取;迁移不删除旧供应商标识字段的数据。
6. 离线地图瓦片功能和旧供应商设置不再暴露。
7. 全仓依赖与文本扫描确认没有旧地图供应商的运行时域名、包依赖、环境变量或可达 API 入口。
8. 单元/契约测试覆盖高德适配器、坐标转换、路径拆分、公交转换、缺 Key、超时、限流和 URL 编码;预发环境以真实 Key 完成冒烟测试。
## 实施前提与风险
- 部署者后续需要申请并配置高德 Web 服务 Key、JS API Key 和 JS 安全密钥。
- 高德的区域覆盖、公交数据、POI 字段和照片授权必须在预发环境用真实账户核验;这些能力不与 Google/OSM 自动等价。
- 此迁移横跨客户端、服务端、共享页、Atlas、PWA、MCP、数据库兼容和文档应以分阶段、可测试任务实施避免在旧地图组件尚被引用时删除依赖。