package com.ruoyi.system.service.impl; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.config.BaiduMapConfig; import com.ruoyi.system.service.IMapService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; /** * 百度地图服务实现 * * @author ruoyi */ @Service("baiduMapService") public class BaiduMapServiceImpl implements IMapService { private static final Logger logger = LoggerFactory.getLogger(BaiduMapServiceImpl.class); @Autowired private BaiduMapConfig baiduMapConfig; /** * 地址转GPS坐标(地理编码) * * @param address 地址 * @param city 城市(可选,用于提高解析准确性) * @return GPS坐标,包含lng和lat,如果获取失败返回null */ @Override public Map geocoding(String address, String city) { // 如果地址为空,直接返回null if (address == null || address.trim().isEmpty()) { return null; } try { // 构建百度地图地理编码API URL String url = "https://api.map.baidu.com/geocoding/v3/"; String params = "address=" + URLEncoder.encode(address, StandardCharsets.UTF_8.toString()) + (city != null && !city.trim().isEmpty() ? "&city=" + URLEncoder.encode(city, StandardCharsets.UTF_8.toString()) : "") + "&output=json" + "&ak=" + baiduMapConfig.getAk(); logger.info("百度地图地理编码请求: address={}, city={}", address, city); // 发送HTTP请求 String response = HttpUtils.sendGet(url, params); // 解析响应 JSONObject jsonObject = JSONObject.parseObject(response); if (jsonObject.getInteger("status") != 0) { logger.warn("百度地图地理编码失败: address={}, status={}, message={}", address, jsonObject.getInteger("status"), jsonObject.getString("message")); return null; } // 提取坐标 JSONObject result = jsonObject.getJSONObject("result"); JSONObject location = result.getJSONObject("location"); double lng = location.getDouble("lng"); double lat = location.getDouble("lat"); logger.info("百度地图地理编码成功: address={}, lng={}, lat={}", address, lng, lat); Map coordinates = new HashMap<>(); coordinates.put("lng", lng); coordinates.put("lat", lat); return coordinates; } catch (Exception e) { // 捕获所有异常,避免影响主流程 logger.error("百度地图地理编码异常: address=" + address, e); return null; } } @Override public String reverseGeocoding(double lng, double lat) { //调用百度地址反向解析接口 String url = "https://api.map.baidu.com/reverse_geocoding/v3/"; String params = "location=" + lat + "," + lng + "&output=json" + "&ak=" + baiduMapConfig.getAk(); String response = HttpUtils.sendGet(url, params); //"{\"status\":0,\"result\":{\"location\":{\"lng\":113.25330399999999,\"lat\":23.04668300960378},\"formatted_address\":\"广东省佛山市南海区桂城街道\",\"edz\":{\"name\":\"\"},\"business\":\"\",\"business_info\":[],\"addressComponent\":{\"country\":\"中国\",\"country_code\":0,\"region_code_iso\":\"CHN\",\"country_code_iso\":\"CHN\",\"country_code_iso2\":\"CN\",\"province\":\"广东省\",\"city\":\"佛山市\",\"city_level\":2,\"district\":\"南海区\",\"town\":\"桂城街道\",\"town_code\":\"440605011\",\"distance\":\"\",\"direction\":\"\",\"adcode\":\"440605\",\"street\":\"\",\"street_number\":\"\"},\"pois\":[],\"roads\":[],\"poiRegions\":[],\"sematic_description\":\"\",\"formatted_address_poi\":\"\",\"cityCode\":138}}" JSONObject jsonObject = JSONObject.parseObject(response); if (jsonObject.getInteger("status") != 0) { logger.warn("百度地图地址反向解析失败: lng={}, lat={}, status={}, message={}", lng, lat, jsonObject.getInteger("status"), jsonObject.getString("message")); return null; } String address = jsonObject.getJSONObject("result").getString("formatted_address"); logger.info("百度地图地址反向解析成功: lng={}, lat={}, address={}", lng, lat, address); return address; } }