package com.estate.expert.admin.component.map; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; /** * 地理位置翻译组件 * *

该组件提供地址到地理坐标的转换功能,基于高德地图API实现。 * 主要用于将中文地址转换为精确的经纬度坐标,支持各种基于位置的服务。

* *

主要功能:

* * *

技术特点:

* * *

使用场景:

* * * @author daisy * @since 2023/10/29 */ @Slf4j @Component public class GeoTranslateComponent { /** * 高德地图地理编码API地址 * *

高德地图提供的地理编码服务接口,用于将地址转换为地理坐标。

* *

API说明:

* * *

请求参数:

* * *

API文档:https://lbs.amap.com/api/webservice/guide/api/georegeo

*/ private static final String MAP_API_URL = "https://restapi.amap.com/v3/geocode/geo"; /** * 高德地图API密钥 * *

用于访问高德地图服务的认证密钥,从配置文件中读取。

* *

配置说明:

* * *

安全注意事项:

* */ @Value("${map.api.key}") private final String API_KEY = "5ad97434d47b7cc74b4145d5509d28d2"; /** * HTTP客户端模板 * *

用于发送HTTP请求到高德地图API服务。 * Spring RestTemplate提供了便捷的HTTP客户端功能。

*/ RestTemplate restTemplate = new RestTemplate(); /** * 地址转坐标方法 * *

该方法将文本地址转换为地理坐标(经纬度),支持中文地址解析。 * 通过调用高德地图地理编码API实现地址到坐标的转换。

* *

处理流程:

*
    *
  1. 构建API请求URL,包含地址和API密钥参数
  2. *
  3. 发送HTTP GET请求到高德地图API
  4. *
  5. 解析JSON响应数据
  6. *
  7. 提取第一个地理编码结果的坐标信息
  8. *
  9. 将坐标字符串解析为Double数组
  10. *
  11. 处理异常情况并返回null
  12. *
* *

坐标格式:

* * *

异常处理:

* * * @param address 待解析的地址文本,支持中文地址 * @return Double[] 坐标数组,格式为[经度, 纬度],解析失败时返回null * * @see GeoResponse API响应格式说明 * *

使用示例:

*
     * GeoTranslateComponent component = new GeoTranslateComponent();
     * Double[] coords = component.translate("北京市朝阳区阜通东大街6号");
     * if (coords != null) {
     *     double longitude = coords[0]; // 经度
     *     double latitude = coords[1];  // 纬度
     * }
     * 
*/ public Double[] translate(String address) { try { // 构建API请求URL String url = MAP_API_URL + "?address=" + address + "&key=" + API_KEY; log.debug("发送地理编码请求: {}", url); // 发送HTTP GET请求并获取响应 var response = restTemplate.getForObject(url, GeoResponse.class); // 检查响应数据是否有效 if (response != null && response.getGeocodes() != null && !response.getGeocodes().isEmpty()) { // 获取第一个地理编码结果的坐标字符串 var location = response.getGeocodes().get(0).getLocation(); log.debug("获取到坐标: {}", location); // 解析坐标字符串为Double数组 var locationArray = location.split(","); if (locationArray.length >= 2) { double longitude = Double.parseDouble(locationArray[0]); double latitude = Double.parseDouble(locationArray[1]); log.info("地址 '{}' 解析成功: 经度={}, 纬度={}", address, longitude, latitude); return new Double[]{longitude, latitude}; } else { log.warn("坐标格式无效: {}", location); } } else { log.warn("地址 '{}' 未找到匹配的地理编码结果", address); } } catch (Exception e) { // 记录详细的错误信息 log.error("地理编码API请求失败, 地址: {}, 错误: {}", address, e.getMessage(), e); } // 异常情况下返回null return null; } /** * 测试方法 - 地址转坐标示例 * *

该方法演示了如何使用地理编码组件进行地址到坐标的转换。 * 适用于功能测试和开发调试。

* *

测试地址:

* * *

使用说明:

* */ public static void main(String[] args) { // 创建地理编码组件实例 GeoTranslateComponent component = new GeoTranslateComponent(); // 测试地址转坐标功能 var result = component.translate("北京市朝阳区阜通东大街6号"); // 输出结果 if (result != null) { System.out.println("地址解析成功:"); System.out.println("经度: " + result[0]); System.out.println("纬度: " + result[1]); } else { System.out.println("地址解析失败"); } } }