diff --git a/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/AlgorithmEventsViewer.java b/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/AlgorithmEventsViewer.java index 2bc87c97..c9264b48 100644 --- a/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/AlgorithmEventsViewer.java +++ b/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/AlgorithmEventsViewer.java @@ -153,8 +153,6 @@ public class AlgorithmEventsViewer { private long delayRuin = 5; - private long delay = 2; - public void setRecreationDelay(long delay_in_ms) { this.delayRecreation = delay_in_ms; } @@ -174,6 +172,7 @@ public class AlgorithmEventsViewer { DelayContainer delayContainer = new DelayContainer(); DelaySink delaySink = new DelaySink(delayContainer); + long delay = 2; delaySink.setDelay(delay); delaySink.setRecreateDelay(delayRecreation); delaySink.setRuinDelay(delayRuin); @@ -197,7 +196,7 @@ public class AlgorithmEventsViewer { } } - public static void main(String[] args) throws IOException { + public static void main(String[] args) { AlgorithmEventsViewer viewer = new AlgorithmEventsViewer(); viewer.setRuinDelay(10); viewer.setRecreationDelay(5); diff --git a/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/GraphStreamViewer.java b/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/GraphStreamViewer.java index 22d38ce9..2897d4fb 100644 --- a/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/GraphStreamViewer.java +++ b/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/GraphStreamViewer.java @@ -19,9 +19,8 @@ package com.graphhopper.jsprit.analysis.toolbox; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; +import com.graphhopper.jsprit.core.problem.job.Activity; import com.graphhopper.jsprit.core.problem.job.Job; -import com.graphhopper.jsprit.core.problem.job.Service; -import com.graphhopper.jsprit.core.problem.job.Shipment; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.solution.route.activity.DeliveryActivity; @@ -46,7 +45,7 @@ public class GraphStreamViewer { public static class StyleSheets { - public static String BLUE_FOREST = + static String BLUE_FOREST = "graph { fill-color: #141F2E; }" + "node {" + " size: 7px, 7px;" + @@ -169,7 +168,7 @@ public class GraphStreamViewer { } - public static Graph createMultiGraph(String name, String style) { + static Graph createMultiGraph(String name, String style) { Graph g = new MultiGraph(name); g.addAttribute("ui.quality"); g.addAttribute("ui.antialias"); @@ -177,66 +176,14 @@ public class GraphStreamViewer { return g; } - public static ViewPanel createEmbeddedView(Graph graph, double scaling) { + private static ViewPanel createEmbeddedView(Graph graph, double scaling) { Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD); ViewPanel view = viewer.addDefaultView(false); view.setPreferredSize(new Dimension((int) (698 * scaling), (int) (440 * scaling))); return view; } - public static String STYLESHEET = - "node {" + - " size: 10px, 10px;" + - " fill-color: #6CC644;" + - " text-alignment: at-right;" + - " stroke-mode: plain;" + - " stroke-color: #999;" + - " stroke-width: 1.0;" + - " text-font: couriernew;" + - " text-offset: 2,-5;" + - " text-size: 8;" + - "}" + - "node.pickup {" + - " fill-color: #6CC644;" + - "}" + - "node.delivery {" + - " fill-color: #f93;" + - "}" + - "node.pickupInRoute {" + - " fill-color: #6CC644;" + - " stroke-mode: plain;" + - " stroke-color: #333;" + - " stroke-width: 2.0;" + - "}" + - "node.deliveryInRoute {" + - " fill-color: #f93;" + - " stroke-mode: plain;" + - " stroke-color: #333;" + - " stroke-width: 2.0;" + - "}" + - "node.depot {" + - " fill-color: #BD2C00;" + - " size: 10px, 10px;" + - " shape: box;" + - "}" + - "node.removed {" + - " fill-color: #BD2C00;" + - " size: 10px, 10px;" + - " stroke-mode: plain;" + - " stroke-color: #333;" + - " stroke-width: 2.0;" + - "}" + - - "edge {" + - " fill-color: #333;" + - " arrow-size: 6px,3px;" + - "}" + - "edge.shipment {" + - " fill-color: #999;" + - " arrow-size: 6px,3px;" + - "}"; - - public static enum Label { + public enum Label { NO_LABEL, ID, JOB_NAME, ARRIVAL_TIME, DEPARTURE_TIME, ACTIVITY } @@ -244,7 +191,7 @@ public class GraphStreamViewer { final double x; final double y; - public Center(double x, double y) { + Center(double x, double y) { super(); this.x = x; this.y = y; @@ -319,13 +266,9 @@ public class GraphStreamViewer { public void display() { System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer"); - - Graph g = createMultiGraph("g"); - + Graph g = createMultiGraph(); ViewPanel view = createEmbeddedView(g, scaling); - createJFrame(view, scaling); - render(g, view); } @@ -369,8 +312,58 @@ public class GraphStreamViewer { return jframe; } - private Graph createMultiGraph(String name) { - return GraphStreamViewer.createMultiGraph(name, STYLESHEET); + private Graph createMultiGraph() { + String STYLESHEET = "node {" + + " size: 10px, 10px;" + + " fill-color: #6CC644;" + + " text-alignment: at-right;" + + " stroke-mode: plain;" + + " stroke-color: #999;" + + " stroke-width: 1.0;" + + " text-font: couriernew;" + + " text-offset: 2,-5;" + + " text-size: 8;" + + "}" + + "node.pickup {" + + " fill-color: #6CC644;" + + "}" + + "node.delivery {" + + " fill-color: #f93;" + + "}" + + "node.pickupInRoute {" + + " fill-color: #6CC644;" + + " stroke-mode: plain;" + + " stroke-color: #333;" + + " stroke-width: 2.0;" + + "}" + + "node.deliveryInRoute {" + + " fill-color: #f93;" + + " stroke-mode: plain;" + + " stroke-color: #333;" + + " stroke-width: 2.0;" + + "}" + + "node.depot {" + + " fill-color: #BD2C00;" + + " size: 10px, 10px;" + + " shape: box;" + + "}" + + "node.removed {" + + " fill-color: #BD2C00;" + + " size: 10px, 10px;" + + " stroke-mode: plain;" + + " stroke-color: #333;" + + " stroke-width: 2.0;" + + "}" + + + "edge {" + + " fill-color: #333;" + + " arrow-size: 6px,3px;" + + "}" + + "edge.shipment {" + + " fill-color: #999;" + + " arrow-size: 6px,3px;" + + "}"; + return GraphStreamViewer.createMultiGraph("g", STYLESHEET); } private void render(Graph g, ViewPanel view) { @@ -385,11 +378,7 @@ public class GraphStreamViewer { } for (Job j : vrp.getJobs().values()) { - if (j instanceof Service) { - renderService(g, (Service) j, label); - } else if (j instanceof Shipment) { - renderShipment(g, (Shipment) j, label, renderShipments); - } + renderJob(g, j, label); sleep(renderDelay_in_ms); } @@ -404,6 +393,7 @@ public class GraphStreamViewer { } + private void alignCamera(View view) { view.getCamera().setViewCenter(center.x, center.y, 0); view.getCamera().setViewPercent(zoomFactor); @@ -501,26 +491,22 @@ public class GraphStreamViewer { return 0.0; } - private void renderShipment(Graph g, Shipment shipment, Label label, boolean renderShipments) { - - Node n1 = g.addNode(makeId(shipment.getId(), shipment.getPickupLocation().getId())); - if (label.equals(Label.ID)) n1.addAttribute("ui.label", shipment.getId()); - n1.addAttribute("x", shipment.getPickupLocation().getCoordinate().getX()); - n1.addAttribute("y", shipment.getPickupLocation().getCoordinate().getY()); - n1.setAttribute("ui.class", "pickup"); - - Node n2 = g.addNode(makeId(shipment.getId(), shipment.getDeliveryLocation().getId())); - if (label.equals(Label.ID)) n2.addAttribute("ui.label", shipment.getId()); - n2.addAttribute("x", shipment.getDeliveryLocation().getCoordinate().getX()); - n2.addAttribute("y", shipment.getDeliveryLocation().getCoordinate().getY()); - n2.setAttribute("ui.class", "delivery"); - - if (renderShipments) { - Edge s = g.addEdge(shipment.getId(), makeId(shipment.getId(), shipment.getPickupLocation().getId()), - makeId(shipment.getId(), shipment.getDeliveryLocation().getId()), true); - s.addAttribute("ui.class", "shipment"); + private void renderJob(Graph g, Job j, Label label) { + String lastNodeId = null; + for (Activity act : j.getActivities()) { + String nodeId = makeId(j.getId(), act.getLocation().getId()); + Node n1 = g.addNode(nodeId); + if (label.equals(Label.ID)) n1.addAttribute("ui.label", j.getId()); + n1.addAttribute("x", act.getLocation().getCoordinate().getX()); + n1.addAttribute("y", act.getLocation().getCoordinate().getY()); + if (act.getActivityType().equals(Activity.Type.PICKUP)) n1.setAttribute("ui.class", "pickup"); + else if (act.getActivityType().equals(Activity.Type.DELIVERY)) n1.setAttribute("ui.class", "delivery"); + if (renderShipments && lastNodeId != null) { + Edge s = g.addEdge(j.getId(), lastNodeId, nodeId, true); + s.addAttribute("ui.class", "shipment"); + } + lastNodeId = nodeId; } - } private void sleep(long renderDelay_in_ms2) { @@ -532,15 +518,6 @@ public class GraphStreamViewer { } } - private void renderService(Graph g, Service service, Label label) { - Node n = g.addNode(makeId(service.getId(), service.getLocation().getId())); - if (label.equals(Label.ID)) n.addAttribute("ui.label", service.getId()); - n.addAttribute("x", service.getLocation().getCoordinate().getX()); - n.addAttribute("y", service.getLocation().getCoordinate().getY()); - if (service.getType().equals("pickup")) n.setAttribute("ui.class", "pickup"); - if (service.getType().equals("delivery")) n.setAttribute("ui.class", "delivery"); - } - private String makeId(String id, String locationId) { return id + "_" + locationId; } @@ -575,18 +552,24 @@ public class GraphStreamViewer { if (act instanceof JobActivity) { Job job = ((JobActivity) act).getJob(); String currIdentifier = makeId(job.getId(), act.getLocation().getId()); - if (label.equals(Label.ACTIVITY)) { - Node actNode = g.getNode(currIdentifier); - actNode.addAttribute("ui.label", act.getName()); - } else if (label.equals(Label.JOB_NAME)) { - Node actNode = g.getNode(currIdentifier); - actNode.addAttribute("ui.label", job.getName()); - } else if (label.equals(Label.ARRIVAL_TIME)) { - Node actNode = g.getNode(currIdentifier); - actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getArrTime())); - } else if (label.equals(Label.DEPARTURE_TIME)) { - Node actNode = g.getNode(currIdentifier); - actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getEndTime())); + Node actNode = g.getNode(currIdentifier); + switch (label) { + case ACTIVITY: { + actNode.addAttribute("ui.label", act.getName()); + break; + } + case JOB_NAME: { + actNode.addAttribute("ui.label", job.getName()); + break; + } + case ARRIVAL_TIME: { + actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getArrTime())); + break; + } + case DEPARTURE_TIME: { + actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getEndTime())); + break; + } } g.addEdge(makeEdgeId(routeId, vehicle_edgeId), prevIdentifier, currIdentifier, true); if (act instanceof PickupActivity) g.getNode(currIdentifier).addAttribute("ui.class", "pickupInRoute"); @@ -607,7 +590,4 @@ public class GraphStreamViewer { return Integer.valueOf(routeId).toString() + "." + Integer.valueOf(vehicle_edgeId).toString(); } - // public void saveAsPNG(String filename){ - // - // } } diff --git a/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/Plotter.java b/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/Plotter.java index c519e759..6c36424c 100644 --- a/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/Plotter.java +++ b/jsprit-analysis/src/main/java/com/graphhopper/jsprit/analysis/toolbox/Plotter.java @@ -19,7 +19,7 @@ package com.graphhopper.jsprit.analysis.toolbox; import com.graphhopper.jsprit.core.problem.Location; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; -import com.graphhopper.jsprit.core.problem.job.*; +import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; @@ -27,14 +27,12 @@ import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import com.graphhopper.jsprit.core.util.Coordinate; import org.jfree.chart.*; import org.jfree.chart.axis.NumberAxis; -import org.jfree.chart.labels.XYItemLabelGenerator; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.data.Range; import org.jfree.data.xy.XYDataItem; -import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.RectangleEdge; @@ -79,7 +77,7 @@ public class Plotter { private Set firstActivities; - public MyActivityRenderer(XYSeriesCollection seriesCollection, Map activities, Set firstActivities) { + MyActivityRenderer(XYSeriesCollection seriesCollection, Map activities, Set firstActivities) { super(false, true); this.seriesCollection = seriesCollection; this.activities = activities; @@ -126,7 +124,7 @@ public class Plotter { double maxX; double maxY; - public BoundingBox(double minX, double minY, double maxX, double maxY) { + BoundingBox(double minX, double minY, double maxX, double maxY) { super(); this.minX = minX; this.minY = minY; @@ -148,7 +146,7 @@ public class Plotter { * * @author schroeder */ - public static enum Label { + public enum Label { ID, SIZE, @SuppressWarnings("UnusedDeclaration")NO_LABEL } @@ -164,13 +162,13 @@ public class Plotter { private BoundingBox boundingBox = null; - private Map activitiesByDataItem = new HashMap(); + private Map activitiesByDataItem = new HashMap<>(); - private Map labelsByDataItem = new HashMap(); + private Map labelsByDataItem = new HashMap<>(); private XYSeries activities; - private Set firstActivities = new HashSet(); + private Set firstActivities = new HashSet<>(); private boolean containsPickupAct = false; @@ -247,7 +245,7 @@ public class Plotter { * @param minY lower left y * @param maxX upper right x * @param maxY upper right y - * @return + * @return Plotter */ @SuppressWarnings("UnusedDeclaration") public Plotter setBoundingBox(double minX, double minY, double maxX, double maxY) { @@ -321,27 +319,15 @@ public class Plotter { @Override public LegendItemCollection getLegendItems() { LegendItemCollection lic = new LegendItemCollection(); - LegendItem vehLoc = new LegendItem("vehLoc", Color.RED); - vehLoc.setShape(ELLIPSE); - vehLoc.setShapeVisible(true); - lic.add(vehLoc); + addLegendItem(lic, "vehLoc", Color.RED); if (containsServiceAct) { - LegendItem item = new LegendItem("service", Color.BLUE); - item.setShape(ELLIPSE); - item.setShapeVisible(true); - lic.add(item); + addLegendItem(lic, "service", Color.BLUE); } if (containsPickupAct) { - LegendItem item = new LegendItem("pickup", Color.GREEN); - item.setShape(ELLIPSE); - item.setShapeVisible(true); - lic.add(item); + addLegendItem(lic, "pickup", Color.GREEN); } if (containsDeliveryAct) { - LegendItem item = new LegendItem("delivery", Color.BLUE); - item.setShape(ELLIPSE); - item.setShapeVisible(true); - lic.add(item); + addLegendItem(lic, "delivery", Color.BLUE); } if (routes != null) { LegendItem item = new LegendItem("firstActivity", Color.BLACK); @@ -363,6 +349,13 @@ public class Plotter { } return lic; } + + private void addLegendItem(LegendItemCollection lic, String jobType, Color color) { + LegendItem item = new LegendItem(jobType, color); + item.setShape(ELLIPSE); + item.setShapeVisible(true); + lic.add(item); + } }; LegendTitle legend = new LegendTitle(lis); @@ -384,14 +377,9 @@ public class Plotter { private MyActivityRenderer getProblemRenderer(final XYSeriesCollection problem) { MyActivityRenderer problemRenderer = new MyActivityRenderer(problem, activitiesByDataItem, firstActivities); - problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() { - - @Override - public String generateLabel(XYDataset arg0, int arg1, int arg2) { - XYDataItem item = problem.getSeries(arg1).getDataItem(arg2); - return labelsByDataItem.get(item); - } - + problemRenderer.setBaseItemLabelGenerator((arg0, arg1, arg2) -> { + XYDataItem item = problem.getSeries(arg1).getDataItem(arg2); + return labelsByDataItem.get(item); }); problemRenderer.setBaseItemLabelsVisible(true); problemRenderer.setBaseItemLabelPaint(Color.BLACK); @@ -467,7 +455,7 @@ public class Plotter { } } - private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, Collection routes) throws NoLocationFoundException { + private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, Collection routes) { Map coords = makeMap(vrp.getAllLocations()); XYSeriesCollection coll = new XYSeriesCollection(); int counter = 1; @@ -493,22 +481,20 @@ public class Plotter { } private Map makeMap(Collection allLocations) { - Map coords = new HashMap(); + Map coords = new HashMap<>(); for (Location l : allLocations) coords.put(l.getId(), l.getCoordinate()); return coords; } - private XYSeriesCollection makeShipmentSeries(Collection jobs) throws NoLocationFoundException { + private XYSeriesCollection makeShipmentSeries(Collection jobs) { XYSeriesCollection coll = new XYSeriesCollection(); if (!plotShipments) return coll; int sCounter = 1; String ship = "shipment"; boolean first = true; for (Job job : jobs) { - if (!(job instanceof Shipment)) { - continue; - } - Shipment shipment = (Shipment) job; + if (job.getActivities().size() == 1) continue; +// Shipment shipment = (Shipment) job; XYSeries shipmentSeries; if (first) { first = false; @@ -517,57 +503,34 @@ public class Plotter { shipmentSeries = new XYSeries(sCounter, false, true); sCounter++; } - Coordinate pickupCoordinate = getCoordinate(shipment.getPickupLocation().getCoordinate()); - Coordinate delCoordinate = getCoordinate(shipment.getDeliveryLocation().getCoordinate()); - shipmentSeries.add(pickupCoordinate.getX() * scalingFactor, pickupCoordinate.getY() * scalingFactor); - shipmentSeries.add(delCoordinate.getX() * scalingFactor, delCoordinate.getY() * scalingFactor); + for (com.graphhopper.jsprit.core.problem.job.Activity act : job.getActivities()) { + Coordinate actCoordinate = getCoordinate(act.getLocation().getCoordinate()); + shipmentSeries.add(actCoordinate.getX() * scalingFactor, actCoordinate.getY() * scalingFactor); + } coll.addSeries(shipmentSeries); } return coll; } private void addJob(XYSeries activities, Job job) { - if (job instanceof Shipment) { - Shipment s = (Shipment) job; - Coordinate pickupCoordinate = getCoordinate(s.getPickupLocation().getCoordinate()); - XYDataItem dataItem = new XYDataItem(pickupCoordinate.getX() * scalingFactor, pickupCoordinate.getY() * scalingFactor); + for (com.graphhopper.jsprit.core.problem.job.Activity act : job.getActivities()) { + XYDataItem dataItem = new XYDataItem(getCoordinate(act.getLocation().getCoordinate()).getX() * scalingFactor, getCoordinate(act.getLocation().getCoordinate()).getY() * scalingFactor); activities.add(dataItem); - addLabel(s, dataItem); - markItem(dataItem, Activity.PICKUP); - containsPickupAct = true; - - Coordinate deliveryCoordinate = getCoordinate(s.getDeliveryLocation().getCoordinate()); - XYDataItem dataItem2 = new XYDataItem(deliveryCoordinate.getX() * scalingFactor, deliveryCoordinate.getY() * scalingFactor); - activities.add(dataItem2); - addLabel(s, dataItem2); - markItem(dataItem2, Activity.DELIVERY); - containsDeliveryAct = true; - } else if (job instanceof Pickup) { - Pickup service = (Pickup) job; - Coordinate coord = getCoordinate(service.getLocation().getCoordinate()); - XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor); - activities.add(dataItem); - addLabel(service, dataItem); - markItem(dataItem, Activity.PICKUP); - containsPickupAct = true; - } else if (job instanceof Delivery) { - Delivery service = (Delivery) job; - Coordinate coord = getCoordinate(service.getLocation().getCoordinate()); - XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor); - activities.add(dataItem); - addLabel(service, dataItem); - markItem(dataItem, Activity.DELIVERY); - containsDeliveryAct = true; - } else if (job instanceof Service) { - Service service = (Service) job; - Coordinate coord = getCoordinate(service.getLocation().getCoordinate()); - XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor); - activities.add(dataItem); - addLabel(service, dataItem); - markItem(dataItem, Activity.SERVICE); - containsServiceAct = true; - } else { - throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported."); + addLabel(job, dataItem); + switch (act.getActivityType()) { + case PICKUP: + markItem(dataItem, Activity.PICKUP); + containsPickupAct = true; + break; + case DELIVERY: + markItem(dataItem, Activity.DELIVERY); + containsDeliveryAct = true; + break; + case SERVICE: + markItem(dataItem, Activity.SERVICE); + containsServiceAct = true; + break; + } } } @@ -585,11 +548,11 @@ public class Plotter { boolean firstDim = true; for (int i = 0; i < job.getSize().getNuOfDimensions(); i++) { if (firstDim) { - builder.append(String.valueOf(job.getSize().get(i))); + builder.append(job.getSize().get(i)); firstDim = false; } else { builder.append(","); - builder.append(String.valueOf(job.getSize().get(i))); + builder.append(job.getSize().get(i)); } } builder.append(")"); @@ -606,16 +569,16 @@ public class Plotter { private void retrieveActivities(VehicleRoutingProblem vrp) throws NoLocationFoundException { activities = new XYSeries("activities", false, true); for (Vehicle v : vrp.getVehicles()) { - Coordinate start_coordinate = getCoordinate(v.getStartLocation().getCoordinate()); - if (start_coordinate == null) throw new NoLocationFoundException(); - XYDataItem item = new XYDataItem(start_coordinate.getX() * scalingFactor, start_coordinate.getY() * scalingFactor); + Coordinate startCoordinate = getCoordinate(v.getStartLocation().getCoordinate()); + if (startCoordinate == null) throw new NoLocationFoundException(); + XYDataItem item = new XYDataItem(startCoordinate.getX() * scalingFactor, startCoordinate.getY() * scalingFactor); markItem(item, Activity.START); activities.add(item); if (!v.getStartLocation().getId().equals(v.getEndLocation().getId())) { - Coordinate end_coordinate = getCoordinate(v.getEndLocation().getCoordinate()); - if (end_coordinate == null) throw new NoLocationFoundException(); - XYDataItem end_item = new XYDataItem(end_coordinate.getX() * scalingFactor, end_coordinate.getY() * scalingFactor); + Coordinate endCoordinate = getCoordinate(v.getEndLocation().getCoordinate()); + if (endCoordinate == null) throw new NoLocationFoundException(); + XYDataItem end_item = new XYDataItem(endCoordinate.getX() * scalingFactor, endCoordinate.getY() * scalingFactor); markItem(end_item, Activity.END); activities.add(end_item); }