server/system_service/src/main/java/com/doumee/core/utils/Constants.java
@@ -558,28 +558,21 @@ return d; } public static BigDecimal formatBigdecimal4Float(BigDecimal d) { return formatBigdecimalScale(d,4); } public static BigDecimal formatBigdecimalScale(BigDecimal d,int scale) { if (d == null) { d = new BigDecimal(0.0); } //ä¿ç两ä½å°æ°ä¸åèäºå ¥ d = d.setScale(4, BigDecimal.ROUND_HALF_UP); d = d.setScale(scale, BigDecimal.ROUND_HALF_UP); return d; } public static BigDecimal formatBigdecimal0Float(BigDecimal d) { if (d == null) { d = new BigDecimal(0.0); } //ä¿ç两ä½å°æ°ä¸åèäºå ¥ d = d.setScale(0, BigDecimal.ROUND_HALF_UP); return d; return formatBigdecimalScale(d,0); } public static BigDecimal formatBigdecimal2Float(BigDecimal d) { if (d == null) { d = new BigDecimal(0.0); } //ä¿ç两ä½å°æ°ä¸åèäºå ¥ d = d.setScale(2, BigDecimal.ROUND_HALF_UP); return d; return formatBigdecimalScale(d,2); } server/system_service/src/main/java/com/doumee/core/utils/DistanceCalculator.java
ÎļþÒÑɾ³ý server/visits/dmvisit_service/pom.xml
@@ -21,6 +21,18 @@ <groupId>com.doumee</groupId> <artifactId>system_service</artifactId> <version>1.0.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>4.31.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.doumee</groupId> server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCalculator.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,94 @@ package com.doumee.core.tsp; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.doumee.core.utils.Constants; import com.doumee.core.utils.HttpsUtil; import com.doumee.dao.business.model.JkCustomer; import com.doumee.dao.business.model.JkSketchCustomer; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @Slf4j public class DistanceCalculator { private static final double EARTH_RADIUS = 6371.0; // å°çåå¾ï¼åä½ï¼å ¬éï¼ public static void main(String[] args) { //118.363428,31.326485 //118.363312,31.326638 System.out.println(calculateDistance(39.326638d,116.363312d,31.326606,118.363272)); } public static DistanceModel calculateDistanceGaode(String urlStr, JkSketchCustomer c1, JkSketchCustomer c2) { DistanceModel r =new DistanceModel(); r.setStart(c1); r.setEnd(c2); r.setDistance(0); r.setLocations( new ArrayList<>()); try { String url =urlStr.replace("${lat1}", Constants.formatBigdecimalScale(c1.getLatitude(),6)+"") .replace("${lat2}",Constants.formatBigdecimalScale(c2.getLatitude(),6)+"") .replace("${long1}",Constants.formatBigdecimalScale(c1.getLongitude(),6)+"") .replace("${long2}",Constants.formatBigdecimalScale(c2.getLongitude(),6)+""); String result = HttpsUtil.get(url ,true); JSONObject json = JSONObject.parseObject(result); if(json!=null && json.getInteger("status")!=null && json.getInteger("status") ==1 && json.getJSONObject("route")!=null && json.getJSONObject("route").getJSONArray("paths") !=null && json.getJSONObject("route").getJSONArray("paths") .size()>0 ){ JSONArray array = json.getJSONObject("route").getJSONArray("paths"); JSONObject model = array.getJSONObject(0);//å第ä¸ä¸ª Long distance = Long.parseLong(model.getString("distance")); r.setDistance(distance*1000); JSONArray steps = model.getJSONArray("steps"); String tl = ""; if(steps!=null && steps.size()>0){ for (int i = 0; i < steps.size(); i++) { if(StringUtils.isBlank(steps.getJSONObject(i).getString("polyline" ))){ continue; } if(!tl.equals("") &&!tl.endsWith(";")){ tl += ";"; } tl+= steps.getJSONObject(i).getString("polyline" ); } } r.setLocations(Arrays.asList(tl.split(";"))); }else{ log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=============="); } }catch (Exception e){ log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=====失败=========="); } return r ; } private BigDecimal getDecimalByVal(String val) { try { return new BigDecimal(val); }catch (Exception e){ } return null; } public static long calculateDistance (double lat1, double lon1, double lat2, double lon2) { double dLat = Math.toRadians(lat2 - lat1); double dLon = Math.toRadians(lon2 - lon1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return (long) (EARTH_RADIUS * c * 1000); } } server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceMapParam.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ package com.doumee.core.tsp; import com.doumee.dao.business.model.JkCustomer; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.List; @Slf4j @Data public class DistanceMapParam { private long distance; private Integer id; } server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceModel.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ package com.doumee.core.tsp; import com.doumee.dao.business.model.JkCustomer; import com.doumee.dao.business.model.JkSketchCustomer; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.List; @Slf4j @Data public class DistanceModel { private long distance; private List<String> locations; private JkSketchCustomer start; private JkSketchCustomer end; } server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/TspSolver.java
ÎļþÃû´Ó server/system_service/src/main/java/com/doumee/core/utils/tsp/TspSolver.java ÐÞ¸Ä @@ -1,4 +1,4 @@ package com.doumee.core.utils.tsp; package com.doumee.core.tsp; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; @@ -6,12 +6,9 @@ import com.google.ortools.constraintsolver.*; import lombok.extern.slf4j.Slf4j; import com.google.protobuf.Internal.IntListAdapter.IntConverter; import com.google.ortools.constraintsolver.mainJNI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Slf4j public class TspSolver { server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/TspSolverSolutions.java
ÎļþÃû´Ó server/system_service/src/main/java/com/doumee/core/utils/tsp/TspSolverSolutions.java ÐÞ¸Ä @@ -1,4 +1,4 @@ package com.doumee.core.utils.tsp; package com.doumee.core.tsp; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java
@@ -12,6 +12,8 @@ import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; import java.math.BigDecimal; import java.util.List; import java.util.Map; /** * 交æ§-客æ·ä¿¡æ¯è¡¨ @@ -87,6 +89,9 @@ @ApiModelProperty(value = "ç¶æ 0æ£å¸¸ ç¦ç¨", example = "1") //@ExcelColumn(name="ç¶æ 0æ£å¸¸ ç¦ç¨") private Integer status; @ApiModelProperty(value = "客æ·é´è·ç¦»éå", example = "1") //@ExcelColumn(name="ç¶æ 0æ£å¸¸ ç¦ç¨") private String distance; @ApiModelProperty(value = "æåºç ", example = "1") //@ExcelColumn(name="æåºç ") @@ -110,4 +115,10 @@ @ApiModelProperty(value = "æ¯å¦æ°å¢ï¼ 0å¦ 1æ¯", example = "1") @TableField(exist = false) private int isnew; @ApiModelProperty(value = "åçç»é´å®¢æ·ä½ç½®è·ç¦»æ°ç»ï¼[{a:12,b:100},{a:13,b:200},...],aï¼å®¢æ·ç¼ç ï¼bï¼ä¸å®¢æ·aä¹é´çè·ç¦»") @TableField(exist = false) private List<Map<String,Object>> distanceList; } server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.doumee.core.annotation.excel.ExcelColumn; import com.doumee.core.tsp.DistanceMapParam; import com.doumee.service.business.third.model.LoginUserModel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -98,6 +99,7 @@ @ExcelColumn(name="线路",index = 4,width = 10) @TableField(exist = false) private String lineName; @ApiModelProperty(value = "æå±ä¸»çº¿è·¯", example = "1") @ExcelColumn(name="æå±ä¸»çº¿è·¯",index = 3,width = 10) @TableField(exist = false) @@ -117,8 +119,13 @@ //@ExcelColumn(name="维度") @TableField(exist = false) private BigDecimal latitude; @ApiModelProperty(value = "线路åç§°", example = "1") @TableField(exist = false) private String distanceJson; @ApiModelProperty(value = "åçç»é´å®¢æ·ä½ç½®è·ç¦»æ°ç»ï¼[{a:12,b:100},{a:13,b:200},...],aï¼å®¢æ·ç¼ç ï¼bï¼ä¸å®¢æ·aä¹é´çè·ç¦»") @TableField(exist = false) private List<Map<String,Object>> distanceList; @ApiModelProperty(value = "åçç»é´å®¢æ·ä½ç½®è·ç¦»æ°ç»ï¼[{a:12,b:100},{a:13,b:200},...],aï¼å®¢æ·ç¼ç ï¼bï¼ä¸å®¢æ·aä¹é´çè·ç¦»") @TableField(exist = false) private List<DistanceMapParam> distanceMapParamList; } server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java
@@ -227,7 +227,6 @@ @Override public void checkNullLocation() { log.error("æ´æ°äº¤æ§ä¸å¿å®¢æ·ç»çº¬åº¦ä¿¡æ¯===============å¼å§"); Boolean importing = (Boolean) redisTemplate.opsForValue().get(Constants.RedisKeys.CHECKING_JKCUSTOMER_LOCATION); if(importing!=null && importing){ @@ -277,7 +276,6 @@ }catch (Exception e){ log.error("æ´æ°äº¤æ§ä¸å¿å®¢æ·ç»çº¬åº¦ä¿¡æ¯=====失败=========="+c.getName()+"-"+c.getLocation()); } } }catch (Exception e){ log.error("æ´æ°äº¤æ§ä¸å¿å®¢æ·ç»çº¬åº¦ä¿¡æ¯===============",e.getMessage()); server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java
@@ -1,12 +1,15 @@ package com.doumee.service.business.impl; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.annotation.excel.ExcelImporter; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.core.tsp.*; import com.doumee.core.utils.*; import com.doumee.core.utils.tsp.TspSolver; import com.doumee.core.utils.tsp.TspSolverSolutions; import com.doumee.core.wms.model.response.WmsBaseDataResponse; import com.doumee.core.wms.model.response.WmsBaseResponse; import com.doumee.dao.admin.request.JkOrdersImport; import com.doumee.dao.business.*; import com.doumee.dao.business.model.*; @@ -19,8 +22,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.wrapper.MPJLambdaWrapper; import netscape.javascript.JSObject; import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.units.qual.C; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Async; @@ -139,6 +142,7 @@ @Async public void startUpdateLineAsync(JkSketch model) { try { initCustomerDistance(model); List<JkSketchCustomer> customerList = model.getCustomerList(); List<JkLine> lineList = model.getLineList(); TspSolver.DataModel dataModel = new TspSolver.DataModel(); @@ -188,6 +192,69 @@ .set(JkSketch::getPlanLineEndDate,new Date())); } } private void initCustomerDistance(JkSketch model) { String url = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.GAODE_LOCATION_GEOAPI_URL).getCode(); List<JkCustomer> updateCustomerList = new ArrayList<>(); List<JkSketchCustomer> customerList = model.getCustomerList(); for(JkSketchCustomer c : customerList){ List<DistanceMapParam> tmpList = new ArrayList<>(); List<DistanceMapParam> distanceMapParamList = getListFromJsonStr(c.getDistanceJson()); for(JkSketchCustomer cm : customerList){ boolean isNew = false; DistanceMapParam t = new DistanceMapParam(); t.setId(cm.getId()); DistanceMapParam param = getParamByCustomerIds( cm.getId(),distanceMapParamList); if(param!=null){//妿ä¹åå·²ç»è·åè¿ t = param; }else{ isNew = true; if(Constants.equalsInteger(c.getCustomerId(),cm.getCustomerId())){ t.setDistance(0l); }else{ DistanceModel dm = DistanceCalculator.calculateDistanceGaode(url,c,cm); t.setDistance(dm.getDistance() ); if(dm.getLocations().size()>0){ //妿æè·¯å¾ä¿¡æ¯ } } } tmpList.add(t); if(isNew){// JkCustomer u =new JkCustomer(); u.setId(c.getId()); u.setDistance(JSONObject.toJSONString(tmpList)); } } c.setDistanceMapParamList(tmpList); } if(updateCustomerList.size()>0){ for(JkCustomer c : updateCustomerList){ jkCustomerMapper.updateById(c);//æ´æ°å®¢æ·ä¸å ¶ä»ç¹ä¹é´çè·ç¦» } } } private DistanceMapParam getParamByCustomerIds( Integer id1, List<DistanceMapParam> distanceMapParamList) { if(distanceMapParamList!=null){ for(DistanceMapParam p :distanceMapParamList){ if(Constants.equalsInteger(p.getId(),id1)){ return p; } } } return null; } private List<DistanceMapParam> getListFromJsonStr(String distanceJson) { try { return JSONObject.parseObject(distanceJson, new TypeReference<List<DistanceMapParam>>(){}.getType()); }catch (Exception e){ } return new ArrayList<>(); } private void dealSearchSolution(JkSketch model, TspSolver.DataModel dataModel) { @@ -287,11 +354,11 @@ } private List<JkSketchCustomer> checkJketchCustomerLocation(JkSketch model) { MPJLambdaWrapper<JkSketchCustomer> queryWrapper = new MPJLambdaWrapper<>(); queryWrapper.selectAll(JkSketchCustomer.class ) .selectAs(JkCustomer::getName,JkSketchCustomer::getName) .selectAs(JkCustomer::getCode,JkSketchCustomer::getCode) .selectAs(JkCustomer::getDistance,JkSketchCustomer::getDistanceJson) .selectAs(JkCustomer::getLongitude,JkSketchCustomer::getLongitude) .selectAs(JkCustomer::getLatitude,JkSketchCustomer::getLatitude) .leftJoin(JkCustomer.class,JkCustomer::getId,JkSketchCustomer::getCustomerId ) @@ -311,7 +378,7 @@ if(StringUtils.isNotBlank(errorMsg)){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"该线路客æ·:"+errorMsg+"å®ä½ä¿¡æ¯ä¸å®æ´ï¼ä¸æ»¡è¶³ä¼åæ¡ä»¶ï¼"); } for(JkSketchCustomer c : customerList){ /* for(JkSketchCustomer c : customerList){ List<Map<String,Object>> tmpList = new ArrayList<>(); for(JkSketchCustomer cm : customerList){ Map<String,Object> t = new HashMap<>(); @@ -321,7 +388,7 @@ }else{ t.put("b", DistanceCalculator.calculateDistance( Constants.formatBigdecimal(c.getLatitude()).doubleValue(), Constants.formatBigdecimal(c.getLatitude()).doubleValue(), Constants.formatBigdecimal(c.getLongitude()).doubleValue(), Constants.formatBigdecimal(cm.getLatitude()).doubleValue(), Constants.formatBigdecimal(cm.getLongitude()).doubleValue())); } @@ -329,8 +396,8 @@ } c.setDistanceList(tmpList); } if(Constants.equalsInteger(Constants.ZERO,model.getStatus())){ */ /*if(Constants.equalsInteger(Constants.ZERO,model.getStatus())){ //å¦ææ¯æªä¼åç¶æï¼è®¡ç®åå§è·ç¦» long totalDistance = 0; MPJLambdaWrapper<JkSketchLine> queryWrapper1 = new MPJLambdaWrapper<>(); @@ -359,7 +426,8 @@ ,Constants.formatBigdecimal(c.getLatitude()).doubleValue() ,Constants.formatBigdecimal(c.getLongitude()).doubleValue()); }else{ totalDistance += DistanceCalculator.calculateDistance(Constants.formatBigdecimal(c.getLatitude()).doubleValue() totalDistance += DistanceCalculator.calculateDistance( Constants.formatBigdecimal(c.getLatitude()).doubleValue() ,Constants.formatBigdecimal(c.getLongitude()).doubleValue() ,Constants.formatBigdecimal(last.getLatitude()).doubleValue() ,Constants.formatBigdecimal(last.getLongitude()).doubleValue()); @@ -377,7 +445,7 @@ } model.setOriginDistance(totalDistance); } }*/ return customerList; }