高德地址转换
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package org.jeecg.common.amap.service;
|
||||
|
||||
import org.jeecg.common.amap.vo.AmapResultVo;
|
||||
|
||||
public interface AmapService {
|
||||
public AmapResultVo getFormattedAddress(Double lng, Double lat, int timeoutMs);
|
||||
public AmapResultVo getFormattedAddress(Double lng, Double lat);
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package org.jeecg.common.amap.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.jeecg.common.amap.service.AmapService;
|
||||
import org.jeecg.common.amap.vo.AmapResultVo;
|
||||
import org.jeecg.common.amap.vo.RegeoResponse;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AmapServiceImpl implements AmapService {
|
||||
|
||||
@Value("${amap.key}")
|
||||
private String amapKey;
|
||||
|
||||
@Value("${amap.regeo-url}")
|
||||
private String regeoUrl;
|
||||
|
||||
// ===== 核心方法 =====
|
||||
public AmapResultVo getFormattedAddress(Double lng, Double lat, int timeoutMs) {
|
||||
AmapResultVo result = validateCoordinates(lng, lat);
|
||||
if (!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int timeout = timeoutMs > 0 ? timeoutMs : 5000;
|
||||
|
||||
RequestConfig config = RequestConfig.custom()
|
||||
.setConnectTimeout(timeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.build();
|
||||
|
||||
CloseableHttpClient client = HttpClients.custom()
|
||||
.setDefaultRequestConfig(config)
|
||||
.build();
|
||||
|
||||
RestTemplate restTemplate = new RestTemplate(
|
||||
new HttpComponentsClientHttpRequestFactory(client)
|
||||
);
|
||||
restTemplate.getMessageConverters().forEach(converter -> {
|
||||
if (converter instanceof org.springframework.http.converter.StringHttpMessageConverter) {
|
||||
((org.springframework.http.converter.StringHttpMessageConverter) converter)
|
||||
.setDefaultCharset(StandardCharsets.UTF_8);
|
||||
}
|
||||
});
|
||||
|
||||
String url = regeoUrl +
|
||||
"?key=" + amapKey +
|
||||
"&location=" + lng + "," + lat +
|
||||
"&extensions=base";
|
||||
log.info("高德 API 请求 URL: {}", url);
|
||||
String json = restTemplate.getForObject(url, String.class);
|
||||
if (json == null) {
|
||||
throw new RuntimeException("高德 API 返回空响应");
|
||||
}
|
||||
|
||||
RegeoResponse resp = JSON.parseObject(json, RegeoResponse.class);
|
||||
|
||||
if ("1".equals(resp.getStatus())) {
|
||||
RegeoResponse.Regeocode rg = resp.getRegeocode();
|
||||
if (rg != null && rg.getFormattedAddress() != null) {
|
||||
return AmapResultVo.ok( rg.getFormattedAddress());
|
||||
} else {
|
||||
return AmapResultVo.error("高德地址为空");
|
||||
}
|
||||
} else {
|
||||
return AmapResultVo.error("高德地址获取异常["+resp.getInfocode()+"]:["+resp.getInfo()+"]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== 新增:经纬度校验 =====
|
||||
private AmapResultVo validateCoordinates(Double lng, Double lat) {
|
||||
AmapResultVo result = new AmapResultVo();
|
||||
if (lng == null || lat == null) {
|
||||
return AmapResultVo.error("经纬度不能为空");
|
||||
}
|
||||
if (Double.isNaN(lng) || Double.isInfinite(lng) ||
|
||||
Double.isNaN(lat) || Double.isInfinite(lat)) {
|
||||
return AmapResultVo.error("经纬度不能为 NaN 或 Infinity");
|
||||
}
|
||||
|
||||
if (lng < -180.0 || lng > 180.0) {
|
||||
return AmapResultVo.error("经度(lng)必须在 [-180.0, 180.0] 范围内");
|
||||
}
|
||||
|
||||
if (lat < -90.0 || lat > 90.0) {
|
||||
return AmapResultVo.error("纬度(lat)必须在 [-90.0, 90.0] 范围内");
|
||||
}
|
||||
return AmapResultVo.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmapResultVo getFormattedAddress(Double lng, Double lat) {
|
||||
return getFormattedAddress(lng, lat, 30000);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.jeecg.common.amap.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AmapResultVo {
|
||||
private boolean success = true;
|
||||
private String errorMsg;
|
||||
private String address;
|
||||
|
||||
public static AmapResultVo error(String errorMsg) {
|
||||
AmapResultVo resultVo = new AmapResultVo();
|
||||
resultVo.setSuccess(false);
|
||||
resultVo.setErrorMsg(errorMsg);
|
||||
return resultVo;
|
||||
}
|
||||
|
||||
public static AmapResultVo ok(String address) {
|
||||
AmapResultVo resultVo = new AmapResultVo();
|
||||
resultVo.setSuccess(true);
|
||||
resultVo.setAddress(address);
|
||||
return resultVo;
|
||||
}
|
||||
|
||||
public static AmapResultVo ok() {
|
||||
AmapResultVo resultVo = new AmapResultVo();
|
||||
resultVo.setSuccess(true);
|
||||
return resultVo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.jeecg.common.amap.vo;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RegeoResponse {
|
||||
private String status;
|
||||
private String info;
|
||||
private String infocode;
|
||||
|
||||
@JSONField(name = "regeocode")
|
||||
private Regeocode regeocode;
|
||||
|
||||
@Data
|
||||
public class Regeocode {
|
||||
@JSONField(name = "formatted_address")
|
||||
private String formattedAddress;
|
||||
|
||||
// 后续可扩展 province/city 等
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user