今日学习的内容是百度地图的使用,记录备用====
百度地图api的使用,使用的目的是通过中文地址转换为地图上的经纬度,同时通过两地的经纬度获取两地的距离,此项目为外卖项目,用于判断用户的下单地址和店铺的地址距离不能超过限制距离
获取百度地图的ak
先进入百度地图开发的控制台
进入之后选择填写自己需要的内容,这边的ip白名单如果没有的话,可以去百度上找对应的ip白名单,也可以直接输入0.0.0.0/0 谨慎使用 注册成功后就可以得到ak
代码开发,第一种相对比较好理解的方法
首先通过百度地图的ak和传入的address获取该地址的经纬度,本项目是在springboot的框架中完成的项目,所以可以先将自己的ak和店铺的地址存入到yml配置文件,再通过@value注解直接获得对应的数据
也可以通过直接 String ak = ***** ; 直接写入
接下来是通过解析中文地址获取经纬度
private Map<String, Double> getAddress(String address) {
//获取地址的url
String httpUrl = "http://api.map.baidu.com/geocoding/v3/?address=" + address + "&output=json&ak=" + ak;
StringBuilder json = new StringBuilder();
try {
URL url = new URL(httpUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String inputLine = null;
while ((inputLine = in.readLine()) != null) {
json.append(inputLine);
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
String data = json.toString();
if (data != null && !"".equals(data)) {
Map map = JSON.parseObject(data, Map.class);
if ("0".equals(map.getOrDefault("status", "500").toString())) {
Map childMap = (Map) map.get("result");
Map posMap = (Map) childMap.get("location");
// 经度
double lng = Double.parseDouble(posMap.getOrDefault("lng", "0").toString());
// 纬度
double lat = Double.parseDouble(posMap.getOrDefault("lat", "0").toString());
Map<String, Double> addressMap = new HashMap<>();
addressMap.put("lng", lng);
addressMap.put("lat", lat);
return addressMap;
}
}
return null;
}
这段代码是面向百度开发的,我也小小整理了一下,可以直接拿过去使用,通过传入的中文地址获得经纬度,再通过两次调用,分别传入店铺的地址和用户的地址获得分别记录两个地址的经纬度的map集合,再通过map中的get() 得到对应的经度和纬度, 直接通过三角函数相关知识就可以获得距离信息
//校验用户的地址信息 获取店铺的经纬度
Map<String, Double> shopAddress = getAddress(this.shopAddress);
//用户当前地址的经纬度 == 用户的城市名称 + 区名称 + 详细地址
Map<String, Double> userAddress = getAddress(addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail());
//店铺和用户的经纬度
Double shopLng = shopAddress.get("lng");
Double shopLat = shopAddress.get("lat");
Double userLng = userAddress.get("lng");
Double userLat = userAddress.get("lat");
//经纬度之差
Double diffLng = shopLng - userLng;
Double diffLat = shopLat - userLat;
//每经度单位米
double jl_jd = 102834.74258026089786013677476285;
//每纬度单位米
double jl_wd = 111712.69150641055729984301412873;
double b = Math.abs(diffLat * jl_jd);
double a = Math.abs(diffLng * jl_wd);
Double distance = Math.sqrt((a * a + b * b));
//判断距离是否超过5km
if (distance > MAX_DISTANCE) {
throw new OrderBusinessException("超出配送范围");
}
第二种方法: 也是解析中文地址转换为经纬度,再通过路线规划的距离来判断是否超过限制
private void checkOutOfRange(String address) {
//店铺地址信息map
Map map = new HashMap();
map.put("address", shopAddress);
map.put("output", "json");
map.put("ak", ak);
//获取店铺的经纬度坐标
String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);
JSONObject jsonObject = JSON.parseObject(shopCoordinate);
if (!jsonObject.getString("status").equals("0")) {
throw new OrderBusinessException("店铺地址解析失败");
}
//数据解析
JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
String lat = location.getString("lat");
String lng = location.getString("lng");
//店铺经纬度坐标
String shopLngLat = lat + "," + lng;
map.put("address", address);
//获取用户收货地址的经纬度坐标
String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);
jsonObject = JSON.parseObject(userCoordinate);
if (!jsonObject.getString("status").equals("0")) {
throw new OrderBusinessException("收货地址解析失败");
}
//数据解析
location = jsonObject.getJSONObject("result").getJSONObject("location");
lat = location.getString("lat");
lng = location.getString("lng");
//用户收货地址经纬度坐标
String userLngLat = lat + "," + lng;
map.put("origin", shopLngLat);
map.put("destination", userLngLat);
map.put("steps_info", "0");
//路线规划
String json = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map);
jsonObject = JSON.parseObject(json);
if (!jsonObject.getString("status").equals("0")) {
throw new OrderBusinessException("配送路线规划失败");
}
//数据解析
JSONObject result = jsonObject.getJSONObject("result");
JSONArray jsonArray = (JSONArray) result.get("routes");
Integer distance = (Integer) ((JSONObject) jsonArray.get(0)).get("distance");
if (distance > 5000) {
//配送距离超过5000米
throw new OrderBusinessException("超出配送范围");
}
}
这段调用时直接传入用户地址就可以判断
checkOutOfRange(addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail());