Graphics2D g = createCanvas(width, height);
g.setFont(g.getFont().deriveFont((float) TEXT_SIZE));
g.setStroke(TangoColorFactory.NORMAL_STROKE);
for (Customer customer : solution.getCustomerList()) {
Location location = customer.getLocation();
int x = translator.translateLongitudeToX(location.getLongitude());
int y = translator.translateLatitudeToY(location.getLatitude());
g.setColor(TangoColorFactory.ALUMINIUM_4);
g.fillRect(x - 1, y - 1, 3, 3);
String demandString = Integer.toString(customer.getDemand());
g.drawString(demandString, x - (g.getFontMetrics().stringWidth(demandString) / 2), y - TEXT_SIZE/2);
if (customer instanceof TimeWindowedCustomer) {
TimeWindowedCustomer timeWindowedCustomer = (TimeWindowedCustomer) customer;
g.setColor(TangoColorFactory.ALUMINIUM_3);
int circleX = x - (TIME_WINDOW_DIAMETER / 2);
int circleY = y + 5;
g.drawOval(circleX, circleY, TIME_WINDOW_DIAMETER, TIME_WINDOW_DIAMETER);
g.fillArc(circleX, circleY, TIME_WINDOW_DIAMETER, TIME_WINDOW_DIAMETER,
90 - calculateTimeWindowDegree(maximumTimeWindowTime, timeWindowedCustomer.getReadyTime()),
calculateTimeWindowDegree(maximumTimeWindowTime, timeWindowedCustomer.getReadyTime())
- calculateTimeWindowDegree(maximumTimeWindowTime, timeWindowedCustomer.getDueTime()));
if (timeWindowedCustomer.getArrivalTime() != null) {
if (timeWindowedCustomer.isArrivalAfterDueTime()) {
g.setColor(TangoColorFactory.SCARLET_2);
} else if (timeWindowedCustomer.isArrivalBeforeReadyTime()) {
g.setColor(TangoColorFactory.ORANGE_2);
} else {
g.setColor(TangoColorFactory.ALUMINIUM_6);
}
g.setStroke(TangoColorFactory.THICK_STROKE);
int circleCenterY = y + 5 + TIME_WINDOW_DIAMETER / 2;
int angle = calculateTimeWindowDegree(maximumTimeWindowTime, timeWindowedCustomer.getArrivalTime());
g.drawLine(x, circleCenterY,
x + (int) (Math.sin(Math.toRadians(angle)) * (TIME_WINDOW_DIAMETER / 2 + 3)),
circleCenterY - (int) (Math.cos(Math.toRadians(angle)) * (TIME_WINDOW_DIAMETER / 2 + 3)));
g.setStroke(TangoColorFactory.NORMAL_STROKE);
}
}
}
g.setColor(TangoColorFactory.ALUMINIUM_3);
for (Depot depot : solution.getDepotList()) {
int x = translator.translateLongitudeToX(depot.getLocation().getLongitude());
int y = translator.translateLatitudeToY(depot.getLocation().getLatitude());
g.fillRect(x - 2, y - 2, 5, 5);
g.drawImage(depotImageIcon.getImage(),
x - depotImageIcon.getIconWidth() / 2, y - 2 - depotImageIcon.getIconHeight(), imageObserver);
}
int colorIndex = 0;
// TODO Too many nested for loops
for (Vehicle vehicle : solution.getVehicleList()) {
g.setColor(TangoColorFactory.SEQUENCE_2[colorIndex]);
Customer vehicleInfoCustomer = null;
int longestNonDepotDistance = -1;
int load = 0;
for (Customer customer : solution.getCustomerList()) {
if (customer.getPreviousStandstill() != null && customer.getVehicle() == vehicle) {
load += customer.getDemand();
Location previousLocation = customer.getPreviousStandstill().getLocation();
Location location = customer.getLocation();
translator.drawRoute(g, previousLocation.getLongitude(), previousLocation.getLatitude(),
location.getLongitude(), location.getLatitude(),
location instanceof AirLocation);
// Determine where to draw the vehicle info
int distance = customer.getDistanceFromPreviousStandstill();
if (customer.getPreviousStandstill() instanceof Customer) {
if (longestNonDepotDistance < distance) {
longestNonDepotDistance = distance;
vehicleInfoCustomer = customer;
}
} else if (vehicleInfoCustomer == null) {
// If there is only 1 customer in this chain, draw it on a line to the Depot anyway
vehicleInfoCustomer = customer;
}
// Line back to the vehicle depot
if (customer.getNextCustomer() == null) {
Location vehicleLocation = vehicle.getLocation();
g.setStroke(TangoColorFactory.FAT_DASHED_STROKE);
translator.drawRoute(g, location.getLongitude(), location.getLatitude(),
vehicleLocation.getLongitude(), vehicleLocation.getLatitude(),
location instanceof AirLocation);
g.setStroke(TangoColorFactory.NORMAL_STROKE);
}
}
}
// Draw vehicle info
if (vehicleInfoCustomer != null) {
if (load > vehicle.getCapacity()) {
g.setColor(TangoColorFactory.SCARLET_2);
}
Location previousLocation = vehicleInfoCustomer.getPreviousStandstill().getLocation();
Location location = vehicleInfoCustomer.getLocation();
double longitude = (previousLocation.getLongitude() + location.getLongitude()) / 2.0;
int x = translator.translateLongitudeToX(longitude);
double latitude = (previousLocation.getLatitude() + location.getLatitude()) / 2.0;
int y = translator.translateLatitudeToY(latitude);
boolean ascending = (previousLocation.getLongitude() < location.getLongitude())
^ (previousLocation.getLatitude() < location.getLatitude());
ImageIcon vehicleImageIcon = vehicleImageIcons[colorIndex];
int vehicleInfoHeight = vehicleImageIcon.getIconHeight() + 2 + TEXT_SIZE;
g.drawImage(vehicleImageIcon.getImage(),
x + 1, (ascending ? y - vehicleInfoHeight - 1 : y + 1), imageObserver);