wlzboy
5 天以前 fe33646ee6e2d1e57f2b51812e94983a0e9efb04
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.ruoyi.system.service.impl;
 
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.config.TiandituMapConfig;
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("tiandituMapService")
public class TiandituMapServiceImpl implements IMapService {
    
    private static final Logger logger = LoggerFactory.getLogger(TiandituMapServiceImpl.class);
    
    @Autowired
    private TiandituMapConfig tiandituMapConfig;
    
    /**
     * 地址转GPS坐标(地理编码)
     * 
     * @param address 地址
     * @param city 城市(可选,用于提高解析准确性)
     * @return GPS坐标,包含lng和lat,如果获取失败返回null
     */
    @Override
    public Map<String, Double> geocoding(String address, String city) {
        // 如果地址为空,直接返回null
        if (address == null || address.trim().isEmpty()) {
            return null;
        }
        if(address.indexOf(",")>0){
            String[] split = address.split(",");
            address=split[0];
        }
        if(address.indexOf(",")>0){
            String[] split = address.split(",");
            address=split[0];
        }
        try {
            // 构建天地图地理编码API URL
            String url = "http://api.tianditu.gov.cn/geocoder";
            String params = "ds=" + URLEncoder.encode("{\"keyWord\":\"" + address + "\"}", StandardCharsets.UTF_8.toString()) +
                           "&tk=" + tiandituMapConfig.getTk();
            
            logger.info("天地图地理编码请求: address={}, city={}", address, city);
            
            // 发送HTTP请求
            String response = HttpUtils.sendGet(url, params);
            
            // 解析响应
            JSONObject jsonObject = JSONObject.parseObject(response);
            
            // 检查状态
            if (jsonObject.getInteger("status") == null || jsonObject.getInteger("status") != 0) {
                logger.warn("天地图地理编码失败: address={}, status={}, msg={}", 
                           address, jsonObject.getInteger("status"), jsonObject.getString("msg"));
                return null;
            }
            
 
            
            JSONObject location = jsonObject.getJSONObject("location");
            if (location == null) {
                logger.warn("天地图地理编码响应无location: address={}", address);
                return null;
            }
            
            double lng = location.getDouble("lon");
            double lat = location.getDouble("lat");
            
            logger.info("天地图地理编码成功: address={}, lng={}, lat={}", address, lng, lat);
            
            Map<String, Double> coordinates = new HashMap<>();
            coordinates.put("lng", lng);
            coordinates.put("lat", lat);
            
            return coordinates;
        } catch (Exception e) {
            // 捕获所有异常,避免影响主流程
            logger.error("天地图地理编码异常: address=" + address, e);
            return null;
        }
    }
 
    /**
     * 直接返回地址
     * @param lng 经度
     * @param lat 纬度
     * @return
     */
    @Override
    public String reverseGeocoding(double lng, double lat) {
        // 构建天地图逆地理编码API URL
        String url = "http://api.tianditu.gov.cn/geocoder";
        String params = "postStr={\"lon\":" + lng + ",\"lat\":" + lat + ",\"ver\":1}" +
                "&type=geocode" +
                "&tk=" + tiandituMapConfig.getTk();
 
        logger.info("天地图逆地理编码请求: lon={}, lat={}", lng, lat);
 
        // 发送HTTP请求
        String response = HttpUtils.sendGet(url, params);
 
        // "{\"msg\":\"ok\",\"location\":{\"score\":100,\"level\":\"门址\",\"lon\":\"116.290158\",\"lat\":\"39.894696\",\"keyWord\":\"北京市海淀区莲花池西路28号\"},\"searchVersion\":\"7.4.3V\",\"status\":\"0\"}"
        logger.info("天地图逆地理编码响应: {}", response);
        com.alibaba.fastjson.JSONObject obj= com.alibaba.fastjson.JSONObject.parseObject(response);
        if (obj.getInteger("status") !=0) {
            logger.error("天地图逆地理编码失败: {}", response);
            return null;
        }
        com.alibaba.fastjson.JSONObject location = obj.getJSONObject("result");
        if (location == null) {
            logger.error("天地图逆地理编码响应无location: {}", response);
            return null;
        }
        return location.getString("formatted_address");
 
    }
}