1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00
This commit is contained in:
oblonski 2014-11-18 19:33:13 +01:00
parent 9c857962d6
commit b702c8015b
2 changed files with 394 additions and 57 deletions

View file

@ -24,14 +24,15 @@ import jsprit.core.algorithm.recreate.listener.BeforeJobInsertionListener;
import jsprit.core.algorithm.recreate.listener.InsertionEndsListener; import jsprit.core.algorithm.recreate.listener.InsertionEndsListener;
import jsprit.core.algorithm.recreate.listener.InsertionStartsListener; import jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
import jsprit.core.algorithm.ruin.listener.RuinListener; import jsprit.core.algorithm.ruin.listener.RuinListener;
import jsprit.core.problem.AbstractActivity;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Job; import jsprit.core.problem.job.*;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleImpl;
import jsprit.core.util.Coordinate;
import jsprit.core.util.Solutions; import jsprit.core.util.Solutions;
import org.graphstream.graph.Edge; import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph; import org.graphstream.graph.Graph;
@ -43,11 +44,19 @@ import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.List;
public class AlgorithmEventRecorder implements RuinListener, IterationStartsListener, InsertionStartsListener, BeforeJobInsertionListener, InsertionEndsListener, AlgorithmEndsListener { public class AlgorithmEventRecorder implements RuinListener, IterationStartsListener, InsertionStartsListener, BeforeJobInsertionListener, InsertionEndsListener, AlgorithmEndsListener {
private boolean renderShipments = false;
public static void writeSolution(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, File outfile){
AlgorithmEventRecorder rec = new AlgorithmEventRecorder(vrp,outfile);
rec.initialiseGraph(vrp);
rec.addRoutes(solution.getRoutes());
rec.finish();
}
public static enum RecordPolicy { public static enum RecordPolicy {
RECORD_AND_WRITE RECORD_AND_WRITE
@ -75,7 +84,10 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
private int currentIteration = 0; private int currentIteration = 0;
private VehicleRoutingProblem vrp;
public AlgorithmEventRecorder(VehicleRoutingProblem vrp, File outfile) { public AlgorithmEventRecorder(VehicleRoutingProblem vrp, File outfile) {
this.vrp = vrp;
graph = new MultiGraph("g"); graph = new MultiGraph("g");
try { try {
writer = new FileWriter(outfile); writer = new FileWriter(outfile);
@ -88,6 +100,11 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
initialiseGraph(vrp); initialiseGraph(vrp);
} }
public AlgorithmEventRecorder(VehicleRoutingProblem vrp, File outfile, boolean renderShipments) {
this.renderShipments = renderShipments;
new AlgorithmEventRecorder(vrp,outfile);
}
public void setRecordingRange(int startIteration, int endIteration){ public void setRecordingRange(int startIteration, int endIteration){
this.start_recording_at = startIteration; this.start_recording_at = startIteration;
this.end_recording_at = endIteration; this.end_recording_at = endIteration;
@ -114,21 +131,39 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
public void ruinStarts(Collection<VehicleRoute> routes) { public void ruinStarts(Collection<VehicleRoute> routes) {
if(!record()) return; if(!record()) return;
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION); fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION);
recordRoutes(routes); addRoutes(routes);
fileSink.stepBegins(graph.getId(),0,RUIN); fileSink.stepBegins(graph.getId(),0,RUIN);
} }
private void recordRoutes(Collection<VehicleRoute> routes) { private void addRoutes(Collection<VehicleRoute> routes) {
for(VehicleRoute route : routes){ for(VehicleRoute route : routes){
String prevNode = makeStartId(route.getVehicle()); String prevNode = makeStartId(route.getVehicle());
for(TourActivity act : route.getActivities()){ for(TourActivity act : route.getActivities()){
String actNode = ((TourActivity.JobActivity)act).getJob().getId(); String actNodeId = getNodeId(act);
addEdge(prevNode+"_"+actNode,prevNode,actNode); addEdge(prevNode+"_"+actNodeId,prevNode,actNodeId);
prevNode = actNode; prevNode = actNodeId;
} }
if(route.getVehicle().isReturnToDepot()) {
String lastNode = makeEndId(route.getVehicle()); String lastNode = makeEndId(route.getVehicle());
addEdge(prevNode+"_"+lastNode,prevNode,lastNode); addEdge(prevNode+"_"+lastNode,prevNode,lastNode);
} }
}
}
private String getNodeId(TourActivity act) {
String nodeId = null;
if(act instanceof TourActivity.JobActivity){
Job job = ((TourActivity.JobActivity) act).getJob();
if(job instanceof Service){
nodeId = job.getId();
}
else if(job instanceof Shipment){
if(act.getName().equals("pickupShipment")) nodeId = getFromNodeId((Shipment) job);
else nodeId = getToNodeId((Shipment) job);
}
}
return nodeId;
} }
private boolean record() { private boolean record() {
@ -143,19 +178,99 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
@Override @Override
public void removed(Job job, VehicleRoute fromRoute) { public void removed(Job job, VehicleRoute fromRoute) {
if(!record()) return; if(!record()) return;
if(job instanceof Service) removeService(job, fromRoute);
else if(job instanceof Shipment) removeShipment(job,fromRoute);
}
private void removeShipment(Job job, VehicleRoute fromRoute) {
Shipment shipment = (Shipment)job;
String fromNodeId = getFromNodeId(shipment);
String toNodeId = getToNodeId(shipment);
// removeNodeAndBelongingEdges(fromNodeId,fromRoute);
// removeNodeAndBelongingEdges(toNodeId,fromRoute);
Edge enteringToNode = getEnteringEdge(toNodeId);
if(enteringToNode.getNode0().getId().equals(fromNodeId)){
markRemoved(graph.getNode(fromNodeId));
markRemoved(graph.getNode(toNodeId));
// i -> from -> to -> j: rem(i,from), rem(from,to), rem(to,j), add(i,j)
Edge enteringFromNode = getEnteringEdge(fromNodeId);
removeEdge(enteringFromNode.getId());
removeEdge(enteringToNode.getId());
if(graph.getNode(toNodeId).getLeavingEdgeSet().isEmpty()){
if(fromRoute.getVehicle().isReturnToDepot()) throw new IllegalStateException("leaving edge is missing");
return;
}
Edge leavingToNode = getLeavingEdge(toNodeId);
removeEdge(leavingToNode.getId());
Node from = enteringFromNode.getNode0();
Node to = leavingToNode.getNode1();
if(!fromRoute.getActivities().isEmpty()){
addEdge(makeEdgeId(from,to),from.getId(),to.getId());
}
}
else{
removeNodeAndBelongingEdges(fromNodeId,fromRoute);
removeNodeAndBelongingEdges(toNodeId,fromRoute);
}
}
private Edge getLeavingEdge(String toNodeId) {
Collection<Edge> edges = graph.getNode(toNodeId).getLeavingEdgeSet();
if(edges.size()==1) return edges.iterator().next();
else{
for(Edge e : edges){
if(e.getId().startsWith("shipment")){ continue; }
return e;
}
}
return null;
}
private Edge getEnteringEdge(String toNodeId) {
Collection<Edge> enteringEdges = graph.getNode(toNodeId).getEnteringEdgeSet();
if(enteringEdges.size()==1) return enteringEdges.iterator().next();
else{
for(Edge e : enteringEdges){
if(e.getId().startsWith("shipment")){ continue; }
return e;
}
}
return null;
}
private String getToNodeId(Shipment shipment) {
return shipment.getId() + "_delivery";
}
private String getFromNodeId(Shipment shipment) {
return shipment.getId() + "_pickup";
}
private void removeService(Job job, VehicleRoute fromRoute) {
String nodeId = job.getId(); String nodeId = job.getId();
removeNodeAndBelongingEdges(nodeId, fromRoute);
}
private void removeNodeAndBelongingEdges(String nodeId, VehicleRoute fromRoute) {
Node node = graph.getNode(nodeId); Node node = graph.getNode(nodeId);
markRemoved(node); markRemoved(node);
Edge entering = node.getEnteringEdge(0); Edge entering = getEnteringEdge(nodeId);
removeEdge(entering.getId()); removeEdge(entering.getId());
Edge leaving = node.getLeavingEdge(0);
if(node.getLeavingEdgeSet().isEmpty()){
if(fromRoute.getVehicle().isReturnToDepot()) throw new IllegalStateException("leaving edge is missing");
return;
}
Edge leaving = getLeavingEdge(nodeId);
removeEdge((leaving.getId())); removeEdge((leaving.getId()));
Node from = entering.getNode0(); Node from = entering.getNode0();
Node to = leaving.getNode1(); Node to = leaving.getNode1();
if(!fromRoute.getActivities().isEmpty()){ if(!fromRoute.getActivities().isEmpty()){
addEdge(makeEdgeId(from,to),from.getId(),to.getId()); addEdge(makeEdgeId(from,to),from.getId(),to.getId());
} }
} }
private void markRemoved(Node node) { private void markRemoved(Node node) {
@ -170,7 +285,11 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions); VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions);
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION); fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION);
recordRoutes(solution.getRoutes()); addRoutes(solution.getRoutes());
finish();
}
private void finish() {
try { try {
fileSink.end(); fileSink.end();
writer.close(); writer.close();
@ -189,10 +308,50 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
addVehicle(vehicle); addVehicle(vehicle);
} }
for(Job job : problem.getJobs().values()){ for(Job job : problem.getJobs().values()){
Service service = (Service)job; addJob(job);
addService(service); }
} }
private void addJob(Job job) {
if(job instanceof Service){
Service service = (Service)job;
addNode(service.getId(), service.getCoord());
markService(service);
}
else if(job instanceof Shipment){
Shipment shipment = (Shipment)job;
String fromNodeId = getFromNodeId(shipment);
addNode(fromNodeId, shipment.getPickupCoord());
String toNodeId = getToNodeId(shipment);
addNode(toNodeId,shipment.getDeliveryCoord());
markShipment(shipment);
if(renderShipments) {
Edge e = graph.addEdge("shipment_" + fromNodeId + "_" + toNodeId, fromNodeId, toNodeId, true);
e.addAttribute("ui.class", "shipment");
}
}
}
private void markShipment(Shipment shipment) {
markPickup(getFromNodeId(shipment));
markDelivery(getToNodeId(shipment));
}
private void markService(Service service) {
if(service instanceof Pickup){
markPickup(service.getId());
}
else if(service instanceof Delivery){
markDelivery(service.getId());
}
}
private void markPickup(String id) {
graph.getNode(id).addAttribute("ui.class","pickup");
}
private void markDelivery(String id) {
graph.getNode(id).addAttribute("ui.class","delivery");
} }
private void addVehicle(Vehicle vehicle) { private void addVehicle(Vehicle vehicle) {
@ -220,32 +379,98 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
return vehicle.getId() + "_end"; return vehicle.getId() + "_end";
} }
private void addService(Service service) { private void addNode(String nodeId, Coordinate nodeCoord) {
Node serviceNode = graph.addNode(service.getId()); Node node = graph.addNode(nodeId);
serviceNode.addAttribute("x", service.getCoord().getX()); node.addAttribute("x", nodeCoord.getX());
serviceNode.addAttribute("y", service.getCoord().getY()); node.addAttribute("y", nodeCoord.getY());
} }
@Override @Override
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) { public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
if(!record()) return; if(!record()) return;
fileSink.stepBegins(graph.getId(),0,CLEAR_SOLUTION); fileSink.stepBegins(graph.getId(),0,CLEAR_SOLUTION);
removeRoutes(vehicleRoutes);
}
private void removeRoutes(Collection<VehicleRoute> vehicleRoutes) {
for(VehicleRoute route : vehicleRoutes){ for(VehicleRoute route : vehicleRoutes){
String prevNode = makeStartId(route.getVehicle()); String prevNode = makeStartId(route.getVehicle());
for(TourActivity act : route.getActivities()){ for(TourActivity act : route.getActivities()){
String actNode = ((TourActivity.JobActivity)act).getJob().getId(); String actNode = getNodeId(act);
removeEdge(prevNode + "_" + actNode); removeEdge(prevNode + "_" + actNode);
prevNode = actNode; prevNode = actNode;
} }
if(route.getVehicle().isReturnToDepot()) {
String lastNode = makeEndId(route.getVehicle()); String lastNode = makeEndId(route.getVehicle());
removeEdge(prevNode + "_" + lastNode); removeEdge(prevNode + "_" + lastNode);
} }
} }
}
@Override @Override
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) { public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
if(!record()) return; if(!record()) return;
markInserted(job); markInserted(job);
handleVehicleSwitch(data, route);
insertJob(job, data, route);
}
private void insertJob(Job job, InsertionData data, VehicleRoute route) {
if(job instanceof Service) insertService(job,data,route);
else if(job instanceof Shipment) insertShipment(job,data,route);
}
private void insertShipment(Job job, InsertionData data, VehicleRoute route) {
String fromNodeId = getFromNodeId((Shipment) job);
String toNodeId = getToNodeId((Shipment) job);
insertNode(toNodeId,data.getDeliveryInsertionIndex(),data,route);
List<AbstractActivity> del = vrp.getActivities(job);
VehicleRoute copied = VehicleRoute.copyOf(route);
copied.getTourActivities().addActivity(data.getDeliveryInsertionIndex(),del.get(1));
insertNode(fromNodeId, data.getPickupInsertionIndex(), data, copied);
}
private void insertService(Job job, InsertionData data, VehicleRoute route) {
insertNode(job.getId(), data.getDeliveryInsertionIndex(), data, route);
}
private void insertNode(String nodeId, int insertionIndex, InsertionData data, VehicleRoute route) {
// VehicleRoute copied = VehicleRoute.copyOf(route);
String node_i;
if(isFirst(insertionIndex,route)) {
node_i = makeStartId(data.getSelectedVehicle());
}
else {
TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex - 1);
node_i = getNodeId(jobActivity);
}
String node_k = nodeId;
String edgeId_1 = node_i + "_" + node_k;
String node_j;
if(isLast(insertionIndex,route)) {
node_j = makeEndId(data.getSelectedVehicle());
}
else {
TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex);
node_j = getNodeId(jobActivity);
}
String edgeId_2 = node_k + "_" + node_j;
addEdge(edgeId_1, node_i, node_k);
if(!(isLast(insertionIndex,route) && !data.getSelectedVehicle().isReturnToDepot())) {
addEdge(edgeId_2, node_k, node_j);
if (!route.getActivities().isEmpty()) {
removeEdge(node_i + "_" + node_j);
}
}
}
private void handleVehicleSwitch(InsertionData data, VehicleRoute route) {
boolean vehicleSwitch = false; boolean vehicleSwitch = false;
if(!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) { if(!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
if (!route.getVehicle().getId().equals(data.getSelectedVehicle().getId())) { if (!route.getVehicle().getId().equals(data.getSelectedVehicle().getId())) {
@ -258,56 +483,55 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
String oldEnd = makeEndId(route.getVehicle()); String oldEnd = makeEndId(route.getVehicle());
String lastAct = ((TourActivity.JobActivity)route.getActivities().get(route.getActivities().size()-1)).getJob().getId(); String lastAct = ((TourActivity.JobActivity)route.getActivities().get(route.getActivities().size()-1)).getJob().getId();
removeEdge(oldStart + "_" + firstAct); removeEdge(oldStart + "_" + firstAct);
if(route.getVehicle().isReturnToDepot()) {
removeEdge(lastAct + "_" + oldEnd); removeEdge(lastAct + "_" + oldEnd);
}
String newStart = makeStartId(data.getSelectedVehicle()); String newStart = makeStartId(data.getSelectedVehicle());
String newEnd = makeEndId(data.getSelectedVehicle()); String newEnd = makeEndId(data.getSelectedVehicle());
addEdge(newStart + "_" + firstAct,newStart,firstAct); addEdge(newStart + "_" + firstAct,newStart,firstAct);
addEdge(lastAct + "_" + newEnd, lastAct,newEnd);
}
String node_i;
if(isFirst(data,route)) { if(data.getSelectedVehicle().isReturnToDepot()) {
node_i = makeStartId(data.getSelectedVehicle()); addEdge(lastAct + "_" + newEnd, lastAct, newEnd);
} }
else {
node_i = ((TourActivity.JobActivity)route.getActivities().get(data.getDeliveryInsertionIndex()-1)).getJob().getId();
}
String node_k = job.getId();
String edgeId_1 = node_i + "_" + node_k;
String node_j;
if(isLast(data,route)) {
node_j = makeEndId(data.getSelectedVehicle());
}
else {
node_j = ((TourActivity.JobActivity)route.getActivities().get(data.getDeliveryInsertionIndex())).getJob().getId();
}
String edgeId_2 = node_k + "_" + node_j;
addEdge(edgeId_1, node_i, node_k);
addEdge(edgeId_2, node_k, node_j);
if(!route.getActivities().isEmpty()){
removeEdge(node_i + "_" + node_j);
} }
} }
private void markInserted(Job job) { private void markInserted(Job job) {
graph.getNode(job.getId()).removeAttribute("ui.class"); if(job instanceof Service){
markService((Service) job);
}
else{
markShipment((Shipment)job);
}
} }
private void removeEdge(String edgeId) { private void removeEdge(String edgeId) {
markEdgeRemoved(edgeId);
graph.removeEdge(edgeId); graph.removeEdge(edgeId);
} }
private boolean isFirst(InsertionData data, VehicleRoute route) { private void markEdgeRemoved(String edgeId) {
return data.getDeliveryInsertionIndex() == 0; graph.getEdge(edgeId).addAttribute("ui.class","removed");
} }
private boolean isLast(InsertionData data, VehicleRoute route) { private boolean isFirst(int index, VehicleRoute route) {
return data.getDeliveryInsertionIndex() == route.getActivities().size(); return index == 0;
}
private boolean isLast(int index, VehicleRoute route) {
return index == route.getActivities().size();
} }
private void addEdge(String edgeId, String fromNode, String toNode) { private void addEdge(String edgeId, String fromNode, String toNode) {
graph.addEdge(edgeId,fromNode,toNode,true); graph.addEdge(edgeId,fromNode,toNode,true);
markEdgeInserted(edgeId);
}
private void markEdgeInserted(String edgeId) {
graph.getEdge(edgeId).addAttribute("ui.class","inserted");
graph.getEdge(edgeId).removeAttribute("ui.class");
} }
@Override @Override

View file

@ -33,16 +33,95 @@ import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph; import org.graphstream.graph.Graph;
import org.graphstream.graph.Node; import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.MultiGraph; import org.graphstream.graph.implementations.MultiGraph;
import org.graphstream.stream.Sink;
import org.graphstream.stream.file.FileSinkImages;
import org.graphstream.ui.swingViewer.View; import org.graphstream.ui.swingViewer.View;
import org.graphstream.ui.swingViewer.Viewer; import org.graphstream.ui.swingViewer.Viewer;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.io.File;
public class GraphStreamViewer { public class GraphStreamViewer {
private static class EmptySink implements Sink {
@Override
public void graphAttributeAdded(String sourceId, long timeId, String attribute, Object value) {
}
@Override
public void graphAttributeChanged(String sourceId, long timeId, String attribute, Object oldValue, Object newValue) {
}
@Override
public void graphAttributeRemoved(String sourceId, long timeId, String attribute) {
}
@Override
public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value) {
}
@Override
public void nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue) {
}
@Override
public void nodeAttributeRemoved(String sourceId, long timeId, String nodeId, String attribute) {
}
@Override
public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value) {
}
@Override
public void edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue) {
}
@Override
public void edgeAttributeRemoved(String sourceId, long timeId, String edgeId, String attribute) {
}
@Override
public void nodeAdded(String sourceId, long timeId, String nodeId) {
}
@Override
public void nodeRemoved(String sourceId, long timeId, String nodeId) {
}
@Override
public void edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed) {
}
@Override
public void edgeRemoved(String sourceId, long timeId, String edgeId) {
}
@Override
public void graphCleared(String sourceId, long timeId) {
}
@Override
public void stepBegins(String sourceId, long timeId, double step) {
}
}
public static Graph createMultiGraph(String name, String style){ public static Graph createMultiGraph(String name, String style){
Graph g = new MultiGraph(name); Graph g = new MultiGraph(name);
@ -143,6 +222,12 @@ public class GraphStreamViewer {
private double scaling = 1.0; private double scaling = 1.0;
private boolean createImageByEvent = false;
private File imageDirectory;
Sink fsi = new EmptySink();
public GraphStreamViewer(VehicleRoutingProblem vrp) { public GraphStreamViewer(VehicleRoutingProblem vrp) {
super(); super();
this.vrp = vrp; this.vrp = vrp;
@ -159,6 +244,12 @@ public class GraphStreamViewer {
return this; return this;
} }
public GraphStreamViewer createImagesByEvent(boolean createImanges, File outDirectory){
createImageByEvent = true;
imageDirectory = outDirectory;
return this;
}
public GraphStreamViewer setRenderDelay(long ms){ public GraphStreamViewer setRenderDelay(long ms){
this.renderDelay_in_ms=ms; this.renderDelay_in_ms=ms;
return this; return this;
@ -204,7 +295,21 @@ public class GraphStreamViewer {
JFrame jframe = createJFrame(view,scaling); JFrame jframe = createJFrame(view,scaling);
render(g,view); Sink fsi;
if(createImageByEvent){
FileSinkImages.OutputPolicy outputPolicy = FileSinkImages.OutputPolicy.BY_ELEMENT_EVENT;
String prefix = "screenshot_";
FileSinkImages.OutputType type = FileSinkImages.OutputType.PNG;
FileSinkImages.Resolution resolution = FileSinkImages.Resolutions.HD720;
fsi = new FileSinkImages( type, resolution );
((FileSinkImages)fsi).setStyleSheet(STYLESHEET);
((FileSinkImages)fsi).setOutputPolicy(outputPolicy);
((FileSinkImages)fsi).setLayoutPolicy(FileSinkImages.LayoutPolicy.NO_LAYOUT);
((FileSinkImages)fsi).setQuality(FileSinkImages.Quality.HIGH);
((FileSinkImages)fsi).setRenderer(FileSinkImages.RendererType.SCALA);
}
render(g, view);
} }
private JFrame createJFrame(View view, double scaling) { private JFrame createJFrame(View view, double scaling) {
@ -254,8 +359,7 @@ public class GraphStreamViewer {
private void render(Graph g, View view) { private void render(Graph g, View view) {
if(center != null){ if(center != null){
view.resizeFrame(view.getWidth(), view.getHeight()); view.resizeFrame(view.getWidth(), view.getHeight());
view.getCamera().setViewCenter(center.x, center.y, 0); alignCamera(view);
view.getCamera().setViewPercent(zoomFactor);
} }
for(Vehicle vehicle : vrp.getVehicles()){ for(Vehicle vehicle : vrp.getVehicles()){
@ -284,6 +388,15 @@ public class GraphStreamViewer {
} }
private void alignCamera(View view) {
view.getCamera().setViewCenter(center.x, center.y, 0);
view.getCamera().setViewPercent(zoomFactor);
if(fsi instanceof FileSinkImages){
((FileSinkImages) fsi).setViewCenter(center.x, center.y);
((FileSinkImages) fsi).setViewPercent(zoomFactor);
}
}
private JLabel createEmptyLabel() { private JLabel createEmptyLabel() {
JLabel emptyLabel1 = new JLabel(); JLabel emptyLabel1 = new JLabel();
emptyLabel1.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling))); emptyLabel1.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));