From b2883411bcbf887fccd9495d4acf37f4c418d477 Mon Sep 17 00:00:00 2001 From: jubnl Date: Sat, 11 Jul 2026 15:12:20 +0800 Subject: [PATCH] docs: add amap migration design --- .../2026-07-11-amap-single-provider-design.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-11-amap-single-provider-design.md diff --git a/docs/superpowers/specs/2026-07-11-amap-single-provider-design.md b/docs/superpowers/specs/2026-07-11-amap-single-provider-design.md new file mode 100644 index 00000000..8151de62 --- /dev/null +++ b/docs/superpowers/specs/2026-07-11-amap-single-provider-design.md @@ -0,0 +1,148 @@ +# 高德地图单供应商迁移设计 + +**状态:** 已确认,待编写实施计划 +**日期:** 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、数据库兼容和文档,应以分阶段、可测试任务实施,避免在旧地图组件尚被引用时删除依赖。