| | |
| | | package com.doumee.core.utils.geocode; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.doumee.core.utils.Http; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | |
| | | /** 逆地理解析 */ |
| | | private static final String GEO_URL = "https://restapi.amap.com/v3/geocode/regeo"; |
| | | |
| | | /** 正向地理解析 */ |
| | | private static final String GEOCODE_URL = "https://restapi.amap.com/v3/geocode/geo"; |
| | | |
| | | /** 驾车路径规划 */ |
| | | private static final String DRIVING_URL = "https://restapi.amap.com/v3/direction/driving"; |
| | | |
| | |
| | | @Value("${geocode_map_key:}") |
| | | public void setAmapKey(String amapKey) { |
| | | MapUtil.amapKey = amapKey; |
| | | } |
| | | |
| | | /** |
| | | * 正向地理解析 - 根据地址获取经纬度 |
| | | * |
| | | * @param address 地址文本(如"四川省成都市") |
| | | * @return "lat,lng" 格式的经纬度字符串,解析失败返回 null |
| | | */ |
| | | public static String geocode(String address) { |
| | | try { |
| | | String url = GEOCODE_URL |
| | | + "?key=" + amapKey |
| | | + "&address=" + URLEncoder.encode(address, "UTF-8"); |
| | | |
| | | log.info("高德地图正向地理解析请求: address={}", address); |
| | | |
| | | JSONObject json = new Http().build(url) |
| | | .setConnectTimeout(5000) |
| | | .setReadTimeout(10000) |
| | | .get() |
| | | .toJSONObject(); |
| | | |
| | | log.info("高德地图正向地理解析响应: {}", json); |
| | | |
| | | if (!"1".equals(json.getString("status"))) { |
| | | log.warn("高德地图正向地理解析失败: {}", json.getString("info")); |
| | | return null; |
| | | } |
| | | |
| | | JSONArray geocodes = json.getJSONArray("geocodes"); |
| | | if (geocodes == null || geocodes.isEmpty()) { |
| | | log.warn("高德地图正向地理解析无结果: address={}", address); |
| | | return null; |
| | | } |
| | | |
| | | String location = geocodes.getJSONObject(0).getString("location"); // lng,lat |
| | | if (StringUtils.isBlank(location)) { |
| | | return null; |
| | | } |
| | | String[] parts = location.split(","); |
| | | // 转为 lat,lng 格式 |
| | | return parts[1] + "," + parts[0]; |
| | | } catch (Exception e) { |
| | | log.error("高德地图正向地理解析异常: address={}", address, e); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | throw new RuntimeException("高德地图路径规划异常", e); |
| | | } |
| | | } |
| | | |
| | | public static JSONObject directionInfo(String mode, String from, String to) { |
| | | // 高德坐标系为 lng,lat |
| | | String[] fromArr = from.split(","); |
| | | String[] toArr = to.split(","); |
| | | String origin = fromArr[1] + "," + fromArr[0]; // lng,lat |
| | | String destination = toArr[1] + "," + toArr[0]; // lng,lat |
| | | |
| | | try { |
| | | String url; |
| | | if ("bicycling".equals(mode)) { |
| | | url = BICYCLING_URL |
| | | + "?key=" + amapKey |
| | | + "&origin=" + URLEncoder.encode(origin, "UTF-8") |
| | | + "&destination=" + URLEncoder.encode(destination, "UTF-8"); |
| | | } else { |
| | | // 默认驾车 |
| | | url = DRIVING_URL |
| | | + "?key=" + amapKey |
| | | + "&origin=" + URLEncoder.encode(origin, "UTF-8") |
| | | + "&destination=" + URLEncoder.encode(destination, "UTF-8"); |
| | | } |
| | | |
| | | log.info("高德地图路径规划请求: mode={}, from={}, to={}", mode, from, to); |
| | | |
| | | JSONObject json = new Http().build(url) |
| | | .setConnectTimeout(5000) |
| | | .setReadTimeout(10000) |
| | | .get() |
| | | .toJSONObject(); |
| | | |
| | | log.info("高德地图路径规划响应: {}", json); |
| | | return json; |
| | | } catch (IOException e) { |
| | | log.error("高德地图路径规划异常", e); |
| | | throw new RuntimeException("高德地图路径规划异常", e); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |