百度地图开放平台(百度地图-百万开发者首选的地图服务商,提供专属的行业解决方案)
1.环境配置
1.1.左上角注册/登录---控制台
1.2.应用管理-我的应用-创建应用
1.3.填写配置
1.4.复制(记录)AK,用于后续调用接口的参数传递
1.5.配置application.yml和application-dev.yml,把4中复制的ak写入
application-yml:
applicaiton-dev.yml:
2.代码编写
2.1 OrderServiceImpl 新增成员变量及方法
2.1.1 添加成员变量
@Value("${sky.shop.address}")
private String shopAddress ;
@Value("${sky.baidu.ak}")
private String ak ;
public static final String SHOP_ADDRESS_PARSE_FAILED = "商铺地址解析失败" ;
public static final String USER_ADDRESS_PARSE_FAILED = "用户地址解析失败" ;
public static final String USER_ADDRESS_OUT_OF_RANGE = "用户地址超出配送范围" ;
2.1.2 新增地址校验函数 checkAddressIsAvailable
/**
* 基于百度开放平台
* 优化用户下单功能,加入校验逻辑
* 如果用户的收货地址距离商家门店超出配送范围(配送范围为5公里内),则下单失败。
* @param address 用户地址
*/
private void checkAddressIsAvailable(String address) {
// 1.处理店铺地址
// 封装请求参数
// API服务请求的示例:https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation //GET请求
Map paramMap = new HashMap<>() ;
paramMap.put("address", shopAddress) ;
paramMap.put("output", "json") ;
paramMap.put("ak", ak) ;
// 发送请求,调用将地址转成对应的经纬度的接口
String shopRespStr = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", paramMap);
// 将JSON字符串映射成JSON对象
JSONObject shopJsonObject = JSONObject.parseObject(shopRespStr);
if (!"0".equals(shopJsonObject.getString("status"))) { // 本次API访问状态,如果成功返回0,如果失败返回其他数字
throw new OrderBusinessException(SHOP_ADDRESS_PARSE_FAILED) ;
}
JSONObject shopLocation = shopJsonObject.getJSONObject("result").getJSONObject("location");
StringBuilder sb = new StringBuilder() ;
// 维度
sb.append(toSixDecimalPlaces(shopLocation.getString("lat"))).append(",") ;
// 精度
sb.append(toSixDecimalPlaces(shopLocation.getString("lng")));
// 店铺地址经纬度坐标
String shopCoordinate = sb.toString() ;
// 2.处理用户地址
paramMap.put("address", address) ;
String userRespStr = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", paramMap);
JSONObject userJsonObject = JSONObject.parseObject(userRespStr);
if (!"0".equals(userJsonObject.getString("status"))) { // 本次API访问状态,如果成功返回0,如果失败返回其他数字
throw new OrderBusinessException(USER_ADDRESS_PARSE_FAILED) ;
}
JSONObject userLocation = userJsonObject.getJSONObject("result") // 返回的结果
.getJSONObject("location");// 经纬度坐标
sb.setLength(0); // 清空StringBuffer原有内容
// 维度 小数点后不超过6位 --> 编写toSixDecimalPlaces函数
sb.append(toSixDecimalPlaces(userLocation.getString("lat"))).append(",") ;
// 精度
sb.append(toSixDecimalPlaces(userLocation.getString("lng"))) ;
// 用户地址经纬度坐标
String userCoordinate = sb.toString() ;
// 3.调用接口计算两点间的距离,这里使用的是骑行接口计算距离
// 封装接口所需参数
paramMap.clear(); // 清空map原有内容
paramMap.put("origin", shopCoordinate) ;
paramMap.put("destination", userCoordinate) ;
paramMap.put("ak", ak) ;
String distRespStr = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/riding", paramMap);
JSONObject distJsonObject = JSONObject.parseObject(distRespStr);
if (!"0".equals(distJsonObject.getString("status"))) {
throw new OrderBusinessException("配送路线规划失败") ;
}
/*
String distStr = distJsonObject.getJSONObject("result")
.getJSONObject("routes") // 返回的方案集 是个JSONArray
.getString("distance");
// 所以会报错 ClassCastException: class com.alibaba.fastjson.JSONArray cannot be cast to class com.alibaba.fastjson.JSONObject (com.alibaba.fastjson.JSONArray and com.alibaba.fastjson.JSONObject are in unnamed module of loader 'app')
*/
JSONArray jsonArray = (JSONArray) distJsonObject.getJSONObject("result").get("routes") ;
// routes是一个数组
// 参考https://lbs.baidu.com/faq/api?title=webapi/guide/webservice-lwrouteplanapi/cycling 里面的JSON示例
String distStr = ((JSONObject)jsonArray.get(0)).getString("distance") ;
int distance = Integer.parseInt(distStr);
if (distance > 5000) { // 如果大于5公里就抛出业务异常
throw new OrderBusinessException(USER_ADDRESS_OUT_OF_RANGE) ;
}
}`
toSixDecimalPlaces 函数
/**
* 转为6位小数
* @param resouce
* @return
*/
private String toSixDecimalPlaces(String resouce) {
double number = Double.parseDouble(resouce); // 将字符串转换为double
DecimalFormat df = new DecimalFormat("#.######"); // 创建DecimalFormat对象,保留6位小数
return df.format(number); // 格式化数字
}
2.2 OrderServiceImpl 修改订单提交函数 submit
// 判断地址是否超出配送范围
StringBuilder sb = new StringBuilder() ;
String userAddr = sb.append(addressBook.getProvinceName())
.append(addressBook.getCityName())
.append(addressBook.getDistrictName())
.append(addressBook.getDetail())
.toString() ;
checkAddressIsAvailable(userAddr); // 这里如果地址不合法,就会抛出相应的业务异常