mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add json stuff
This commit is contained in:
parent
b4ae11631b
commit
ed1361482e
2 changed files with 86 additions and 36 deletions
|
|
@ -66,6 +66,11 @@ public class JsonConstants {
|
||||||
|
|
||||||
public static final String TIME_WINDOW = "time_window";
|
public static final String TIME_WINDOW = "time_window";
|
||||||
|
|
||||||
|
public static final String TYPE = "type";
|
||||||
|
|
||||||
|
public static final String PICKUP = "pickup";
|
||||||
|
|
||||||
|
public static final String DELIVERY = "delivery";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Vehicle {
|
public static class Vehicle {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,9 @@ package jsprit.core.problem.io;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.job.Delivery;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
|
import jsprit.core.problem.job.Pickup;
|
||||||
import jsprit.core.problem.job.Service;
|
import jsprit.core.problem.job.Service;
|
||||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
@ -37,7 +39,7 @@ import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by schroeder on 04.11.14.
|
* Reads vehicle routing problem from json file.
|
||||||
*/
|
*/
|
||||||
public class VrpJsonReader {
|
public class VrpJsonReader {
|
||||||
|
|
||||||
|
|
@ -49,6 +51,13 @@ public class VrpJsonReader {
|
||||||
this.vrpBuilder = vrpBuilder;
|
this.vrpBuilder = vrpBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads json file.
|
||||||
|
*
|
||||||
|
* @param jsonFile to be read
|
||||||
|
* @throws java.lang.IllegalStateException if there is a service without id and proper location spec OR
|
||||||
|
* if there is a vehicle without id and proper location spec OR if there is a vehicle type without id
|
||||||
|
*/
|
||||||
public void read(String jsonFile){
|
public void read(String jsonFile){
|
||||||
JsonNode root = buildTree_and_getRoot(jsonFile);
|
JsonNode root = buildTree_and_getRoot(jsonFile);
|
||||||
setFleetSize(root);
|
setFleetSize(root);
|
||||||
|
|
@ -69,15 +78,26 @@ public class VrpJsonReader {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param root node
|
||||||
|
* @throws java.lang.IllegalStateException if service id is missing OR neither location id nor location coordinate are set
|
||||||
|
*/
|
||||||
private void parse_services(JsonNode root) {
|
private void parse_services(JsonNode root) {
|
||||||
JsonNode services = root.path(JsonConstants.SERVICES);
|
JsonNode services = root.path(JsonConstants.SERVICES);
|
||||||
for(JsonNode serviceNode : services){
|
for(JsonNode serviceNode : services){
|
||||||
|
//type
|
||||||
|
JsonNode typeNode = serviceNode.path(JsonConstants.Job.TYPE);
|
||||||
|
//service id
|
||||||
JsonNode jobIdNode = serviceNode.path(JsonConstants.Job.ID);
|
JsonNode jobIdNode = serviceNode.path(JsonConstants.Job.ID);
|
||||||
if(jobIdNode.isMissingNode()){
|
if(jobIdNode.isMissingNode()) throw new IllegalStateException("service-id is missing");
|
||||||
throw new IllegalStateException("service-id is missing");
|
|
||||||
}
|
|
||||||
Service.Builder serviceBuilder = Service.Builder.newInstance(jobIdNode.asText());
|
|
||||||
|
|
||||||
|
Service.Builder serviceBuilder;
|
||||||
|
if(typeNode.isMissingNode()) serviceBuilder = Service.Builder.newInstance(jobIdNode.asText());
|
||||||
|
else if(typeNode.asText().equals(JsonConstants.Job.PICKUP)) serviceBuilder = Pickup.Builder.newInstance(jobIdNode.asText());
|
||||||
|
else if(typeNode.asText().equals(JsonConstants.Job.DELIVERY)) serviceBuilder = Delivery.Builder.newInstance(jobIdNode.asText());
|
||||||
|
else throw new IllegalStateException("type of service ("+typeNode.asText()+") is not supported");
|
||||||
|
|
||||||
|
//service address
|
||||||
JsonNode addressIdNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.ID);
|
JsonNode addressIdNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.ID);
|
||||||
boolean either_locationId_or_coord = false;
|
boolean either_locationId_or_coord = false;
|
||||||
if(!addressIdNode.isMissingNode()){
|
if(!addressIdNode.isMissingNode()){
|
||||||
|
|
@ -85,24 +105,26 @@ public class VrpJsonReader {
|
||||||
either_locationId_or_coord = true;
|
either_locationId_or_coord = true;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Double lon = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.LON).asDouble();
|
JsonNode lonNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.LON);
|
||||||
Double lat = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.LAT).asDouble();
|
JsonNode latNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.LAT);
|
||||||
if (lon != null && lat != null) {
|
if (!lonNode.isMissingNode() && !latNode.isMissingNode()) {
|
||||||
serviceBuilder.setCoord(Coordinate.newInstance(lon, lat));
|
serviceBuilder.setCoord(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
||||||
either_locationId_or_coord = true;
|
either_locationId_or_coord = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!either_locationId_or_coord) throw new IllegalStateException("location missing. either locationId or locationCoordinate is required");
|
if(!either_locationId_or_coord) throw new IllegalStateException("location missing. either locationId or locationCoordinate is required");
|
||||||
|
//service name
|
||||||
serviceBuilder.setName(serviceNode.path(JsonConstants.Job.NAME).asText());
|
JsonNode nameNode = serviceNode.path(JsonConstants.Job.NAME);
|
||||||
|
if(!nameNode.isMissingNode()) serviceBuilder.setName(nameNode.asText());
|
||||||
|
//service duration
|
||||||
serviceBuilder.setServiceTime(serviceNode.path(JsonConstants.Job.SERVICE_DURATION).asDouble());
|
serviceBuilder.setServiceTime(serviceNode.path(JsonConstants.Job.SERVICE_DURATION).asDouble());
|
||||||
|
//service tw
|
||||||
Double tw_start = serviceNode.path(JsonConstants.Job.TIME_WINDOW).path(JsonConstants.TimeWindow.START).asDouble();
|
JsonNode start_tw_node = serviceNode.path(JsonConstants.Job.TIME_WINDOW).path(JsonConstants.TimeWindow.START);
|
||||||
Double tw_end = serviceNode.path(JsonConstants.Job.TIME_WINDOW).path(JsonConstants.TimeWindow.END).asDouble();
|
JsonNode end_tw_node = serviceNode.path(JsonConstants.Job.TIME_WINDOW).path(JsonConstants.TimeWindow.END);
|
||||||
if(tw_start != null && tw_end != null){
|
if(!start_tw_node.isMissingNode() && !end_tw_node.isMissingNode()){
|
||||||
serviceBuilder.setTimeWindow(TimeWindow.newInstance(tw_start,tw_end));
|
serviceBuilder.setTimeWindow(TimeWindow.newInstance(start_tw_node.asDouble(),end_tw_node.asDouble()));
|
||||||
}
|
}
|
||||||
|
//service size
|
||||||
JsonNode sizeNode = serviceNode.path(JsonConstants.Job.SIZE);
|
JsonNode sizeNode = serviceNode.path(JsonConstants.Job.SIZE);
|
||||||
int size_index = 0;
|
int size_index = 0;
|
||||||
for(JsonNode sizeValNode : sizeNode){
|
for(JsonNode sizeValNode : sizeNode){
|
||||||
|
|
@ -110,46 +132,64 @@ public class VrpJsonReader {
|
||||||
serviceBuilder.addSizeDimension(size_index,size_value);
|
serviceBuilder.addSizeDimension(size_index,size_value);
|
||||||
size_index++;
|
size_index++;
|
||||||
}
|
}
|
||||||
|
//service skills
|
||||||
JsonNode reqSkills = serviceNode.path(JsonConstants.Job.SKILLS);
|
JsonNode reqSkills = serviceNode.path(JsonConstants.Job.SKILLS);
|
||||||
for(JsonNode skillNode : reqSkills){
|
for(JsonNode skillNode : reqSkills){
|
||||||
serviceBuilder.addRequiredSkill(skillNode.asText());
|
serviceBuilder.addRequiredSkill(skillNode.asText());
|
||||||
}
|
}
|
||||||
|
//add service
|
||||||
vrpBuilder.addJob(serviceBuilder.build());
|
vrpBuilder.addJob(serviceBuilder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param root node
|
||||||
|
* @throws java.lang.IllegalStateException if vehicle id is missing OR if neither start location id nor start location
|
||||||
|
* coordinate are set
|
||||||
|
*/
|
||||||
private void parse_vehicles(JsonNode root) {
|
private void parse_vehicles(JsonNode root) {
|
||||||
JsonNode vehicles = root.path(JsonConstants.VEHICLES);
|
JsonNode vehicles = root.path(JsonConstants.VEHICLES);
|
||||||
|
|
||||||
for(JsonNode vehicleNode : vehicles){
|
for(JsonNode vehicleNode : vehicles){
|
||||||
// JsonNode vehicleNode = vehicle_iterator.next();
|
//vehicle id
|
||||||
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicleNode.path(JsonConstants.Vehicle.ID).asText());
|
JsonNode vehicle_id_node = vehicleNode.path(JsonConstants.Vehicle.ID);
|
||||||
|
if(vehicle_id_node.isMissingNode()) throw new IllegalStateException("vehicle id missing");
|
||||||
|
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicle_id_node.asText());
|
||||||
|
//vehicle type
|
||||||
VehicleType type = vehicle_type_map.get(vehicleNode.path(JsonConstants.Vehicle.TYPE_ID).asText());
|
VehicleType type = vehicle_type_map.get(vehicleNode.path(JsonConstants.Vehicle.TYPE_ID).asText());
|
||||||
vehicleBuilder.setType(type);
|
vehicleBuilder.setType(type);
|
||||||
|
//earliest start
|
||||||
JsonNode earliestStartNode = vehicleNode.path(JsonConstants.Vehicle.EARLIEST_START);
|
JsonNode earliestStartNode = vehicleNode.path(JsonConstants.Vehicle.EARLIEST_START);
|
||||||
if(!earliestStartNode.isMissingNode()) vehicleBuilder.setEarliestStart(earliestStartNode.asDouble());
|
if(!earliestStartNode.isMissingNode()) vehicleBuilder.setEarliestStart(earliestStartNode.asDouble());
|
||||||
|
//latest end
|
||||||
JsonNode latestEndNode = vehicleNode.path(JsonConstants.Vehicle.LATEST_END);
|
JsonNode latestEndNode = vehicleNode.path(JsonConstants.Vehicle.LATEST_END);
|
||||||
if(!latestEndNode.isMissingNode()) vehicleBuilder.setLatestArrival(latestEndNode.asDouble());
|
if(!latestEndNode.isMissingNode()) vehicleBuilder.setLatestArrival(latestEndNode.asDouble());
|
||||||
|
//start
|
||||||
String startLocationId = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.ID).asText();
|
//location id
|
||||||
vehicleBuilder.setStartLocationId(startLocationId);
|
boolean either_id_or_coord = false;
|
||||||
JsonNode endAddressId = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.ID);
|
JsonNode startAddressId = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.ID);
|
||||||
if(!endAddressId.isMissingNode()){
|
if(!startAddressId.isMissingNode()){
|
||||||
if(!startLocationId.equals(endAddressId.asText())){
|
vehicleBuilder.setStartLocationId(startAddressId.asText());
|
||||||
vehicleBuilder.setEndLocationId(endAddressId.asText());
|
either_id_or_coord = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//location coordinate
|
||||||
{
|
{
|
||||||
JsonNode lonNode = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.LON);
|
JsonNode lonNode = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.LON);
|
||||||
JsonNode latNode = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.LAT);
|
JsonNode latNode = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.LAT);
|
||||||
if (!lonNode.isMissingNode() && !latNode.isMissingNode()) {
|
if (!lonNode.isMissingNode() && !latNode.isMissingNode()) {
|
||||||
vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
||||||
|
either_id_or_coord = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!either_id_or_coord) throw new IllegalStateException("start location of vehicle missing. either id or coordinate required");
|
||||||
|
//end
|
||||||
|
//location id
|
||||||
|
JsonNode endAddressId = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.ID);
|
||||||
|
if(!endAddressId.isMissingNode()){
|
||||||
|
if(!startAddressId.asText().equals(endAddressId.asText())){
|
||||||
|
vehicleBuilder.setEndLocationId(endAddressId.asText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//location coordinate
|
||||||
{
|
{
|
||||||
JsonNode lonNode = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.LON);
|
JsonNode lonNode = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.LON);
|
||||||
JsonNode latNode = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.LAT);
|
JsonNode latNode = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.LAT);
|
||||||
|
|
@ -157,23 +197,28 @@ public class VrpJsonReader {
|
||||||
vehicleBuilder.setEndLocationCoordinate(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
vehicleBuilder.setEndLocationCoordinate(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//skills
|
||||||
JsonNode skillsNode = vehicleNode.path(JsonConstants.Vehicle.SKILLS);
|
JsonNode skillsNode = vehicleNode.path(JsonConstants.Vehicle.SKILLS);
|
||||||
for(JsonNode skillNode : skillsNode){
|
for(JsonNode skillNode : skillsNode){
|
||||||
String skill = skillNode.asText();
|
String skill = skillNode.asText();
|
||||||
vehicleBuilder.addSkill(skill);
|
vehicleBuilder.addSkill(skill);
|
||||||
}
|
}
|
||||||
|
|
||||||
VehicleImpl vehicle = vehicleBuilder.build();
|
vrpBuilder.addVehicle(vehicleBuilder.build());
|
||||||
vrpBuilder.addVehicle(vehicle);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param root node
|
||||||
|
* @throws java.lang.IllegalStateException if type id is missing
|
||||||
|
*/
|
||||||
private void parse_and_map_vehicle_types(JsonNode root) {
|
private void parse_and_map_vehicle_types(JsonNode root) {
|
||||||
JsonNode types = root.path(JsonConstants.VEHICLE_TYPES);
|
JsonNode types = root.path(JsonConstants.VEHICLE_TYPES);
|
||||||
for(JsonNode typeNode : types){
|
for(JsonNode typeNode : types){
|
||||||
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeNode.path(JsonConstants.Vehicle.Type.ID).asText());
|
JsonNode typeIdNode = typeNode.path(JsonConstants.Vehicle.Type.ID);
|
||||||
|
if(typeIdNode.isMissingNode()) throw new IllegalStateException("type id missing");
|
||||||
|
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeIdNode.asText());
|
||||||
typeBuilder.setFixedCost(typeNode.path(JsonConstants.Vehicle.Type.FIXED_COSTS).asDouble());
|
typeBuilder.setFixedCost(typeNode.path(JsonConstants.Vehicle.Type.FIXED_COSTS).asDouble());
|
||||||
typeBuilder.setCostPerDistance(typeNode.path(JsonConstants.Vehicle.Type.DISTANCE).asDouble());
|
typeBuilder.setCostPerDistance(typeNode.path(JsonConstants.Vehicle.Type.DISTANCE).asDouble());
|
||||||
typeBuilder.setCostPerTime(typeNode.path(JsonConstants.Vehicle.Type.TIME).asDouble());
|
typeBuilder.setCostPerTime(typeNode.path(JsonConstants.Vehicle.Type.TIME).asDouble());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue