GraphHopper.com | Forum | GitHub | Maps | Blog

Outputting the solution to JSON


#1

Hey there,
I’m new to jSprit and I was wondering if it was possible, in any way, to output the given solution to a third party (like javascript on a front-end) and use the data there.

Thanks in advance.


#2

You can copy everything to a Jackson-annotated class, and serialize the resulting object/s.


#3

Oh I see, and how would i go to get the data from the solution?


#4

Start by calling VehicleRoutingProblemSolution.getRoutes(), then for each route get the activities, and so on.


#5

Thank you!


#6

Hi Mattia

I output the results to a JSON object with the solution routes, the statistics for the run, any jobs that I rejected for time windows during a pre-processing phase, any unallocated jobs and the likely reason for the unallocated jobs.

It calls PrintJSON which calls getJSON. I do that for a specific reason and you could skip the printJSON call and go straight to getJSON if it suits you.

I hope it helps and of course if you improve on it - I would like to hear about it.

regards
Grant

In the main function I call:

    bestSolution = Solutions.bestOf(solutions);
    return Utils.printJSON(problem,bestSolution, cm, stats,jobsRejectedForTimeWindow, reasonTracker );

And in Utils.printJSON I have:

public static String printJSON( VehicleRoutingProblem problem, VehicleRoutingProblemSolution solution, CostMatrix cm, JSONObject stats, List<String> rejections, UnassignedJobReasonTracker reasonTracker ){
JSONObject result = getJSON(problem, solution, cm, rejections, reasonTracker);
result.put("stats", stats);
return result.toJSONString();

}

And finally in getJSON:

public static JSONObject getJSON( VehicleRoutingProblem problem, VehicleRoutingProblemSolution solution, CostMatrix cm, List<String> rejections, UnassignedJobReasonTracker reasonTracker) {
		int routeNu = 1;
		List<VehicleRoute> list = new ArrayList<VehicleRoute>(solution.getRoutes());
		Collections.sort(list , new com.graphhopper.jsprit.core.util.VehicleIndexComparator());
		JSONObject output = new JSONObject();
		JSONArray routeJSONArray = new JSONArray();
		for (VehicleRoute route : list) {
			double costs = 0.0;
			int routeOrder = 1;
		JSONObject routeJson = null ; 
			TourActivity prevAct = route.getStart();
			for (TourActivity act : route.getActivities()) {
				String jobId;
				if (act instanceof TourActivity.JobActivity) {
					jobId = ((TourActivity.JobActivity) act).getJob().getId();
				} else {
					jobId = "-";
				}
				double c = problem.getTransportCosts().getTransportCost(prevAct.getLocation(), act.getLocation(), prevAct.getEndTime(), 
						route.getDriver(),
						route.getVehicle());
				costs += c;

				String distanceCostStr = cm.getDistance(prevAct.getLocation().getId(), act.getLocation().getId());
				JSONParser parser = new JSONParser();
				JSONObject toThis = null;
				try {
					toThis = (JSONObject)parser.parse(distanceCostStr);
				} catch (ParseException e) {
					e.printStackTrace();
				}
				double costPerDistanceUnit = ((VehicleType)route.getVehicle().getType()).getVehicleCostParams().perDistanceUnit;

				String distanceStr = toThis.get("distance").toString();
				double distanceCost = Double.parseDouble(distanceStr) * costPerDistanceUnit;

				routeJson = new JSONObject();
				routeJson.put("fromLocation", prevAct.getLocation().getId());
				routeJson.put("toLocation", act.getLocation().getId());
				routeJson.put("distanceToLocation", distanceStr);
				routeJson.put("size",  act.getSize().get(0));
				routeJson.put("routeNumber", routeNu);
				routeJson.put("routeOrder",  routeOrder);
				routeJson.put("deviceID", route.getVehicle().getId());
				routeJson.put("activity", act.getName());
				routeJson.put("jobID", jobId);
				routeJson.put("arriveTime",Math.round(act.getArrTime()));
				routeJson.put("endTime",Math.round(act.getEndTime()));
				routeJson.put("operationTime", act.getOperationTime());
				routeJson.put("timeOnSite", Math.round(act.getEndTime() - act.getArrTime()));
				routeJson.put("costb", Math.round(c));
				routeJson.put("cost", Math.round(distanceCost));    				
				//************************
				// get the distance in time and meters to the next point of delivery
				// unless we are on the last job.
				//************************
				JSONObject toNext = null;
				String nextJobId = "not a tour activity";
				TourActivity nextAct = Utils.getNextTourActivity(route, act);
				if (nextAct != null && nextAct instanceof TourActivity.JobActivity) {
					String toNextStr = cm.getDistance(act.getLocation().getId(),nextAct.getLocation().getId());
					nextJobId = ((TourActivity.JobActivity) nextAct).getJob().getId();
					parser = new JSONParser();
					try {
						toNext = (JSONObject)parser.parse(toNextStr);
					} catch (ParseException e) {
						e.printStackTrace();
					}
					// add it to the routeJson packet
					routeJson.put("distanceToNext", toNext.get("distance"));
					routeJson.put("timeToNext",  toNext.get("time"));
					routeJson.put("nextStop", nextJobId);
				} 
				routeJSONArray.add(routeJson);
				prevAct = act;
				routeOrder++;
			}
			// now get the end of route
			TourActivity lastone = route.getEnd();
			double c = problem.getTransportCosts().getTransportCost(prevAct.getLocation(), route.getEnd().getLocation(), prevAct.getEndTime(),
					route.getDriver(), route.getVehicle());
			c += problem.getActivityCosts().getActivityCost(route.getEnd(), route.getEnd().getArrTime(), route.getDriver(), route.getVehicle());
			costs += c;
			routeJson = new JSONObject();
			routeJson.put("routeNumber", routeNu);
			routeJson.put("routeOrder",  999);
			routeJson.put("deviceID", route.getVehicle().getId());
			routeJson.put("activity", route.getEnd().getName());
			routeJson.put("location",  route.getEnd().getLocation().getId());
			routeJson.put("jobID", "Route End - Return To Depot");
			routeJson.put("size",  0);
			routeJson.put("arriveTime",Math.round(Math.round(route.getEnd().getArrTime())));
			routeJson.put("endTime","undef");
			routeJson.put("cost", Math.round(costs));
			routeJSONArray.add(routeJson);
			routeNu++;
		}
		output.put("routes",routeJSONArray);
		routeJSONArray = new JSONArray();
		if (!solution.getUnassignedJobs().isEmpty()) {
			for (Job j : solution.getUnassignedJobs()) {
				JSONObject routeJson = new JSONObject();
				routeJson.put("jobID", j.getId());
				if(!reasonTracker.getMostLikelyReason(j.getId()).isEmpty()){
					routeJson.put("reasonCode", reasonTracker.getMostLikelyReasonCode(j.getId()));
					routeJson.put("reason", reasonTracker.getMostLikelyReason(j.getId()));
				}
				routeJSONArray.add(routeJson);
			}
		}
		// process rejected jobs

		if(rejections != null){
			for (String rejectedJob : rejections){
				JSONObject routeJson = new JSONObject();
				routeJson.put("jobID", rejectedJob);
				routeJSONArray.add(routeJson);
			}
		}
		if(!routeJSONArray.isEmpty())
			output.put("unresolved", routeJSONArray);

//		LOGGER.log(Level.INFO, output.toJSONString());
		return(output);
	}