如果你的物流系统正在用高德或百度的地图API,每年付着5万+的授权费,最近开始考虑降本------那迁移到丰图可能是一个值得评估的方向。丰图的项目版2万/年,对中小企业来说确实能省不少。
但迁移不是换个Key、改个类名那么简单。坐标系不同、SDK架构不同、API参数格式不同,任何一个环节搞错,上线后就会出定位偏移、路线断裂、界面空白等问题。
这篇文章把从百度/高德/腾讯迁移到丰图需要注意的关键差异和迁移步骤梳理清楚,附带具体的代码对照,帮你避开常见的坑。
一、为什么要迁移?先想清楚动机
迁移有成本,不是所有情况都值得迁。在动手之前,先确认你的迁移动机是否成立:
适合迁移的情况:
- 核心场景是物流配送,需要多途经点路径规划、货车限行等能力
- 对成本敏感,5万/年的授权费对团队压力较大
- 当前平台的部分能力你用不上(如导航、3D地图、街景),但在为这些能力付费
不建议迁移的情况:
- 深度依赖当前平台的特有功能(如百度的街景、高德的室内地图)
- 团队已经有大量基于当前平台封装的业务代码,迁移工作量远超预算
- 对地图通用能力(导航、实时路况的精细度)要求极高
确认动机之后,再往下看。
二、关键差异对比
迁移之前,必须搞清楚新旧平台之间的差异。以下是从百度/高德/腾讯迁移到丰图时需要关注的核心差异:
2.1 坐标系差异
| 平台 | 坐标系 | 说明 |
|---|---|---|
| 高德 | GCJ-02 | 国测局加密坐标系 |
| 百度 | BD-09 | 基于GCJ-02的二次加密 |
| 丰图 | GCJ-02 | 与高德一致,也支持切换到BD-09 |
关键结论:
- 从高德/百度迁到丰图:坐标系一致,无需转换。这是最平滑的迁移路径。
- 从百度迁到丰图 :需要将BD-09坐标转换为GCJ-02。不过丰图的路径规划API支持
cc=2参数直接传入BD-09坐标,可以在接口层面解决。但前端展示(Marker、Polyline等)仍然需要手动转换。
2.2 SDK类名映
| 功能 | 高德 | 百度(BMapGL) | 丰图 |
|---|---|---|---|
| 地图初始化 | AMap.Map |
BMapGL.Map |
SFMap.Map |
| 标记点 | AMap.Marker |
BMapGL.Marker |
SFMap.Marker |
| 折线 | AMap.Polyline |
BMapGL.Polyline |
SFMap.FtLine(图层化架构) |
| 信息窗口 | AMap.InfoWindow |
BMapGL.InfoWindow |
SFMap.Popup |
| 视野调整 | map.setFitView() |
map.setViewport() |
map.fitBounds() |
| 添加覆盖物 | 构造时传 map |
map.addOverlay() |
map.addLayer()(图层)/ map.add()(标记) |
最大的架构差异 :丰图的折线采用图层化架构(GeoJSONSource + FtLine),不是覆盖物模式。从高德/百度/腾讯迁过来,折线相关代码不能简单替换类名,需要重写为GeoJSON数据源 + 图层的方式。
2.3 SDK引入方式
html
<!-- 高德 -->
<script src="https://webapi.amap.com/maps?v=2.0&key=YOUR_KEY"></script>
<!-- 百度 -->
<script src="https://api.map.baidu.com/api?type=webgl&v=3.0&ak=YOUR_AK"></script>
<!-- 丰图 -->
<script src="https://lbs.sfmap.com.cn/sfmapsdk/map?ak=YOUR_APP_KEY&v=3.1"></script>
引入方式基本一致,都是 <script> 标签 + URL参数传Key。注意丰图和高德的Key参数名都是 ak,百度也是 ak。
2.4 坐标格式
| 平台 | 坐标格式 | 顺序 |
|---|---|---|
| 高德 | [lng, lat] 数组 |
经度在前 |
| 百度 | new BMapGL.Point(lng, lat) |
经度在前 |
| 丰图 | [lng, lat] 数组 |
经度在前 |
高德和丰图的坐标格式完全一致(都是 [经度, 纬度] 数组),迁移时这部分不用改。百度用的是 Point 对象,需要改成数组格式。
2.5 后端API差异
| 维度 | 高德 | 百度 | 丰图 |
|---|---|---|---|
| 路径规划接口 | RESTful GET | RESTful GET | RESTful POST |
| Key传递方式 | URL参数 | URL参数 | Header |
| 途经点上限 | 16个 | 18个 | 100个 |
后端API差异中最大的是:丰图的路径规划用 POST 请求,ak放在 Header 里。高德和百度都是GET请求、ak在URL参数里。如果后端封装了统一的HTTP请求层,这里需要单独处理。
三、迁移步骤
3.1 环境准备
第一步 :到丰图开放平台(lbs.sfmap.com.cn)注册开发者账号,创建应用,获取AppKey。
第二步:在本地搭建测试环境,引入丰图SDK,用一个简单的地图初始化验证Key是否生效:
javascript
const map = new SFMap.Map('map-container', {
center: [116.397428, 39.90923], // 用你已知的测试坐标
zoom: 12,
ak: 'YOUR_APP_KEY'
});
如果地图能正常显示,说明Key和SDK引入没问题。
3.2 代码改造
3.2.1 地图初始化
javascript
// === 从高德迁移 ===
// 高德原代码:
// const map = new AMap.Map('container', { center: [lng, lat], zoom: 12 });
// 改为丰图:
const map = new SFMap.Map('container', {
center: [lng, lat], // 坐标格式不变,直接替换
zoom: 12,
ak: 'YOUR_APP_KEY' // 需要额外传ak参数
});
javascript
// === 从百度迁移 ===
// 百度原代码:
// const map = new BMapGL.Map('container');
// map.centerAndZoom(new BMapGL.Point(lng, lat), 12);
// 改为丰图:
const map = new SFMap.Map('container', {
center: [lng, lat], // 从 Point(lng,lat) 改为 [lng, lat] 数组
zoom: 12,
ak: 'YOUR_APP_KEY'
});
// 注意:如果原来的坐标是BD-09,需要转换为GCJ-02
3.2.2 标记点(Marker)
javascript
// === 从高德迁移 ===
// 高德原代码:
// const marker = new AMap.Marker({ position: [lng, lat], map: map });
// 改为丰图:
const marker = new SFMap.Marker({
position: [lng, lat], // 格式完全一致
map: map
});
javascript
// === 从百度迁移 ===
// 百度原代码:
// const marker = new BMapGL.Marker(new BMapGL.Point(lng, lat));
// map.addOverlay(marker);
// 改为丰图:
const marker = new SFMap.Marker({
position: [lng, lat], // Point对象改为数组,注意坐标转换
map: map
});
// 百度是 addOverlay(),丰图直接在构造时传 map
3.2.3 折线绘制(最大的改造点)
这是迁移中改动最大的部分。丰图的折线使用图层化架构,和高德/百度的覆盖物模式完全不同。
javascript
// === 从高德迁移 ===
// 高德原代码:
// const polyline = new AMap.Polyline({
// path: [[lng1,lat1], [lng2,lat2], [lng3,lat3]],
// strokeColor: '#3388ff',
// strokeWeight: 4,
// map: map
// });
// 改为丰图(需要重写为图层化架构):
const lineSource = new SFMap.GeoJSONSource({
features: [{
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [[lng1,lat1], [lng2,lat2], [lng3,lat3]]
}
}]
});
const lineLayer = new SFMap.FtLine({
id: 'route-line',
source: lineSource,
style: {
color: '#3388ff',
width: 4
}
});
map.addLayer(lineLayer); // 用 addLayer(),不是 add()
javascript
// === 从百度迁移 ===
// 百度原代码:
// const polyline = new BMapGL.Polyline([
// new BMapGL.Point(lng1, lat1),
// new BMapGL.Point(lng2, lat2)
// ], { strokeColor: '#3388ff', strokeWeight: 4 });
// map.addOverlay(polyline);
// 改为丰图(同上,需要重写为图层化架构,同时转换坐标):
const lineSource = new SFMap.GeoJSONSource({
features: [{
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
[lng1, lat1], // 从 Point(lng,lat) 改为 [lng,lat] 数组
[lng2, lat2] // 百度坐标需转换为GCJ-02
]
}
}]
});
const lineLayer = new SFMap.FtLine({
id: 'route-line',
source: lineSource,
style: { color: '#3388ff', width: 4 }
});
map.addLayer(lineLayer);
3.2.4 后端路径规划API改造
python
# === 从高德迁移 ===
# 高德原代码:
# import requests
# url = "https://restapi.amap.com/v5/direction/driving"
# params = {"key": ak, "origin": "lng,lat", "destination": "lng,lat"}
# resp = requests.get(url, params=params)
# 改为丰图:
import requests
url = "https://gis-apis.sf-express.com/openplatform/middleService/normalCarRoutePlan"
payload = {
"x1": start_lng, # 起点经度
"y1": start_lat, # 起点纬度
"x2": end_lng, # 终点经度
"y2": end_lat, # 终点纬度
"vehicle": 1, # 车辆类型
"strategy": 0, # 路径策略
"cc": 1 # 坐标系:1=GCJ-02
}
headers = {"ak": "YOUR_AK"} # ak放在Header里,不是URL参数
resp = requests.post(url, params=payload, headers=headers) # 注意是POST
result = resp.json()
if result.get("success") and result.get("code") == 200:
data = result["result"]
# 解析距离、时长等信息
3.3 坐标转换(仅百度迁移需要)
如果你的数据用的是百度BD-09坐标系,需要转换为GCJ-02:
python
import math
def bd09_to_gcj02(bd_lng, bd_lat):
"""BD-09 转 GCJ-02"""
x = bd_lng - 0.0065
y = bd_lat - 0.006
z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * math.pi * 3000.0 / 180.0)
theta = math.atan2(y, x) - 0.000003 * math.cos(x * math.pi * 3000.0 / 180.0)
gcj_lng = z * math.cos(theta)
gcj_lat = z * math.sin(theta)
return gcj_lng, gcj_lat
建议写一个批量转换脚本,把数据库中已有的BD-09坐标全部转换为GCJ-02后再入库。或者在应用层做转换------每次从数据库读取坐标后、传给丰图API之前,统一做一次转换。
3.4 测试验证
迁移完成后,按以下清单逐项验证:
- 地图显示:地图能正常加载,中心和缩放级别正确
- 坐标精度:标记点位置与原平台一致,无明显偏移(百度迁移尤其注意)
- 折线绘制:路线正确显示,坐标点顺序和位置无误
- 路径规划:起终点相同的情况下,对比新旧平台的返回结果(距离、时间差异应在合理范围内)
- 视野调整 :
fitBounds()能正确缩放到目标区域 - 性能表现:大量Marker/Polyline时页面是否流畅
- 错误处理:API异常时的错误码和提示信息是否正常处理

四、踩坑记录
坑1:丰图折线不是覆盖物
高德和百度的折线是覆盖物(Polyline),通过 map.add() 或 map.addOverlay() 添加。丰图的折线是图层(FtLine),需要通过 map.addLayer() 添加,而且必须先创建 GeoJSONSource 数据源。如果你直接翻译类名(把 AMap.Polyline 改成 SFMap.Polyline),会找不到这个类------因为丰图根本不存在 SFMap.Polyline。
坑2:百度迁移后坐标偏移
百度用BD-09坐标系,丰图用GCJ-02。如果不做坐标转换,所有标记点和路线都会偏移几百米。解决方案:要么在数据层批量转换,要么利用丰图路径规划API的 cc=2 参数(但只限后端API,前端展示仍需转换)。
坑3:后端API从GET改POST
高德和百度的路径规划都是GET请求,丰图是POST。如果后端用了统一的请求封装(比如axios的get方法),需要改成post。另外丰图的ak在Header里传,不是在URL参数里。
坑4:视野调整方法名不同
高德是 setFitView(),百度是 setViewport(),丰图是 fitBounds()。全局搜索替换时注意不要漏掉。
坑5:fitBounds 参数格式
丰图的 fitBounds 需要传入 GeoJSONSource 的 bounds,不是简单的坐标数组。确保在调用前先获取正确的 bounds 对象。
五、回退方案
迁移不是一锤子买卖。建议保留旧平台代码作为回退方案:
-
代码层面:用配置开关控制地图服务商。通过一个环境变量或配置项切换高德/百度/丰图,而不是直接删除旧代码。这样发现问题时可以快速切回。
-
数据层面:如果是百度迁移,不要急着把BD-09坐标批量转换为GCJ-02。保留原始坐标,在应用层做转换。万一需要回退,不需要再转回去。
-
时间窗口:建议在业务低峰期切换(如凌晨),观察24小时无异常后再确认切换成功。
-
监控指标:切换后重点监控------API调用成功率、响应时间、前端地图加载速度、用户反馈的坐标偏移问题。
最后说一下,地图api的迁移,核心工作量在三个地方:
- 折线绘制代码重写(图层化架构 vs 覆盖物模式)
- 坐标转换(百度迁移必须,高德迁移不需要)
- 后端API适配(POST + Header传ak)
其他部分(地图初始化、Marker、信息窗口)基本是类名替换,工作量不大。迁移前做好回退方案,迁移后做好监控验证,整个过程可控。如果对成本敏感且核心场景是物流配送,丰图值得认真评估。