乐于分享
好东西不私藏

地图 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.39747039.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.39747039.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,  selfHostedReverseGeocodefrom'@/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 工程里,方便直接对比和二次开发。

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

体验二维码小程序: