高德地址转换
This commit is contained in:
+1
@@ -51,4 +51,5 @@ public interface WatchMonitorDataMapper extends BaseMapper<WatchMonitorData>, MP
|
|||||||
|
|
||||||
List<MonitorDayStats> monitorDayStats(MonitorMonthStatsRequest request);
|
List<MonitorDayStats> monitorDayStats(MonitorMonthStatsRequest request);
|
||||||
|
|
||||||
|
List<WatchMonitorData> getEmptyAddressList();
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -206,4 +206,14 @@
|
|||||||
</if>
|
</if>
|
||||||
group by data_date order by date;
|
group by data_date order by date;
|
||||||
</select>
|
</select>
|
||||||
|
<select id="getEmptyAddressList" resultType="com.renkang.watch.entity.WatchMonitorData">
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
watch_monitor_data
|
||||||
|
WHERE
|
||||||
|
lon_gd IS NOT NULL
|
||||||
|
AND lat_gd IS NOT NULL
|
||||||
|
AND ifnull(address_gd, '') = ''
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
+2
@@ -54,4 +54,6 @@ public interface IWatchMonitorDataService extends IService<WatchMonitorData> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<AbnormalEvent> listCustomForMap(AbnormalEventFilter filter);
|
List<AbnormalEvent> listCustomForMap(AbnormalEventFilter filter);
|
||||||
|
|
||||||
|
List<WatchMonitorData> getEmptyAddressList();
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -36,6 +36,8 @@ import com.renkang.watch.vo.WatchNotifyVo;
|
|||||||
import com.renkang.watch.websocket.WebSocket;
|
import com.renkang.watch.websocket.WebSocket;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jeecg.bean.request.ListUser;
|
import org.jeecg.bean.request.ListUser;
|
||||||
|
import org.jeecg.common.amap.service.AmapService;
|
||||||
|
import org.jeecg.common.amap.vo.AmapResultVo;
|
||||||
import org.jeecg.common.api.dto.message.BusTemplateMessageDTO;
|
import org.jeecg.common.api.dto.message.BusTemplateMessageDTO;
|
||||||
import org.jeecg.common.export.PoiExportHandler;
|
import org.jeecg.common.export.PoiExportHandler;
|
||||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
@@ -110,6 +112,8 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl<WatchMonitorDataMap
|
|||||||
private final MonitorExport exportInstance = new MonitorExport();
|
private final MonitorExport exportInstance = new MonitorExport();
|
||||||
@Autowired
|
@Autowired
|
||||||
private SpeechUntil speechUntil;
|
private SpeechUntil speechUntil;
|
||||||
|
@Autowired
|
||||||
|
private AmapService amapService;
|
||||||
|
|
||||||
public static Gps GPS84ToGCJ02(double lon, double lat) {
|
public static Gps GPS84ToGCJ02(double lon, double lat) {
|
||||||
if (outOfChina(lon, lat)) {
|
if (outOfChina(lon, lat)) {
|
||||||
@@ -274,6 +278,14 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl<WatchMonitorDataMap
|
|||||||
if (null != gps) {
|
if (null != gps) {
|
||||||
monitorDataEntity.setLonGd(BigDecimal.valueOf(gps.getLongitude()));
|
monitorDataEntity.setLonGd(BigDecimal.valueOf(gps.getLongitude()));
|
||||||
monitorDataEntity.setLatGd(BigDecimal.valueOf(gps.getLatitude()));
|
monitorDataEntity.setLatGd(BigDecimal.valueOf(gps.getLatitude()));
|
||||||
|
//获取高德地址信息
|
||||||
|
AmapResultVo amapResultVo = amapService.getFormattedAddress(gps.getLongitude(), gps.getLatitude(),5000);
|
||||||
|
if (amapResultVo.isSuccess()) {
|
||||||
|
monitorDataEntity.setAddressGd(amapResultVo.getAddress());
|
||||||
|
monitorDataEntity.setAddress(amapResultVo.getAddress());
|
||||||
|
}else{
|
||||||
|
monitorDataEntity.setGpsErrorMsg(monitorDataEntity.getGpsErrorMsg() + ";" +amapResultVo.getErrorMsg());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info("构建异常数据完成 => {}", JSONObject.toJSONString(monitorDataEntity));
|
log.info("构建异常数据完成 => {}", JSONObject.toJSONString(monitorDataEntity));
|
||||||
@@ -962,6 +974,7 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl<WatchMonitorDataMap
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class Gps {
|
public static class Gps {
|
||||||
private String id;
|
private String id;
|
||||||
private double longitude;
|
private double longitude;
|
||||||
@@ -1045,4 +1058,10 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl<WatchMonitorDataMap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<WatchMonitorData> getEmptyAddressList() {
|
||||||
|
return watchMonitorDataMapper.getEmptyAddressList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
package com.renkang.watch.task;
|
||||||
|
|
||||||
|
import com.renkang.watch.entity.WatchMonitorData;
|
||||||
|
import com.renkang.watch.service.IWatchBindHisService;
|
||||||
|
import com.renkang.watch.service.IWatchDeviceService;
|
||||||
|
import com.renkang.watch.service.IWatchMonitorDataService;
|
||||||
|
import com.renkang.watch.util.WatchDataType;
|
||||||
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.jeecg.common.amap.service.AmapService;
|
||||||
|
import org.jeecg.common.amap.vo.AmapResultVo;
|
||||||
|
import org.springframework.batch.core.Job;
|
||||||
|
import org.springframework.batch.core.JobParameters;
|
||||||
|
import org.springframework.batch.core.JobParametersBuilder;
|
||||||
|
import org.springframework.batch.core.JobParametersInvalidException;
|
||||||
|
import org.springframework.batch.core.launch.JobLauncher;
|
||||||
|
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||||
|
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||||
|
import org.springframework.batch.core.repository.JobRestartException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class SynWatchGeoJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AmapService amapService;
|
||||||
|
@Autowired
|
||||||
|
private IWatchMonitorDataService watchMonitorDataService;
|
||||||
|
|
||||||
|
@XxlJob(value = "sync-watchgeo-data")
|
||||||
|
public ReturnT<String> syncWatchgeoData(){
|
||||||
|
log.info("开始处理高德逆地理编码");
|
||||||
|
//先查询地址为空的数据
|
||||||
|
List<WatchMonitorData> list = watchMonitorDataService.getEmptyAddressList();
|
||||||
|
if (!CollectionUtils.isEmpty( list)){
|
||||||
|
for (WatchMonitorData watchMonitorData : list) {
|
||||||
|
AmapResultVo resultVo = amapService.getFormattedAddress(watchMonitorData.getLonGd().doubleValue(), watchMonitorData.getLatGd().doubleValue());
|
||||||
|
if (resultVo.isSuccess()) {
|
||||||
|
watchMonitorData.setAddressGd(resultVo.getAddress());
|
||||||
|
watchMonitorData.setAddress(resultVo.getAddress());
|
||||||
|
watchMonitorDataService.updateById(watchMonitorData);
|
||||||
|
}else{
|
||||||
|
watchMonitorData.setGpsErrorMsg(resultVo.getErrorMsg());
|
||||||
|
watchMonitorDataService.updateById(watchMonitorData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ReturnT.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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