基于百度地图开放平台的地址距离校验的开发步骤

百度地图开放平台(百度地图-百万开发者首选的地图服务商,提供专属的行业解决方案

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); // 这里如果地址不合法,就会抛出相应的业务异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值