实现了百度地图的两个核心距离计算功能:
1. 计算两个坐标之间的距离 - 直接使用经纬度坐标计算驾车距离
2. 计算两个地址之间的距离 - 先将地址转换为坐标,再计算距离
在 ruoyi-admin/src/main/resources/application.yml 中配置:
# 百度地图配置
baidu:
map:
ak: YOUR_BAIDU_MAP_AK_HERE # 请替换为您的百度地图API Key
获取API Key步骤:
1. 访问百度地图开放平台: https://lbsyun.baidu.com/
2. 注册/登录账号
3. 进入控制台 -> 应用管理 -> 我的应用
4. 创建应用,选择"服务端"类型
5. 获取 AK (Access Key)
com.ruoyi.common.config.BaiduMapConfigcom.ruoyi.web.controller.system.VehicleGpsControllerapp/api/map.js接口地址: /system/gps/baidu/route/driving
请求方式: GET
请求参数:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| origin | String | 是 | 起点坐标(纬度,经度) | 40.056878,116.30815 |
| destination | String | 是 | 终点坐标(纬度,经度) | 31.222965,121.505821 |
请求示例: GET /system/gps/baidu/route/driving?origin=40.056878,116.30815&destination=31.222965,121.505821
响应示例:json { "code": 200, "msg": "计算成功", "data": { "status": 0, "message": "ok", "result": { "routes": [{ "distance": 1213000, // 距离(米) "duration": 43920, // 时间(秒) "steps": [...] }] } } }
import { baiduRouteDriving } from '@/api/map'
// 调用示例
baiduRouteDriving('40.056878,116.30815', '31.222965,121.505821')
.then(response => {
console.log('距离计算结果:', response)
// 解析返回数据
const result = JSON.parse(response.data)
if (result.status === 0) {
const distance = result.result.routes[0].distance // 距离(米)
const distanceKm = (distance / 1000).toFixed(2) // 转换为公里
console.log('行驶距离:', distanceKm + ' 公里')
}
})
.catch(error => {
console.error('距离计算失败:', error)
})
接口地址: /system/gps/baidu/geocoding
请求方式: GET
请求参数:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| address | String | 是 | 待解析的地址 | 广州市天河区天河路 |
| city | String | 否 | 地址所在城市 | 广州市 |
请求示例: GET /system/gps/baidu/geocoding?address=广州市天河区天河路&city=广州市
响应示例:json { "code": 200, "msg": "查询成功", "data": { "status": 0, "result": { "location": { "lng": 113.331053, // 经度 "lat": 23.137883 // 纬度 }, "precise": 1, "confidence": 80, "comprehension": 100, "level": "道路" } } }
import { baiduGeocoding } from '@/api/map'
// 调用示例
baiduGeocoding('广州市天河区天河路', '广州市')
.then(response => {
console.log('地理编码结果:', response)
const result = JSON.parse(response.data)
if (result.status === 0) {
const lng = result.result.location.lng // 经度
const lat = result.result.location.lat // 纬度
console.log('坐标:', lat + ',' + lng)
}
})
.catch(error => {
console.error('地理编码失败:', error)
})
接口地址: /system/gps/baidu/distance/byAddress
请求方式: GET
请求参数:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| fromAddress | String | 是 | 起点地址 | 广州市天河区天河路 |
| fromCity | String | 否 | 起点所在城市 | 广州市 |
| toAddress | String | 是 | 终点地址 | 广州市越秀区中山路 |
| toCity | String | 否 | 终点所在城市 | 广州市 |
请求示例: GET /system/gps/baidu/distance/byAddress?fromAddress=广州市天河区天河路&fromCity=广州市&toAddress=广州市越秀区中山路&toCity=广州市
响应示例:json { "code": 200, "msg": "地理编码成功", "data": { "fromGeocoding": "{...}", // 起点地理编码结果 "toGeocoding": "{...}", // 终点地理编码结果 "message": "请解析坐标后调用 /baidu/route/driving 接口计算距离" } }
import { baiduDistanceByAddress, baiduRouteDriving } from '@/api/map'
/**
* 计算两个地址之间的驾车距离
*/
async function calculateAddressDistance(fromAddr, fromCity, toAddr, toCity) {
try {
// 第一步: 获取两个地址的坐标
const geocodingResult = await baiduDistanceByAddress(fromAddr, fromCity, toAddr, toCity)
// 解析起点坐标
const fromGeo = JSON.parse(geocodingResult.data.fromGeocoding)
if (fromGeo.status !== 0) {
throw new Error('起点地址解析失败')
}
const fromLat = fromGeo.result.location.lat
const fromLng = fromGeo.result.location.lng
// 解析终点坐标
const toGeo = JSON.parse(geocodingResult.data.toGeocoding)
if (toGeo.status !== 0) {
throw new Error('终点地址解析失败')
}
const toLat = toGeo.result.location.lat
const toLng = toGeo.result.location.lng
// 第二步: 计算两点间距离
const origin = fromLat + ',' + fromLng
const destination = toLat + ',' + toLng
const routeResult = await baiduRouteDriving(origin, destination)
// 解析距离
const route = JSON.parse(routeResult.data)
if (route.status === 0) {
const distance = route.result.routes[0].distance // 距离(米)
const distanceKm = (distance / 1000).toFixed(2) // 转换为公里
console.log('行驶距离:', distanceKm + ' 公里')
return distanceKm
} else {
throw new Error('距离计算失败')
}
} catch (error) {
console.error('计算地址距离失败:', error)
throw error
}
}
// 使用示例
calculateAddressDistance(
'广州市天河区天河路', '广州市',
'广州市越秀区中山路', '广州市'
).then(distance => {
console.log('最终距离:', distance + ' 公里')
})
在创建急救转运任务时,根据起点和终点地址自动计算行驶距离:
// 在任务表单中监听地址变化
watch(['startAddress', 'endAddress'], async () => {
if (startAddress && endAddress) {
try {
const distance = await calculateAddressDistance(
startAddress, startCity,
endAddress, endCity
)
// 自动填充距离字段
form.distance = distance
} catch (error) {
console.error('自动计算距离失败', error)
}
}
})
用户在地图上选择起点和终点后,自动计算距离:
// 地图选点回调
onMapPointSelected(point) {
if (point.type === 'start') {
this.startLat = point.lat
this.startLng = point.lng
} else {
this.endLat = point.lat
this.endLng = point.lng
}
// 两个点都选择后计算距离
if (this.startLat && this.endLat) {
const origin = this.startLat + ',' + this.startLng
const destination = this.endLat + ',' + this.endLng
baiduRouteDriving(origin, destination).then(res => {
const result = JSON.parse(res.data)
if (result.status === 0) {
const distance = (result.result.routes[0].distance / 1000).toFixed(2)
this.form.distance = distance
}
})
}
}
"纬度,经度"百度地图API返回的状态码说明:
- status: 0 - 成功
- status: 1 - 服务器内部错误
- status: 2 - 请求参数非法
- status: 3 - 权限校验失败
- status: 4 - 配额校验失败
- status: 5 - AK不存在或非法
distanceKm = distance / 1000| 功能 | 百度地图 | 腾讯地图 |
|---|---|---|
| 坐标系 | BD-09 | GCJ-02 |
| 地理编码 | /geocoding/v3/ | /geocoder/v1/ |
| 路线规划 | /directionlite/v1/driving | /distance/v1/ |
| 参数格式 | origin=lat,lng | from=lat,lng |
| 免费配额 | 10万次/天 | 10万次/天 |
建议创建测试用例验证接口功能:
@Test
public void testBaiduRouteDriving() {
// 北京到上海的距离
String origin = "40.056878,116.30815";
String destination = "31.222965,121.505821";
AjaxResult result = controller.baiduRouteDriving(origin, destination);
assertEquals(200, result.get("code"));
}
使用 Postman 或浏览器测试:
GET http://localhost:8080/system/gps/baidu/route/driving?origin=40.056878,116.30815&destination=31.222965,121.505821
在浏览器控制台测试:
import { baiduRouteDriving } from '@/api/map'
baiduRouteDriving('40.056878,116.30815', '31.222965,121.505821')
.then(res => console.log(res))
.catch(err => console.error(err))
原因: API Key 配置错误或未授权该接口
解决方案:
1. 检查 application.yml 中的 AK 是否正确
2. 登录百度地图控制台,检查应用是否启用了对应服务
3. 确认IP白名单设置(如有)
原因: 可能是坐标系不匹配
解决方案:
1. 确认输入坐标是百度坐标系(BD-09)
2. 如是其他坐标系,需先进行坐标转换
3. 检查坐标顺序是否正确(纬度,经度)
原因: 地址不够准确或格式不规范
解决方案:
1. 提供更详细的地址信息
2. 指定所在城市参数
3. 使用标准地址格式
可以扩展接口支持步行、骑行、公交等:
@GetMapping("/baidu/route/{mode}")
public AjaxResult baiduRoute(@PathVariable String mode, String origin, String destination) {
// mode: driving(驾车), walking(步行), riding(骑行), transit(公交)
String url = "https://api.map.baidu.com/directionlite/v1/" + mode;
// ...
}
除了距离,还可以返回路径详情、途经点等:
// 解析完整路线信息
const route = result.result.routes[0]
console.log('距离:', route.distance, '米')
console.log('预计时间:', route.duration, '秒')
console.log('路线详情:', route.steps)
如需计算多个地点间的距离,可以使用批量接口:
@PostMapping("/baidu/route/batch")
public AjaxResult baiduRouteBatch(@RequestBody List<RouteRequest> requests) {
// 批量计算多个路线的距离
}
开发者: AI Assistant
文档创建时间: 2025-10-21
最后更新时间: 2025-10-21