package com.ruoyi.common.core.utils; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.ruoyi.common.core.domain.Result; import com.ruoyi.common.core.enums.GaoDeEnum; import com.ruoyi.common.core.exception.GlobalException; import com.ruoyi.common.core.vo.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * @author HJL */ public class GaoDeMapUtil { /** * 功能描述: 高德地图Key */ private static final String GAO_DE_KEY = "37331f325a4f4ea25bc0d4e1900a1730"; /** * 功能描述: 根据地址名称得到两个地址间的距离 * * @param start 起始位置 * @param end 结束位置 * @return long 两个地址间的距离 */ public static Long getDistanceByAddress(String start, String end) { String startLonLat = getLonLat(start).getDatas(); String endLonLat = getLonLat(end).getDatas(); return Long.valueOf(getDistance(startLonLat, endLonLat).getDatas().toString()); } /** * 功能描述: 地址转换为经纬度 * * @param address 地址 * @return 经纬度 */ public static Result getLonLat(String address) { try { // 返回输入地址address的经纬度信息, 格式是 经度,纬度 String queryUrl = "http://restapi.amap.com/v3/geocode/geo?key=" + GAO_DE_KEY + "&address=" + address; // 高德接口返回的是JSON格式的字符串 String queryResult = getResponse(queryUrl); JSONObject job = JSONObject.parseObject(queryResult); JSONObject json = JSONObject .parseObject( job.get("geocodes").toString().substring(1, job.get("geocodes").toString().length() - 1)); String lngAndLat = json.get("location").toString(); return Result.succeed(lngAndLat, "经纬度转换成功!"); } catch (Exception e) { return Result.failed(e.toString()); } } /** * 将经纬度 转换为 地址 * * @param longitude 经度 * @param latitude 纬度 * @return 地址名称 */ public static Result getAddress(String longitude, String latitude) { String url; try { url = "http://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + longitude + "," + latitude + "&key=" + GAO_DE_KEY + "&radius=0&extensions=base"; // 高德接口返回的是JSON格式的字符串 String queryResult = getResponse(url); if (ObjectUtils.isNull(queryResult)) { return Result.failed("查询结果为空"); } // 将获取结果转为json 数据 JSONObject obj = JSONObject.parseObject(queryResult); if (obj.get(GaoDeEnum.STATUS.getCode()).toString().equals(GaoDeEnum.INT_ONE.getCode())) { // 如果没有返回-1 JSONObject reGeoCode = obj.getJSONObject(GaoDeEnum.RE_GEO_CODE.getCode()); if (reGeoCode.size() > 0) { // 在regeocode中拿到 formatted_address 具体位置 String formatted = reGeoCode.get("formatted_address").toString(); JSONObject addressComponent = reGeoCode.getJSONObject("addressComponent"); String adcode = addressComponent.getString("adcode"); String s = convertToCityCode(adcode); System.err.println("====s"); return Result.succeed(formatted, "地址获取成功!"); } else { return Result.failed("未找到相匹配的地址!"); } } else { return Result.failed("请求错误!"); } } catch (Exception e) { e.printStackTrace(); return Result.failed("系统未知异常,请稍后再试"); } } public static Result getCityCode(String longitude, String latitude) { String url; try { url = "http://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + longitude + "," + latitude + "&key=" + GAO_DE_KEY + "&radius=0&extensions=base"; // 高德接口返回的是JSON格式的字符串 String queryResult = getResponse(url); if (ObjectUtils.isNull(queryResult)) { return Result.failed("查询结果为空"); } // 将获取结果转为json 数据 JSONObject obj = JSONObject.parseObject(queryResult); if (obj.get(GaoDeEnum.STATUS.getCode()).toString().equals(GaoDeEnum.INT_ONE.getCode())) { // 如果没有返回-1 JSONObject reGeoCode = obj.getJSONObject(GaoDeEnum.RE_GEO_CODE.getCode()); if (reGeoCode.size() > 0) { // 在regeocode中拿到 formatted_address 具体位置 String formatted = reGeoCode.get("formatted_address").toString(); JSONObject addressComponent = reGeoCode.getJSONObject("addressComponent"); String adcode = addressComponent.getString("adcode"); String s = convertToCityCode(adcode); System.err.println("====s"); return Result.succeed(s, "地址获取成功!"); } else { return Result.failed("未找到相匹配的地址!"); } } else { return Result.failed("请求错误!"); } } catch (Exception e) { e.printStackTrace(); return Result.failed("系统未知异常,请稍后再试"); } } public static String convertToCityCode(String districtCode) { // 确保输入的字符串长度至少为6位 if (districtCode.length() >= 6) { // 截取前6位中的前4位作为城市代码 return districtCode.substring(0, 4) + "00"; } else { throw new IllegalArgumentException("Invalid district code length: " + districtCode); } } /** * 功能描述: 根据两个定位点的经纬度算出两点间的距离 * 经纬度格式为: 经度,纬度 * * @param startLonLat 起始经纬度 * @param endLonLat 结束经纬度(目标经纬度) * @return 两个定位点之间的距离 */ public static Result getDistance(String startLonLat, String endLonLat) { // 返回起始地startAddr与目的地endAddr之间的距离,单位:米 String queryUrl = "http://restapi.amap.com/v3/distance?key=" + GAO_DE_KEY + "&origins=" + startLonLat + "&destination=" + endLonLat; String queryResult = getResponse(queryUrl); JSONObject job = JSONObject.parseObject(queryResult); JSONArray ja = job.getJSONArray("results"); JSONObject jobO = JSONObject.parseObject(ja.getString(0)); long result = Long.parseLong(jobO.get("distance").toString()); return Result.succeed(result, "距离计算成功!"); } /** * 功能描述: 根据地址获取城市code * * @param address d地址 * @return 两个定位点之间的距离 */ public static Result getAddressInfo(String address) { // 返回起始地startAddr与目的地endAddr之间的距离,单位:米 String queryUrl = "https://restapi.amap.com/v3/geocode/geo?address=" + address + "&key=" + GAO_DE_KEY; String queryResult = getResponse(queryUrl); GaoDeAddressInfoVO data = JSONObject.parseObject(queryResult, GaoDeAddressInfoVO.class); List geocodes = data.getGeocodes(); Geocodes info = geocodes.get(0); String adcode = info.getAdcode(); String city = info.getCity(); return Result.succeed(new CityInfoVO(city, adcode), "距离计算成功!"); } /** * 功能描述: 发送请求 * * @param serverUrl 请求地址 * @return 请求结果 */ private static String getResponse(String serverUrl) { // 用JAVA发起http请求,并返回json格式的结果 StringBuilder result = new StringBuilder(); try { URL url = new URL(serverUrl); URLConnection conn = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result.append(line); } in.close(); } catch (IOException e) { e.printStackTrace(); } return result.toString(); } /** * 从出发地触发到目的地路线规划 * * @param origin 出发地经纬度 * @param destination 目的地经纬度 * @return 路线规划信息 */ public static Path routing(String origin, String destination) { String baseUrl = "https://restapi.amap.com/v3/direction/driving?origin=%s&destination=%s" + "&extensions=all&output=json&key=%s"; String requestUrl = String.format(baseUrl, origin, destination, GAO_DE_KEY); StringBuilder json = new StringBuilder(); try { URL url = new URL(requestUrl); URLConnection urlConnection = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8)); String inputLine; while ((inputLine = in.readLine()) != null) { json.append(inputLine); } in.close(); } catch (IOException e) { throw new GlobalException("获取路线规划失败!"); } String data = json.toString(); GaoDeMap gaoDeMap = JSONObject.parseObject(data, GaoDeMap.class); Path path = gaoDeMap.getRoute().getPaths().get(0); List steps = path.getSteps(); for (Steps step : steps) { // 经纬度地址指向 List polylineDataList = new ArrayList<>(); String polyline = step.getPolyline(); List list = Arrays.stream(polyline.split(";")).collect(Collectors.toList()); for (String s : list) { String[] split = s.split(","); // 经纬度 String longitude = split[0]; String latitude = split[1]; polylineDataList.add(new PolylineData(longitude, latitude)); } step.setPolylineList(polylineDataList); } return path; } }