Skip to content

Latest commit

 

History

History
112 lines (83 loc) · 8.05 KB

SPEC.md

File metadata and controls

112 lines (83 loc) · 8.05 KB

Trip V1 规格

个人项目:一个 iOS App,在地图上找附近的加油站、EV 充电桩、休息区、厕所。 只装在自己的 iPhone 上(免费 Apple ID,每 7 天重新签名),不上架、不变现。

功能

  • 地图显示四类地点:加油站、EV 充电桩、休息区、厕所
  • 圆心 = 地图可见区域的中心(扣掉顶部过滤条和底部列表):打开时以我的位置为中心;拖动地图后列表跟着变;有"回到我的位置"按钮
  • 半径档位 100 m / 500 m / 1 / 2 / 5 / 10 / 25 / 50 km,默认 10 km,记住上次的选择
  • 底部列表按距离排序
  • 顶部四个分类开关(可多选,默认全开);地图缩小时点自动聚合
  • 子过滤:厕所"只看公共";EV "只看快充"和接口类型(NACS / CCS / CHAdeMO / J1772,多选)
  • 营业状态:列表和详情显示"营业中,几点关门 / 已关门,几点开门";"Open now"过滤隐藏确定已关门的地点,营业时间未知的保留
  • 无名厕所显示所在公园或附近街道,例如 "Washroom · Kitsilano Beach Park"
  • 点击地点弹出详情卡片,按类别显示字段;"导航"按钮优先跳 Google Maps,没装则跳 Apple Maps;App 内不做导航
  • 拒绝定位权限时,地图默认显示温哥华市中心
  • 单位 km,界面只做英文;每类地点一个 SF Symbol 图标
  • 设置页注明数据来源(满足 OSM ODbL 等授权要求)

厕所

尽量多收:公共、加油站和休息区、商场/图书馆/社区中心、餐厅/咖啡店。

  • 使用权限:公共(public)/ 仅限顾客(customers)/ 未知(unknown)
  • 可信度:官方数据(official)/ OSM 明确标注(osm)/ 按品牌或类别推断(inferred,界面明确标出)
  • 品牌和类别推断规则在 data/brands.yaml,可随时增删

数据

类别 数据源
加油站、厕所、餐厅/咖啡店等 OpenStreetMap(Overpass API)
EV 充电桩 AFDC API(developer.nlr.gov,原 NREL;覆盖加拿大,数据来自 NRCan)为主,Open Charge Map 补充(需要 key,可选)
公共厕所 City of Vancouver 开放数据 public-washrooms
休息区 DataBC MOT_REST_AREAS_SP(WFS)
  • 覆盖:BC 全省;校对集中在温哥华
  • 营业时间:data/hours.py 把各来源的写法统一解析成每周时间表(OSM 约 95%、AFDC 约 98% 能解析;季节性规则不支持,原文照常显示)。dawn/dusk/sunrise/sunset 由 App 按地点和日期计算。全年开放的 BC 休息区视为 24 小时
  • 无名厕所的位置名:用 Overpass 查每个厕所所在的公园/设施和 60 m 内的街道,按厕所缓存(本地在 data/cache/<地区>/osm_context.json,Actions 里在 data 分支的 context/<地区>.json)
  • 去重:同类点距离很近(默认 50 m,休息区 300 m)视为同一个,官方来源优先,其他来源补齐缺失字段
  • 产出:V1 是 data/build.py 手动运行,生成 Sources/Trip/Resources/pois.json 打包进 App。V2 改为后端定时生成、App 下载,见下
  • 字段
    • 通用:名称、类别、经纬度、地址、开放时间、数据来源
    • 厕所:使用权限、可信度、无障碍、婴儿换尿布台、是否收费
    • 充电桩:接口类型(CCS / NACS / CHAdeMO / J1772)、最大功率、充电网络、DC 快充和 L2 桩数、价格
    • 加油站:品牌、是否有柴油、是否有便利店
    • 休息区:公路编号、行驶方向、厕所数量和类型、是否全年开放、是否容纳大货车

技术

  • SwiftUI + MapKit(地图用 MKMapView 包装,借用原生聚合),最低 iOS 17
  • 在 Linux 上用 xtool 构建,只在真机测试
  • 只申请"使用 App 期间"的定位权限
  • App 名 Trip,bundle ID com.larryw.Trip

V1 不做

油价、前方模式和路线模式(路线模式见 V2)、App 内导航、账号和用户上报、CarPlay、后台定位和提醒、 EV 续航规划和实时空闲状态、离线底图、法语界面。


V2 计划

仍然只有我一个用户,没有账号。分三步,每步都能单独发布。

1. 数据后端(GitHub Actions)

  • 仓库公开(nessusing/trip)。地区和更新频率写在 data/regions.yaml,在 GitHub 上编辑就是"后台"
  • 先做 BC + WA;数据按省/州一个文件。WA 及以后的地区只用 OSM + AFDC;各地官方数据源按需作为可选来源加入
  • workflow 每天跑一次,只重建到期的地区(默认每 3 天);也可以在 GitHub 上手动触发并指定地区。不做按需生成
  • 发布前检查:pytest、App 的 Swift 模型能解码、点数比上一版少 20% 以上则拒绝。失败的地区保留上一版,GitHub 发邮件
  • 产出放在 data 分支(每次强制覆盖,不留历史):manifest.json(各地区版本、sha256、大小、数据格式版本、数据来源、简化边界)、regions/<id>.json、context/<id>.json
  • 每个地点保留一个 source;manifest 记录每个地区用了哪些来源。多数据源比对、按优先级选最准的来源以后再做
  • 品牌规则:全局 brands.yaml + 按地区覆盖
  • AFDC 用自己的 key(GitHub Secret),不用 OCM

2. App 下载数据

  • App 不再打包 pois.json,从 raw.githubusercontent.com 的 data 分支下载,存到 Application Support,之后离线可用
  • 启动时、以及回到前台时(最多每几小时一次)检查 manifest,sha256 变了才下载;"关于"页有"检查更新"按钮,并显示各地区的数据日期
  • 默认自动下载所有地区。全新安装且没网时显示"还没有数据,请联网下载"

3. 目的地与路线

为 road trip 设计。行驶中真正有用的是"前方某一段附近有什么",而不是把整条路线沿途的点全部列出来,所以路线模式的核心是让搜索圆心沿路线拖动。现有的"附近"模式保持不变。

3a. 目的地搜索(短途)

  • 底部列表顶上加搜索框,输入时用 MKLocalSearchCompleter 联想地址和地名(优先当前地图附近)
  • 选中后在目的地放一个大头针,地图和搜索圆跳过去,列表显示目的地周围的服务,跟平时拖地图一样
  • 目的地卡片上有"路线"和"×"(清除)两个按钮。没有单独的模式开关:选了目的地并点"路线"就进入路线模式,点 × 回到附近模式

3b. 路线模式(长途)

  • 从我的位置到目的地,用 MKDirections 算驾车路线并画在地图上;没有定位权限时提示需要定位
  • 搜索圆心吸附在路线上,不再跟随地图中心;拖地图只是看地图,不改变搜索位置
  • 两种方式移动圆心,两者同步:
    • 地图上的拖柄:手指拖动时投影到路线上最近的点
    • 底部的滑条:从我当前所在位置到终点,标着"前方 xx km · 约 xx 分钟";拖滑条时地图跟着圆心走
  • 圆心只能在我当前位置之前;我开过了圆心所在的位置,圆心跟着我往前推
  • 半径、分类、Open now、EV 过滤照常生效;列表按沿路线的先后排序,每项显示"前方 xx km · 约 xx 分钟"(时间按路线总时长按比例估算);离路线 5 km 以上的点只显示直线距离,标"离路线较远"
  • 覆盖范围:路线经过没有数据的地区时,显示"数据不完整:缺 Alberta"(对未覆盖的路段用 CLGeocoder 反查省/州名);整条路线都没有数据时只显示提示

3c. 增强

  • 前方最近一键跳转:每个分类一个按钮(下一个厕所 / 加油站 / 充电桩 / 休息区),把圆心跳到圆心之后、离路线 2 km 以内的第一个符合过滤条件的点
  • 备选路线:请求最多 3 条路线,都画在地图上(选中的高亮),在底部用按钮切换,各自标出里程和时间
  • 缓存路线:选中的路线(折线、里程、时长、目的地)存到手机上,重新打开 App 时恢复,没信号时也能用。底图是否离线可用取决于 Apple 地图缓存,不保证

以后再说:偏离路线后自动重新规划、DriveBC 路况。