Commit 237eeaf1 by huangjinxin

Merge remote-tracking branch 'origin/develop' into develop

2 parents 99031334 c5885899
......@@ -11,6 +11,8 @@ import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
......@@ -59,13 +61,13 @@ public class GeoDistanceCalculator {
}
}
private Map<Location, Map<Location, Pair>> calculateBulkDistanceDuration(Collection<Location> fromLocations, Collection<Location> toLocations) {
private Map<Location, Map<Location, Pair>> calculateBulkDistanceDuration(Collection<Location> fromLocations, Collection<Location> toLocations, Integer vehicleType) {
return fromLocations.stream().collect(Collectors.toMap(
Function.identity(),
from -> toLocations.stream().collect(Collectors.toMap(
Function.identity(),
to -> {
Distance distance = RoadDistanceUtils.getDistance(from, to);
Distance distance = RoadDistanceUtils.getDistance(from, to, vehicleType);
long path = (long) distance.getDis();
long time = distance.getTime();
return new Pair(path, time);
......@@ -74,18 +76,17 @@ public class GeoDistanceCalculator {
));
}
public void initDistanceMaps(Collection<Location> locationList) {
Map<Location, Map<Location, Pair>> distanceMatrix = calculateBulkDistanceDuration(locationList, locationList);
locationList.forEach(location -> {
Map<Location, Pair> mapPair = distanceMatrix.get(location);
mapPair.forEach((loc2, pair) -> {
location.getDistanceMap().put(loc2, pair.Distance);
location.getDistanceTimeMap().put(loc2, pair.Duration);
public void initDistanceMaps(Collection<Location> locationList, List<Integer> vehicleTypes) {
for (Integer vehicleType: vehicleTypes) {
Map<Location, Map<Location, Pair>> distanceMatrix = calculateBulkDistanceDuration(locationList, locationList, vehicleType);
locationList.forEach(location -> {
Map<Location, Pair> mapPair = distanceMatrix.get(location);
mapPair.forEach((loc2, pair) -> {
location.getDistanceMap(vehicleType).put(loc2, pair.Distance);
location.getDistanceTimeMap(vehicleType).put(loc2, pair.Duration);
});
});
});
}
}
}
......
......@@ -51,6 +51,9 @@ public class DispatchEngineer implements Serializable {
@Column(name = "max_distance")
private Integer maxDistance;
@Column(name = "vehicle_type")
private Integer vehicleType;
private String ext = "";
......
......@@ -131,9 +131,9 @@ public class Customer {
// throw new IllegalStateException("This method must not be called when the shadow variables are not initialized yet.");
}
if (previousCustomer == null) {
return technician.getDepot().getLocation().getDistanceTo(location);
return technician.getDepot().getLocation().getDistanceTo(technician.getVehicleType(),location);
}
return previousCustomer.getLocation().getDistanceTo(location);
return previousCustomer.getLocation().getDistanceTo(technician.getVehicleType(),location);
}
/**
......@@ -147,9 +147,9 @@ public class Customer {
// throw new IllegalStateException("This method must not be called when the shadow variables are not initialized yet.");
}
if (previousCustomer == null) {
return technician.getDepot().getLocation().getPathTimeTo(location);
return technician.getDepot().getLocation().getPathTimeTo(technician.getVehicleType(),location);
}
return previousCustomer.getLocation().getPathTimeTo(location);
return previousCustomer.getLocation().getPathTimeTo(technician.getVehicleType(),location);
}
@Override
......
......@@ -24,10 +24,26 @@ public class Location {
private double latitude;
private double longitude;
// 汽车路网矩阵
@JsonIgnore
private Map<Location, Long> distanceMap = new HashMap<Location, Long>();// 路网距离矩阵
private Map<Location, Long> carDistanceMap = new HashMap<Location, Long>();// 路网距离矩阵
@JsonIgnore
private Map<Location, Long> distanceTimeMap = new HashMap<Location, Long>();// 路网时间矩阵
private Map<Location, Long> carDistanceTimeMap = new HashMap<Location, Long>();// 路网时间矩阵
// 电动车路网矩阵
@JsonIgnore
private Map<Location, Long> electricBicycleDistanceMap = new HashMap<Location, Long>();// 路网距离矩阵
@JsonIgnore
private Map<Location, Long> electricBicycleDistanceTimeMap = new HashMap<Location, Long>();// 路网时间矩阵
// 自行车路网矩阵
@JsonIgnore
private Map<Location, Long> bicycleDistanceMap = new HashMap<Location, Long>();// 路网距离矩阵
@JsonIgnore
private Map<Location, Long> bicycleDistanceTimeMap = new HashMap<Location, Long>();// 路网时间矩阵
// 步行路网矩阵
@JsonIgnore
private Map<Location, Long> walkDistanceMap = new HashMap<Location, Long>();// 路网距离矩阵
@JsonIgnore
private Map<Location, Long> walkDistanceTimeMap = new HashMap<Location, Long>();// 路网时间矩阵
public Location(long id) {
this.id = id;
......@@ -47,36 +63,101 @@ public class Location {
this.latitude = latitude;
}
/**
* Set the distance map. Distances are in meters.
*
* @param distanceMap a map containing distances from here to other locations
*/
public void setDistanceMap(Map<Location, Long> distanceMap) {
this.distanceMap = distanceMap;
}
/**
* Distance to the given location in meters.
*
* @param location other location
* @return distance in meters
* 根据不同交通方式返回不同距离
*
* @param vehicleType
* @param location
* @return
*/
public long getDistanceTo(Location location) {
return distanceMap.get(location);
}
public long getDistanceTo(Integer vehicleType, Location location) {
if (null == vehicleType) {
return carDistanceMap.get(location);
}
switch (vehicleType) {
case 1:
return carDistanceMap.get(location);
case 2:
return electricBicycleDistanceMap.get(location);
case 3:
return bicycleDistanceMap.get(location);
case 4:
return walkDistanceMap.get(location);
}
return carDistanceMap.get(location);
}
public Map<Location, Long> getDistanceMap(Integer vehicleType) {
if (null == vehicleType) {
return carDistanceMap;
}
switch (vehicleType) {
case 1:
return carDistanceMap;
case 2:
return electricBicycleDistanceMap;
case 3:
return bicycleDistanceMap;
case 4:
return walkDistanceMap;
}
return carDistanceMap;
}
public Map<Location, Long> getDistanceTimeMap(Integer vehicleType) {
if (null == vehicleType) {
return carDistanceTimeMap;
}
switch (vehicleType) {
case 1:
return carDistanceTimeMap;
case 2:
return electricBicycleDistanceTimeMap;
case 3:
return bicycleDistanceTimeMap;
case 4:
return walkDistanceTimeMap;
}
return carDistanceTimeMap;
}
public int getPathTimeTo(Integer vehicleType, Location location) {
if (null == vehicleType) {
return carDistanceTimeMap.get(location).intValue() / 60;
}
switch (vehicleType) {
case 1:
return carDistanceTimeMap.get(location).intValue() / 60;
case 2:
return electricBicycleDistanceTimeMap.get(location).intValue() / 60;
case 3:
return bicycleDistanceTimeMap.get(location).intValue() / 60;
case 4:
return walkDistanceTimeMap.get(location).intValue() / 60;
}
return carDistanceTimeMap.get(location).intValue() / 60;
}
/**
* time to the given location in minutes.
*
* @param location other location
* @return time in minutes
*/
public int getPathTimeTo(Location location) {
return distanceTimeMap.get(location).intValue()/60;
public int getCarPathTimeTo(Location location) {
return carDistanceTimeMap.get(location).intValue() / 60;
}
public int getElectricBicyclePathTimeTo(Location location) {
return electricBicycleDistanceTimeMap.get(location).intValue() / 60;
}
public int getBicyclePathTimeTo(Location location) {
return bicycleDistanceTimeMap.get(location).intValue() / 60;
}
public int getWalkDathTimeTo(Location location) {
return walkDistanceTimeMap.get(location).intValue() / 60;
}
// ************************************************************************
......@@ -110,5 +191,4 @@ public class Location {
'}';
}
}
......@@ -44,6 +44,9 @@ public class Technician {
// 单位是米,这里要注意
private int maxDistanceMeter;
// 交通方式 1汽车;2电动车;3自行车;4步行 默认是汽车
private Integer vehicleType;
@PlanningListVariable
private List<Customer> customerList = new ArrayList<>();
......@@ -76,6 +79,20 @@ public class Technician {
this.maxDistanceMeter = maxDistanceMeter;
this.preferredlocationDistanceMap = preferredlocationDistanceMap;
}
public Technician(long id, String code, int maxCount, int maxMinute, int maxDistanceMeter, Integer vehicleType, Depot depot,
int startTime, int endTime, Set<String> skills, Map<String, Long> preferredlocationDistanceMap) {
this.id = id;
this.code = code;
this.depot = depot;
this.startTime = startTime;
this.endTime = endTime;
this.skills = skills;
this.maxCount = maxCount;
this.maxMinute = maxMinute;
this.maxDistanceMeter = maxDistanceMeter;
this.preferredlocationDistanceMap = preferredlocationDistanceMap;
}
// ************************************************************************
// Complex methods
......@@ -114,10 +131,10 @@ public class Technician {
Location previousLocation = depot.getLocation();
for (Customer customer : customerList) {
totalDistance += previousLocation.getDistanceTo(customer.getLocation());
totalDistance += previousLocation.getDistanceTo(this.getVehicleType(),customer.getLocation());
previousLocation = customer.getLocation();
}
totalDistance += previousLocation.getDistanceTo(depot.getLocation());
totalDistance += previousLocation.getDistanceTo(this.getVehicleType(), depot.getLocation());
return totalDistance;
}
......
......@@ -210,8 +210,8 @@ public class BatchServiceImpl implements BatchService {
jdbcTemplate.update("delete from dispatch_order where team_id=? and batch_no=?", teamId, batchNo);
log.info("写入新批次技术员、工单数据, teamId:{}, day:{}, batchNo:{}", teamId, batchDay, batchNo);
String sqlEngineer = "INSERT INTO dispatch_engineer (team_id, batch_no, engineer_code, engineer_name, x, y, max_num, max_minute, max_distance)\n"
+ "SELECT o.team_id,?,o.engineer_code, a.name , b.x, b.y , max_num, max_minute, max_distance FROM `org_team_engineer` o,engineer_info a,engineer_business b \r\n"
String sqlEngineer = "INSERT INTO dispatch_engineer (team_id, batch_no, engineer_code, engineer_name, x, y, max_num, max_minute, max_distance, vehicle_type)\n"
+ "SELECT o.team_id,?,o.engineer_code, a.name , b.x, b.y , max_num, max_minute, max_distance, b.vehicle FROM `org_team_engineer` o,engineer_info a,engineer_business b \r\n"
+ " WHERE o.team_id=? AND `status`=1\r\n"
+ " AND o.engineer_code=a.engineer_code AND a.engineer_code = b.engineer_code \r\n"
+ " AND b.x IS NOT NULL AND b.x !=''" + " order by a.engineer_code asc";
......
......@@ -85,107 +85,108 @@ public class SolveServiceImpl implements SolveService {
// 按小组、批次号组装问题对象
@Override
public DispatchSolution prepareSolution(String groupId, String batchNo) {
log.info("组织问题对象, groupId:{}, batchNo:{}", groupId, batchNo);
entityManager.clear();
// 统一出发地
Depot oneDepot;
Optional<OrgGroup> optional = groupRepository.findByGroupId(groupId);
if (optional.isEmpty()) {
log.error("组织问题对象, 未查询到组织信息 ,groupId:{}, batchNo:{}", groupId, batchNo);
throw new RuntimeException(String.format("组织问题对象, 未查询到组织信息 ,groupId:%s, batchNo:%s", groupId, batchNo));
}
OrgGroup oneGroup = optional.get();
Location deptLocation = new Location(oneGroup.getId(), oneGroup.getGroupId(), "起点", Double.parseDouble(oneGroup.getX()), Double.parseDouble(oneGroup.getY()));
oneDepot = new Depot(oneGroup.getId(), oneGroup.getGroupId(), deptLocation, 60 * 8, 60 * 18);
// customerlist
ArrayList<Customer> customerList = new ArrayList<>();
// 已分配和未分配一起排班,因为已分配会影响整体排班结果
List<DispatchOrder> dispatchOrderList = dispatchOrderRepo.findAll(groupId, batchNo);
// List<DispatchOrder> dispatchOrderList = dispatchOrderRepo.findNotAssigned(groupId, batchNo);
log.info("组织问题对象, dispatchorder-list, groupId:{}, batchNo:{}, dispatchorder-size:{}", groupId, batchNo, dispatchOrderList.size());
if (dispatchOrderList.isEmpty()) {
log.error("组织问题对象, 未查询到工单信息 ,groupId:{}, batchNo:{}", groupId, batchNo);
}
dispatchOrderList.forEach(order -> {
Location location = new Location(order.getId(), order.getOrderId(), "工单", Double.parseDouble(order.getX()), Double.parseDouble(order.getY()));
LocalDateTime ldt1 = dateToLocalDateTime(order.getExpectTimeBegin());
LocalDateTime ldt2 = dateToLocalDateTime(order.getExpectTimeEnd());
int start = 60 * 8;
int end = 60 * 18;
if (ldt1 != null) {
start = ldt1.getHour() * 60 + ldt1.getMinute();
}
if (ldt2 != null) {
end = ldt2.getHour() * 60 + ldt2.getMinute();
}
// 40分钟兜低(技能未能正确匹配原因) FIXME 需要跟客户沟通
if (null == order.getTakeTime()) {
order.setTakeTime(40);
}
if (null == order.getTags()) {
order.setTags("");
}
if (null == order.getPriority()) {
order.setPriority(0);
}
Customer customer = new Customer(order.getId(), order.getOrderId(), order.getDt(), location, start, end, order.getSkills(), order.getTakeTime());
customerList.add(customer);
});
log.info("组织问题对象, customer-list, groupId:{}, batchNo:{}, customer-list:{}", groupId, batchNo, customerList.size());
// technicianList
ArrayList<Technician> technicianList = new ArrayList<>();
dispatchEngineerRepo.findByGroupIdAndBatchNo(groupId, batchNo).forEach(engineer -> {
Location location = new Location(engineer.getId(), engineer.getEngineerCode(), "中心点", Double.parseDouble(engineer.getX()), Double.parseDouble(engineer.getY()));
// Depot depot = new Depot(engineer.getId(), engineer.getEngineerCode(), location, 60 * 8, 60 * 18);
// depotList.add(depot);
// log.debug("组织问题对象, technicianList groupId:{}, batchNo:{}, engineer-code:{}", groupId, batchNo, engineer.getEngineerCode());
List<String> skillList = queryEngineerSkills(engineer.getEngineerCode());
// log.debug("组织问题对象, technicianList groupId:{}, batchNo:{}, engineer-code:{} , skills:{}", groupId, batchNo, engineer.getEngineerCode(), String.join(";", skillList));
// 距离偏好map
Map<String, Long> preferedLoctionDistanceMap = new HashMap<String, Long>();
customerList.forEach(customer -> {
long distance = distanceCalculator.calculateDistance(location, customer.getLocation());
preferedLoctionDistanceMap.put(customer.getCode(), distance);
});
Technician vehicle = new Technician(engineer.getId(), engineer.getEngineerCode(), engineer.getMaxNum(), engineer.getMaxMinute(), engineer.getMaxDistance() * 1000, oneDepot, 60 * 8, 60 * 18, Set.copyOf(skillList), preferedLoctionDistanceMap);
technicianList.add(vehicle);
});
log.info("组织问题对象, depotList-list, groupId:{}, batchNo:{}", groupId, batchNo);
log.info("组织问题对象, technician-list, groupId:{}, batchNo:{}, technician-list:{}", groupId, batchNo, technicianList.size());
// locationlist 起点+订单地点
List<Location> locationList = Stream.concat(Lists.newArrayList(oneDepot).stream().map(Depot::getLocation), customerList.stream().map(Customer::getLocation)).collect(Collectors.toList());
DispatchSolution solution = new DispatchSolution(groupId, batchNo, locationList, oneDepot, technicianList, customerList);
// path 路网数据初始化,FIXME 需要专门路网数据缓存库
long time1 = System.currentTimeMillis();
distanceCalculator.initDistanceMaps(locationList);
long time2 = System.currentTimeMillis();
log.info("组织问题对象 done, groupId:{}, batchNo:{}, technician-size:{}, customer-size:{}, location-size:{}, 路网耗时path:{}ms", groupId, batchNo, technicianList.size(), customerList.size(), locationList.size(), time2-time1);
return solution;
return null;
// log.info("组织问题对象, groupId:{}, batchNo:{}", groupId, batchNo);
//
// entityManager.clear();
//
// // 统一出发地
// Depot oneDepot;
// Optional<OrgGroup> optional = groupRepository.findByGroupId(groupId);
// if (optional.isEmpty()) {
// log.error("组织问题对象, 未查询到组织信息 ,groupId:{}, batchNo:{}", groupId, batchNo);
// throw new RuntimeException(String.format("组织问题对象, 未查询到组织信息 ,groupId:%s, batchNo:%s", groupId, batchNo));
// }
//
// OrgGroup oneGroup = optional.get();
// Location deptLocation = new Location(oneGroup.getId(), oneGroup.getGroupId(), "起点", Double.parseDouble(oneGroup.getX()), Double.parseDouble(oneGroup.getY()));
// oneDepot = new Depot(oneGroup.getId(), oneGroup.getGroupId(), deptLocation, 60 * 8, 60 * 18);
//
//
// // customerlist
// ArrayList<Customer> customerList = new ArrayList<>();
// // 已分配和未分配一起排班,因为已分配会影响整体排班结果
// List<DispatchOrder> dispatchOrderList = dispatchOrderRepo.findAll(groupId, batchNo);
// // List<DispatchOrder> dispatchOrderList = dispatchOrderRepo.findNotAssigned(groupId, batchNo);
//
// log.info("组织问题对象, dispatchorder-list, groupId:{}, batchNo:{}, dispatchorder-size:{}", groupId, batchNo, dispatchOrderList.size());
//
// if (dispatchOrderList.isEmpty()) {
// log.error("组织问题对象, 未查询到工单信息 ,groupId:{}, batchNo:{}", groupId, batchNo);
// }
//
// dispatchOrderList.forEach(order -> {
// Location location = new Location(order.getId(), order.getOrderId(), "工单", Double.parseDouble(order.getX()), Double.parseDouble(order.getY()));
//
// LocalDateTime ldt1 = dateToLocalDateTime(order.getExpectTimeBegin());
// LocalDateTime ldt2 = dateToLocalDateTime(order.getExpectTimeEnd());
// int start = 60 * 8;
// int end = 60 * 18;
// if (ldt1 != null) {
// start = ldt1.getHour() * 60 + ldt1.getMinute();
// }
// if (ldt2 != null) {
// end = ldt2.getHour() * 60 + ldt2.getMinute();
// }
//
//
// // 40分钟兜低(技能未能正确匹配原因) FIXME 需要跟客户沟通
// if (null == order.getTakeTime()) {
// order.setTakeTime(40);
// }
// if (null == order.getTags()) {
// order.setTags("");
// }
// if (null == order.getPriority()) {
// order.setPriority(0);
// }
//
// Customer customer = new Customer(order.getId(), order.getOrderId(), order.getDt(), location, start, end, order.getSkills(), order.getTakeTime());
//
// customerList.add(customer);
// });
//
// log.info("组织问题对象, customer-list, groupId:{}, batchNo:{}, customer-list:{}", groupId, batchNo, customerList.size());
//
// // technicianList
// ArrayList<Technician> technicianList = new ArrayList<>();
// dispatchEngineerRepo.findByGroupIdAndBatchNo(groupId, batchNo).forEach(engineer -> {
// Location location = new Location(engineer.getId(), engineer.getEngineerCode(), "中心点", Double.parseDouble(engineer.getX()), Double.parseDouble(engineer.getY()));
//// Depot depot = new Depot(engineer.getId(), engineer.getEngineerCode(), location, 60 * 8, 60 * 18);
//// depotList.add(depot);
//
//// log.debug("组织问题对象, technicianList groupId:{}, batchNo:{}, engineer-code:{}", groupId, batchNo, engineer.getEngineerCode());
// List<String> skillList = queryEngineerSkills(engineer.getEngineerCode());
//
//// log.debug("组织问题对象, technicianList groupId:{}, batchNo:{}, engineer-code:{} , skills:{}", groupId, batchNo, engineer.getEngineerCode(), String.join(";", skillList));
//
// // 距离偏好map
// Map<String, Long> preferedLoctionDistanceMap = new HashMap<String, Long>();
// customerList.forEach(customer -> {
// long distance = distanceCalculator.calculateDistance(location, customer.getLocation());
// preferedLoctionDistanceMap.put(customer.getCode(), distance);
// });
//
// Technician vehicle = new Technician(engineer.getId(), engineer.getEngineerCode(), engineer.getMaxNum(), engineer.getMaxMinute(), engineer.getMaxDistance() * 1000, oneDepot, 60 * 8, 60 * 18, Set.copyOf(skillList), preferedLoctionDistanceMap);
// technicianList.add(vehicle);
// });
//
// log.info("组织问题对象, depotList-list, groupId:{}, batchNo:{}", groupId, batchNo);
// log.info("组织问题对象, technician-list, groupId:{}, batchNo:{}, technician-list:{}", groupId, batchNo, technicianList.size());
//
// // locationlist 起点+订单地点
// List<Location> locationList = Stream.concat(Lists.newArrayList(oneDepot).stream().map(Depot::getLocation), customerList.stream().map(Customer::getLocation)).collect(Collectors.toList());
//
// DispatchSolution solution = new DispatchSolution(groupId, batchNo, locationList, oneDepot, technicianList, customerList);
//
// // path 路网数据初始化,FIXME 需要专门路网数据缓存库
// long time1 = System.currentTimeMillis();
// distanceCalculator.initDistanceMaps(locationList);
// long time2 = System.currentTimeMillis();
//
// log.info("组织问题对象 done, groupId:{}, batchNo:{}, technician-size:{}, customer-size:{}, location-size:{}, 路网耗时path:{}ms", groupId, batchNo, technicianList.size(), customerList.size(), locationList.size(), time2-time1);
//
// return solution;
}
......@@ -275,9 +276,12 @@ public class SolveServiceImpl implements SolveService {
preferedLoctionDistanceMap.put(customer.getCode(), distance);
});
// FIXME 硬约束:电动车固定40km上限,其他无限制
Technician vehicle = new Technician(engineer.getId(), engineer.getEngineerCode(), engineer.getMaxNum(), engineer.getMaxMinute(), engineer.getMaxDistance() * 1000, oneDepot, 60 * 8, 60 * 18, Set.copyOf(skillList), preferedLoctionDistanceMap);
// 硬约束:电动车固定40km上限,其他无限制
int maxDistance = engineer.getMaxDistance() * 1000;
if (engineer.getVehicleType() != null && engineer.getVehicleType() == 2) {
maxDistance = 40 * 1000;
}
Technician vehicle = new Technician(engineer.getId(), engineer.getEngineerCode(), engineer.getMaxNum(), engineer.getMaxMinute(), maxDistance, engineer.getVehicleType() , oneDepot, 60 * 8, 60 * 18, Set.copyOf(skillList), preferedLoctionDistanceMap);
technicianList.add(vehicle);
});
......@@ -291,8 +295,12 @@ public class SolveServiceImpl implements SolveService {
// path 路网数据初始化,FIXME 需要专门路网数据缓存库
long time1 = System.currentTimeMillis();
distanceCalculator.initDistanceMaps(locationList);
long time2 = System.currentTimeMillis();
// 根据不同的交通工具,初始化不同的路网数据
List<Integer> vehicleTypes = technicianList.stream()
.map(tec -> tec.getVehicleType() == null ? 1 : tec.getVehicleType()).distinct()
.collect(Collectors.toList());
distanceCalculator.initDistanceMaps(locationList, vehicleTypes);
long time2 = System.currentTimeMillis();
log.info("组织问题对象 done, teamId:{}, batchNo:{}, technician-size:{}, customer-size:{}, location-size:{}, 路网耗时path:{}ms", teamId, batchNo, technicianList.size(), customerList.size(), locationList.size(), time2-time1);
......
......@@ -240,7 +240,7 @@ public class DataUtils {
Location locationi = locationIndex.get(i + 1);
for (int j = 0; j < pathMatrix[i].length; j++) {
Location locationj = locationIndex.get(j + 1);
locationi.getDistanceMap().put(locationj, pathMatrix[i][j]);
locationi.getDistanceMap(1).put(locationj, pathMatrix[i][j]);
}
}
......@@ -259,7 +259,7 @@ public class DataUtils {
Location locationi = locationIndex.get(i + 1);
for (int j = 0; j < pathTimeMatrix[i].length; j++) {
Location locationj = locationIndex.get(j + 1);
locationi.getDistanceTimeMap().put(locationj, pathTimeMatrix[i][j]);
locationi.getDistanceTimeMap(1).put(locationj, pathTimeMatrix[i][j]);
}
}
......
......@@ -72,12 +72,12 @@ public class DispatchSolutionUtils {
startPath = technician.getDepot().getStartTime();
// endPath = startPath +
// customer.getLocation().getPathTimeTo(technician.getDepot().getLocation());
endPath = startPath + technician.getDepot().getLocation().getPathTimeTo(customer.getLocation());
endPath = startPath + technician.getDepot().getLocation().getPathTimeTo(technician.getVehicleType(),customer.getLocation());
} else {
startPath = previousCustomer.getDepartureTime();
// endPath = startPath +
// customer.getLocation().getPathTimeTo(previousCustomer.getLocation());
endPath = startPath + previousCustomer.getLocation().getPathTimeTo(customer.getLocation());
endPath = startPath + previousCustomer.getLocation().getPathTimeTo(technician.getVehicleType(),customer.getLocation());
}
if (customer.getArrivalTime() > customer.getEndTime()) {
......
......@@ -26,7 +26,7 @@ import lombok.Data;
*/
public class RoadDistanceUtils {
public static String URL = "https://api.map.baidu.com/routematrix/v2/riding?";
public static String URL = "https://api.map.baidu.com/routematrix/v2/";
public static String AK = "doR30pE7R0I7ivGLwMpkpsTT4bos9Akg";
/**
......@@ -42,20 +42,21 @@ public class RoadDistanceUtils {
*
* @param from
* @param to
* @param vehicleType 不能为空
* @return
*/
public static Distance getDistance(Location from, Location to) {
public static Distance getDistance(Location from, Location to, int vehicleType) {
try {
String key = from.getLongitude() + "," + from.getLatitude() + ";" + to.getLongitude() + ","
+ to.getLatitude();
+ to.getLatitude() + "|" + vehicleType;
Distance distance = distanceCache.get(key);
if (null == distance) {
distance = getDistance(from.getLatitude() + "," + from.getLongitude(),
to.getLatitude() + "," + to.getLongitude());
if(null == distance) {
to.getLatitude() + "," + to.getLongitude(), vehicleType);
if (null == distance) {
Distance dis = new Distance();
return dis;
}else {
} else {
distanceCache.put(key, distance);
}
return distance;
......@@ -68,14 +69,34 @@ public class RoadDistanceUtils {
}
}
private static Distance getDistance(String yx1, String yx2) throws Exception {
private static Distance getDistance(String yx1, String yx2, int vehicleType) throws Exception {
Map<String, String> params = new HashMap<String, String>();
params.put("origins", yx1);
params.put("destinations", yx2);
params.put("ak", AK);
params.put("riding_type", "1");// 电动自行车
params.put("coord_type", "gcj02");
String text = requestGetAK(URL, params);
String url = "";
switch (vehicleType) {
case 1:
url = URL + "driving?";
break;
case 2:
params.put("riding_type", "1");// 电动自行车
url = URL + "riding?";
break;
case 3:
params.put("riding_type", "0");// 普通自行车
url = URL + "riding?";
break;
case 4:
url = URL + "walking?";
break;
}
String text = requestGetAK(url, params);
BDResult webResult = gson.fromJson(text, BDResult.class);
float dis = webResult.getResult().get(0).getDistance().getValue() / 1000F;
int time = webResult.getResult().get(0).getDuration().getValue();
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!