package com.skyversation.poiaddr.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.skyversation.poiaddr.addquery.AddressQueryEngine; import com.skyversation.poiaddr.addquery.AddressTools; import com.skyversation.poiaddr.addquery.Constant; import com.skyversation.poiaddr.addquery.TransfromDataTool; import com.skyversation.poiaddr.bean.AddressResult; import com.skyversation.poiaddr.bean.GeoJsonBean; import com.skyversation.poiaddr.util.address_spliter.SplitAddress; import com.skyversation.poiaddr.util.CoordTransform2; import com.skyversation.poiaddr.util.address_spliter.ShanghaiAddressSplitUtil; import com.skyversation.poiaddr.bean.TAddressCallback; import com.skyversation.poiaddr.bean.YyszAddressQp; import com.skyversation.poiaddr.repository.TAddressCallbackRep; import com.skyversation.poiaddr.repository.YyszAddressQpRep; import com.skyversation.poiaddr.util.net.AddressNetTools; import com.skyversation.poiaddr.util.status.AddressLevel; import com.skyversation.poiaddr.util.status.AddressResultEnum; import lombok.Getter; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.Instant; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Matcher; import java.util.regex.Pattern; @Service public class DataCallBackService { private DataCallBackService(){}; @Getter private static final DataCallBackService instance = new DataCallBackService(); private final ExecutorService successES = Executors.newSingleThreadExecutor(); private final ExecutorService failES = Executors.newSingleThreadExecutor(); @Resource private TAddressCallbackRep tAddressCallbackRep; @Resource private YyszAddressQpRep yyszAddressQpRep; @Resource private ShanghaiAddressSplitUtil shanghaiAddressSplitUtil; @Resource private AddressQueryEngine addressQueryEngine; @Resource private PlatformTransactionManager transactionManager; private static final Map CHINESE_TO_ARABIC = new HashMap<>(); static { CHINESE_TO_ARABIC.put("第一", "01"); CHINESE_TO_ARABIC.put("第二", "02"); CHINESE_TO_ARABIC.put("第三", "03"); CHINESE_TO_ARABIC.put("第四", "04"); CHINESE_TO_ARABIC.put("第五", "05"); CHINESE_TO_ARABIC.put("第六", "06"); CHINESE_TO_ARABIC.put("第七", "07"); CHINESE_TO_ARABIC.put("第八", "08"); CHINESE_TO_ARABIC.put("第九", "09"); } /** * 成功数据入库 */ public void successDataCallBack(AddressResult addressResult){ for (AddressResult.ContentBean bean :addressResult.getData()){ successES.execute(() -> { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { try { System.out.println("回流有结果数据:" + bean.getSearchAddress()); YyszAddressQp yyszAddressQp = new YyszAddressQp(); yyszAddressQp.setSourceaddress(bean.getSearchAddress()); yyszAddressQp.setId(yyszAddressQpRep.findMaxId().orElse(0) + 1); yyszAddressQp.setLon(bean.getLon()); yyszAddressQp.setLat(bean.getLat()); SplitAddress splitAddress = ShanghaiAddressSplitUtil.splitBestAddress(bean.getSearchAddress()); yyszAddressQp.setAddress(splitAddress.getAddr()); yyszAddressQp.setCity(splitAddress.getCity()); yyszAddressQp.setCounty(splitAddress.getDistrict()); yyszAddressQp.setTown(splitAddress.getStreet()); yyszAddressQp.setCommunity(splitAddress.getCommunity()); yyszAddressQp.setCityCode(splitAddress.getCityCode()); yyszAddressQp.setCountyCode(splitAddress.getDistrictCode()); yyszAddressQp.setTownCode(splitAddress.getStreetCode()); yyszAddressQp.setCommunityCode(splitAddress.getCommunityCode()); yyszAddressQp.setIsHistory(0); yyszAddressQp.setSignatureCheckState(0); yyszAddressQp.setSecurityGrade(0); yyszAddressQp.setModelType(0); yyszAddressQp.setIsDelete(0); yyszAddressQp.setLv(0); yyszAddressQp.setIsMulti(0); yyszAddressQp.setRoomOfFloor(0); yyszAddressQp.setSource("标准地址"); yyszAddressQp.setUpdatetime(Instant.now()); yyszAddressQp.setCreatetime(Instant.now()); String regex = "([^0-9]*[路道街])(\\d+[弄号])?(.*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(splitAddress.getAddr()); if (matcher.matches()) { String road = matcher.group(1); String alley = matcher.group(2); String additionalInfo = matcher.group(3); yyszAddressQp.setStreet(road); yyszAddressQp.setDoor(alley); } if (yyszAddressQp.getLon()!=null&&yyszAddressQp.getLat()!=null){ double[] result = CoordTransform2.getInstance().wgs84_to_shcj(yyszAddressQp.getLon(),yyszAddressQp.getLat()); yyszAddressQp.setX(String.valueOf(result[0])); yyszAddressQp.setY(String.valueOf(result[1])); GeoJsonBean geoJsonBean = AreaService.getInstance().isInGridPolygon(yyszAddressQp.getLon(),yyszAddressQp.getLat()); if (geoJsonBean!=null){ yyszAddressQp.setCounty(geoJsonBean.getProperties().getString("所属区县")); yyszAddressQp.setTown(geoJsonBean.getProperties().getString("所属街道")); yyszAddressQp.setGridName(geoJsonBean.getProperties().getString("网格名称")); if (yyszAddressQp.getGridName()!=null&&yyszAddressQp.getTownCode()!=null&&!yyszAddressQp.getTownCode().isEmpty()){ for (String key:CHINESE_TO_ARABIC.keySet()){ if (yyszAddressQp.getGridName().startsWith(key)){ yyszAddressQp.setGridCode(yyszAddressQp.getTownCode()+CHINESE_TO_ARABIC.get(key)); break; } } } } } yyszAddressQpRep.save(yyszAddressQp); if (yyszAddressQp.getLon()!=null&&yyszAddressQp.getLat()!=null){ yyszAddressQpRep.updateLocation(yyszAddressQp.getId(), String.format("POINT(%f %f)", yyszAddressQp.getLon(), yyszAddressQp.getLat())); } } catch (Exception e) { status.setRollbackOnly(); e.printStackTrace(); } } }); }); } } /** * 失败数据入库 */ public void failDataCallBack(List addr){ for (String addrStr:addr){ failES.execute(()->{ System.out.println("尝试回流无结果数据:"+addrStr); SplitAddress splitAddress = ShanghaiAddressSplitUtil.splitBestAddress(addrStr); if (splitAddress.getStatus()==3||splitAddress.getStatus()==-1){ System.out.println("拒绝回流,检测到非地址"); return; } int id = tAddressCallbackRep.findMaxId().orElse(0)+1; TAddressCallback tAddressCallback = new TAddressCallback(id, Instant.now(),addrStr, splitAddress.getAddr(), splitAddress.getProvince(),splitAddress.getCity(),splitAddress.getStreet(), splitAddress.getCommunity(), (short) 0, (short) 0); tAddressCallbackRep.save(tAddressCallback); System.out.println("回流成功,等待进一检查处理"); }); } } /** * 用于将失败数据调高德接口回流 */ public void dbFailDataCallBackTask(){ int pageNum = 0; int pageSize = 1000; Page page; TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); do { page = tAddressCallbackRep.findAllInNative(PageRequest.of(pageNum,pageSize )); pageNum++; for (String tAddressCallback : page.getContent()) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { try { System.out.println("尝试从高德接口获取地址:" + tAddressCallback); AddressResult addressResult = addressQueryEngine.gdV3MultiSearch(Collections.singletonList(tAddressCallback),AddressLevel.LEVEL_1); if (addressResult ==null) { System.out.println("无结果:" + tAddressCallback); tAddressCallbackRep.updateAllProcessStatus(tAddressCallback,1); }else { System.out.println("有结果,回流:" + tAddressCallback); tAddressCallbackRep.updateAllProcessStatus(tAddressCallback,2); successDataCallBack(addressResult); } } catch (Exception e) { status.setRollbackOnly(); e.printStackTrace(); } } }); } } while (page.hasNext()); } }