doum
13 小时以前 86450ddc6c1e36e2160336778672bf20be1a0bd6
最新版本541200007
已添加3个文件
已删除1个文件
已修改6个文件
已重命名2个文件
298 ■■■■ 文件已修改
server/system_service/src/main/java/com/doumee/core/utils/Constants.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/core/utils/DistanceCalculator.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/pom.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCalculator.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceMapParam.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceModel.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/TspSolver.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/TspSolverSolutions.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
    }