# 准备页地图预览方案 > 文档版本:v1.0 > 最后更新:2026-04-07 12:18:00 本文档用于说明活动准备页的地图预览能力如何设计与落地。 当前目标不是直接进入实现,而是先把方案边界、分层、前后端职责和分阶段路径定清。 --- ## 1. 目标 准备页当前已经具备: - 活动状态摘要 - 赛道选择 - 设备准备 - 进入地图 但“本局对象预览”仍然主要是文字占位,对玩家帮助有限。 准备页地图预览的目标是: 1. 在进入地图前,让玩家建立空间预期 2. 在多赛道活动中,让玩家能直观看到当前赛道差异 3. 让准备页更像“出发前准备”,而不是工程参数页 4. 不打断当前 runtime 主链,也不额外制造一套重资源地图体系 --- ## 2. 推荐方案 当前推荐采用: **低级别正式瓦片做底图,前端动态叠加赛道** 也就是: - 底图来源:现有正式瓦片资源 - 底图级别:选择一个较低 zoom 作为预览缩略底图 - 叠加层:前端根据当前赛道数据在预览图上动态绘制起点、终点、控制点和腿线 这是一个“混合预览方案”: - 不单独制作新的预览地图资源 - 不在前端完整拼装高精度交互地图 - 只在准备页做只读预览 --- ## 3. 为什么选这个方案 ### 3.1 不新增独立地图资源 如果单独为准备页制作预览地图资源,会带来: - 资源重复 - 发布链复杂度上升 - 底图与正式地图不一致风险 使用低级别正式瓦片作为预览底图,可以保持: - 同源 - 一致 - 低成本 ### 3.2 多赛道切换更自然 多赛道场景下: - 底图通常是同一张地图 - 差异主要在赛道叠加层 因此最合理的方式是: - 底图固定 - 切换赛道时仅重绘 overlay 这样: - 切换更快 - 数据结构更清楚 - 不需要为每个 variant 重新生成整张预览图 ### 3.3 前后端职责清楚 后端负责: - 提供底图预览所需元数据 - 提供赛道叠加所需坐标数据 前端负责: - 展示底图 - 动态叠加赛道 - 在准备页进行只读预览 这符合当前项目一直坚持的分层原则。 --- ## 4. 整体分层 准备页地图预览建议分成 4 层。 ### 4.1 地图底图层 来源: - 当前正式瓦片资源 形式: - 低级别缩略底图 职责: - 提供地点区域的空间背景 ### 4.2 预览元数据层 来源: - 后端预览元数据 职责: - 告诉前端如何把经纬度投到预览图坐标系中 ### 4.3 赛道叠加层 来源: - variant 控制点与腿线数据 职责: - 在准备页上画出当前赛道 ### 4.4 准备页展示层 职责: - 只读展示 - 切换赛道联动预览 - 不承担局内交互 --- ## 5. 后端需要提供的最小字段 V1 不要求后端提供完整预览图 URL,而是先提供“底图元数据 + 赛道 overlay 元数据”。 建议后端提供以下最小结构: ```json { "preview": { "mode": "full", "baseTiles": { "tileBaseUrl": "https://.../tiles/", "zoom": 15, "tileSize": 256 }, "viewport": { "width": 800, "height": 450, "minLon": 117.0000, "minLat": 36.6000, "maxLon": 117.0800, "maxLat": 36.6600 }, "variants": [ { "variantId": "variant_a", "name": "A线", "routeCode": "route-variant-a", "controls": [ { "id": "start", "kind": "start", "lon": 117.01, "lat": 36.61 }, { "id": "c1", "kind": "control", "lon": 117.02, "lat": 36.615 }, { "id": "finish", "kind": "finish", "lon": 117.03, "lat": 36.62 } ], "legs": [ { "from": "start", "to": "c1" }, { "from": "c1", "to": "finish" } ] } ] } } ``` 其中关键字段是: - `baseTiles.tileBaseUrl` - `baseTiles.zoom` - `viewport.width / height` - `viewport.minLon / minLat / maxLon / maxLat` - `variants[].controls` - `variants[].legs` 这些字段足够前端做只读预览。 --- ## 6. 前端如何消费 前端准备页的消费方式建议如下: ### 6.1 底图渲染 - 使用低级别瓦片作为底图来源 - 按 `viewport` 与 `zoom` 计算需要的瓦片范围 - 只在准备页内绘制一张静态缩略底图 ### 6.2 赛道叠加 - 根据 `viewport` 把控制点经纬度投影到预览图坐标 - 在 canvas 或同等绘制层上叠加: - 起点 - 终点 - 控制点 - 腿线 ### 6.3 多赛道切换 - 切换赛道时不重新换底图 - 只重绘叠加层 ### 6.4 展示层级 准备页只做: - 只读预览 - 不拖拽 - 不缩放 - 不交互打点 --- ## 7. 多赛道场景如何处理 多赛道场景是这套方案的重点。 当前建议规则: 1. 同一活动下,所有 variant 共用一张底图 2. 当前选中的 variant 决定叠加层内容 3. 如果活动允许手动选赛道,切换赛道时预览同步切换 4. 如果活动是随机分配或后台指定: - 准备页在最终绑定前可只显示地点底图 - 一旦后端返回最终绑定赛道,再显示该赛道 overlay 这套设计和当前多赛道 Variant 架构是一致的: - 底图属于地图对象 - 叠加属于 variant 对象 --- ## 8. 预览级别建议 建议预览能力分成 3 档: ### 8.1 `none` - 不显示地图预览 - 只显示地点、地图、赛道文字信息 适用于: - 不允许赛前预览的正式比赛 ### 8.2 `summary` - 显示底图 - 只显示简化赛道范围、起终点或大致区域 - 不暴露完整点位和腿线 适用于: - 需要局前空间感,但不允许完整剧透路线 ### 8.3 `full` - 显示底图 - 显示完整点位与腿线 适用于: - 体验活动 - 教学活动 - 低门槛公开活动 V1 建议先直接支持: - `none` - `full` 后面再补 `summary`。 --- ## 9. 分阶段实施建议 ### 9.1 V1 只做: - 低级别瓦片底图 - 前端动态赛道叠加 - 支持多赛道切换联动 - 只读展示 不做: - 复杂预览交互 - 预览模式细分 - 缩放与拖拽 ### 9.2 V2 补: - `none / summary / full` - 不同活动类型的预览策略 - 更细的赛道保密规则 ### 9.3 V3 考虑扩展到: - 活动详情页缩略预览 - 活动列表卡片缩略图 - 赛后结果页路线回看缩略图 --- ## 10. 不建议的方案 当前不建议: ### 10.1 单独制作一套预览地图资源 问题: - 成本高 - 一致性差 - 发布链复杂 ### 10.2 前端直接现场拼完整高精度瓦片地图 问题: - 性能波动大 - 首次加载慢 - 多端一致性差 ### 10.3 后端为每个 variant 预生成完整大图 问题: - 多赛道下资源重复 - 每次改赛道都要重生图 - 扩展性不如“底图固定 + 叠加切换” --- ## 11. 当前建议结论 准备页地图预览最推荐的路线是: **使用低级别正式瓦片作为预览底图,由前端在准备页动态叠加当前赛道。** 这条路线的优点是: - 不新增独立地图资源 - 底图与正式地图同源 - 多赛道切换成本低 - 前后端职责清晰 - 易于分阶段落地 当前建议优先推进: 1. 后端补预览元数据最小字段 2. 前端在准备页实现只读底图 + overlay 3. 先支持 `full` 4. 后续再扩 `summary / none`