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");
|
|
}
|
}
|