1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

simplify according to getActivities

This commit is contained in:
oblonski 2019-07-18 22:45:38 +02:00
parent dd3f29b5cc
commit fe590fc9f8
No known key found for this signature in database
GPG key ID: 179DE487285680D1
3 changed files with 152 additions and 210 deletions

View file

@ -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);

View file

@ -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){
//
// }
}

View file

@ -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<XYDataItem> firstActivities;
public MyActivityRenderer(XYSeriesCollection seriesCollection, Map<XYDataItem, Activity> activities, Set<XYDataItem> firstActivities) {
MyActivityRenderer(XYSeriesCollection seriesCollection, Map<XYDataItem, Activity> activities, Set<XYDataItem> 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<XYDataItem, Activity> activitiesByDataItem = new HashMap<XYDataItem, Plotter.Activity>();
private Map<XYDataItem, Activity> activitiesByDataItem = new HashMap<>();
private Map<XYDataItem, String> labelsByDataItem = new HashMap<XYDataItem, String>();
private Map<XYDataItem, String> labelsByDataItem = new HashMap<>();
private XYSeries activities;
private Set<XYDataItem> firstActivities = new HashSet<XYDataItem>();
private Set<XYDataItem> 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<VehicleRoute> routes) throws NoLocationFoundException {
private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, Collection<VehicleRoute> routes) {
Map<String, Coordinate> coords = makeMap(vrp.getAllLocations());
XYSeriesCollection coll = new XYSeriesCollection();
int counter = 1;
@ -493,22 +481,20 @@ public class Plotter {
}
private Map<String, Coordinate> makeMap(Collection<Location> allLocations) {
Map<String, Coordinate> coords = new HashMap<String, Coordinate>();
Map<String, Coordinate> coords = new HashMap<>();
for (Location l : allLocations) coords.put(l.getId(), l.getCoordinate());
return coords;
}
private XYSeriesCollection makeShipmentSeries(Collection<Job> jobs) throws NoLocationFoundException {
private XYSeriesCollection makeShipmentSeries(Collection<Job> 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);
}