夜雨聆风学习资料网

ARTICLE · 957420

地图 API 年费太贵?我用 UniApp 做了 8 套低成本替代方案

地图 API 年费太贵?我用 UniApp 做了 8 套低成本替代方案
热门产品推荐:
软著申请全解析:144元轻松搞定版权保护
游戏陪玩平台的技术架构与实现:打造高效、安全的游戏社交生态

天地图、OpenStreetMap、本地省市区、混合降级、OpenCage、MapBox、HERE、自建 Nominatim,一套项目全部跑通。

物流配送、上门服务、签到打卡、本地生活……很多业务都绕不开一个基础能力:

把经纬度转换成用户看得懂的地址。

真正接入商业地图服务后,不少团队才发现:免费额度、商用授权、调用量和年费都可能成为长期成本。对中小项目来说,直接采购高价套餐未必是唯一选择。

这个 UniApp 示例项目给出了 8 条可落地路径,并提供 H5、App、小程序可参考的页面与 API 封装。

先说结论

  • 只需要填写收货地址:优先使用省市区三级联动,无需地图 API。
  • 国内业务且需要地图:优先评估天地图。
  • 海外或低频演示:可评估 OpenStreetMap + Nominatim。
  • 线上核心业务:采用主服务 + 备用服务 + 手动录入的混合降级架构。
  • 调用量大、合规和稳定性要求高:使用商业服务,或评估自建 Nominatim。

“免费”不等于没有约束。调用频率、商用条款、数据许可和免费额度都可能调整,上线前请以各服务商最新官方政策为准。

项目实现了什么

方案
是否需要 Key
核心能力
推荐场景
天地图
是
逆地址编码、影像/矢量/地形切换
国内项目
本地省市区 JSON
否
省、市、区三级联动
地址表单、低成本项目
OpenStreetMap
否
OSM 地图、Nominatim 逆地址编码
海外、低频使用、技术验证
混合方案
按服务而定
自动路由、失败降级
对可用性有要求的项目
OpenCage
是
多语言逆地址编码
海外与多语言业务
MapBox
是
地图与地理编码
需要地图样式和全球数据
HERE
是
企业级地理编码
企业与海外业务
自建 Nominatim
否
自主管理 OSM 地理编码
大调用量、强控制需求

四套核心方案

方案一:天地图

项目使用 OpenLayers 加载天地图瓦片,并实现:

  • 经纬度逆地址编码;
  • 影像图、矢量图、地形图切换;
  • 当前坐标标记;
  • H5 地图固定高度 360px;
  • 定位失败后的提示与手动坐标输入。

核心方法:

const result = await tiandituReverseGeocode(116.397470, 39.908823);console.log(result.address);

适合国内业务,但需要在天地图开放平台申请自己的 Key,并确认应用类型、域名和服务权限配置正确。

方案二:不调用地图 API,前端完成省市区选择

如果业务只需要用户填写省、市、区和详细地址,并不要求地图选点,那么调用逆地址编码反而增加了成本和失败点。

项目通过 utils/regionData.js 提供前端 JSON 数据,实现:

  • 省份变化后刷新城市;
  • 城市变化后刷新区县;
  • 区县编码与名称同时保存;
  • 不依赖网络和地图服务。

生产项目建议定期更新行政区划数据,并根据数据量决定采用本地 JSON 还是后端接口。

方案三:OpenStreetMap + Nominatim

方案三由两部分组成:

  • static/osm-map.html:使用 OpenLayers 加载 OSM 瓦片;
  • nominatimReverseGeocode():调用 Nominatim 完成逆地址编码。
const result = await nominatimReverseGeocode(116.397470, 39.908823);console.log(result.address);

公共 Nominatim 实例适合低频测试和轻量场景,不应被当作无上限的企业级免费接口。正式业务需要遵守其使用政策,限制频率、提供有效标识,并在高调用量时使用第三方托管服务或自建实例。

方案四:混合降级

更可靠的架构不是“找到一个永不失败的免费接口”,而是让系统在接口失败时仍然可用:

获取坐标  ├─ 主服务成功 → 返回标准化地址  └─ 主服务失败       ├─ 备用服务成功 → 返回地址并记录降级       └─ 备用服务失败 → 展示省市区手动录入

项目中的混合页支持自动选择与失败降级,可继续扩展:

  • 超时控制;
  • 熔断与重试;
  • 地址结果缓存;
  • 服务调用量统计;
  • 不同国家或地区的服务路由;
  • 坐标系转换与结果标准化。

其他方案:每个方案都有独立示例

OpenCage

  • 页面:pages/opencage/opencage.vue
  • 方法:opencageReverseGeocode(lng, lat)
  • 特点:多语言、全球覆盖、接入简单

MapBox

  • 页面:pages/mapbox/mapbox.vue
  • 方法:mapboxReverseGeocode(lng, lat)
  • 特点:地图样式丰富,适合全球化产品

HERE

  • 页面:pages/here/here.vue
  • 方法:hereReverseGeocode(lng, lat, apiKey)
  • 特点:企业级地图和位置服务

自建 Nominatim

  • 页面:pages/selfhost/selfhost.vue
  • 方法:selfHostedReverseGeocode(lng, lat, baseUrl)
  • 特点:服务自主、可控制调用策略,但需要服务器、数据导入、更新和运维能力

30 秒运行项目

1. 使用 HBuilderX 打开

本项目为 UniApp 示例,可直接用 HBuilderX 打开。

2. 配置自己的 Key

编辑 utils/mapApi.js:

const TIANDITU_KEY = 'YOUR_TIANDITU_KEY';const OPENCAGE_KEY = 'YOUR_OPENCAGE_KEY';const MAPBOX_KEY = 'YOUR_MAPBOX_KEY';

不要把生产 Key 提交到公开仓库。推荐由后端代理第三方 API,或通过安全配置注入,并设置域名、IP、签名和额度限制。

3. 选择运行平台

  • H5:运行到浏览器;
  • 微信小程序:运行到微信开发者工具;
  • App:运行到真机或模拟器。

H5 定位为什么经常失败

浏览器定位失败通常不是 UniApp API 本身的问题,而是浏览器安全策略:

  1. 除 localhost 和 127.0.0.1 外,通常必须使用 HTTPS;
  2. 用户拒绝权限后,需要在地址栏左侧的网站权限中重新允许;
  3. 桌面设备可能没有 GPS,只能依赖网络定位;
  4. VPN、代理、网络环境或系统定位服务可能导致超时;
  5. iframe/web-view 还可能受到 Permissions Policy 限制。

调试时建议优先使用:

http://localhost:端口http://127.0.0.1:端口https://你的域名

详细排查步骤见 LOCATION_PERMISSION_GUIDE.md。

项目结构

mapApp/├── pages/│   ├── index/              # 方案入口│   ├── tianditu/           # 天地图│   ├── region-select/      # 本地省市区│   ├── openstreetmap/      # OpenStreetMap│   ├── hybrid/             # 混合降级│   ├── other/              # 其他方案入口│   ├── opencage/           # OpenCage 示例│   ├── mapbox/             # MapBox 示例│   ├── here/               # HERE 示例│   └── selfhost/           # 自建 Nominatim 示例├── static/│   ├── tianditu-map.html   # OpenLayers + 天地图│   └── osm-map.html        # OpenLayers + OSM├── utils/│   ├── mapApi.js           # 地图服务 API 封装│   └── regionData.js       # 省市区 JSON└── README.md

统一调用示例

import {  getCurrentLocation,  tiandituReverseGeocode,  nominatimReverseGeocode,  selfHostedReverseGeocode} from'@/utils/mapApi.js';const location = await getCurrentLocation();const address = await tiandituReverseGeocode(  location.longitude,  location.latitude);console.log(address);

上线前必须检查的 7 件事

  1. API Key 是否限制了来源域名、IP 和调用额度;
  2. H5 是否部署在 HTTPS 环境;
  3. 是否统一处理 WGS84、GCJ-02、BD-09 等坐标系;
  4. 第三方接口失败后是否有备用方案;
  5. 是否增加缓存、超时、重试、熔断和限流;
  6. 是否遵守地图数据许可、署名和商用条款;
  7. 是否避免在前端公开可滥用的生产密钥。

怎么选,直接抄这个结论

  • 表单填地址:本地省市区 JSON;
  • 国内地图业务:天地图;
  • 海外低频业务:OpenStreetMap / OpenCage;
  • 需要丰富地图样式:MapBox;
  • 企业海外业务:HERE;
  • 核心线上业务:混合降级;
  • 大调用量且有运维能力:自建 Nominatim。

延伸阅读

文档
内容
FIXES.md
各方案修复与配置
H5_FIXES.md
H5 兼容、跨域和定位
LOCATION_PERMISSION_GUIDE.md
定位权限与 HTTPS
MAP_KEY_FIX.md
地图 Key 与定位超时

写在最后

地图服务选型没有绝对的“免费最优解”,只有与业务规模、数据范围、稳定性和团队能力匹配的方案。

这个项目的价值不只是列出几个 API,而是把地图展示、逆地址编码、手动录入和服务降级放在同一个 UniApp 工程里,方便直接对比和二次开发。

如果这个项目对你有帮助,欢迎收藏、分享,并根据自己的业务继续完善缓存、坐标转换、后端代理和监控能力。

体验二维码小程序:

相关学习资料