Add observers to GraphReader.

This commit is contained in:
Holt59 2018-02-27 23:23:22 +01:00
parent 7b2f3f3549
commit 823ed07770
6 changed files with 450 additions and 207 deletions

View File

@ -29,22 +29,38 @@ public class BinaryGraphReaderV2 extends BinaryReader implements GraphReader {
*/ */
public static RoadType toRoadType(char ch) { public static RoadType toRoadType(char ch) {
switch (ch) { switch (ch) {
case 'a': return RoadType.MOTORWAY; case 'a':
case 'b': return RoadType.TRUNK; return RoadType.MOTORWAY;
case 'c': return RoadType.PRIMARY; case 'b':
case 'd': return RoadType.SECONDARY; return RoadType.TRUNK;
case 'e': return RoadType.MOTORWAY_LINK; case 'c':
case 'f': return RoadType.TRUNK_LINK; return RoadType.PRIMARY;
case 'g': return RoadType.PRIMARY_LINK; case 'd':
case 'h': return RoadType.SECONDARY_LINK; return RoadType.SECONDARY;
case 'i': return RoadType.TERTIARY; case 'e':
case 'j': return RoadType.RESIDENTIAL; return RoadType.MOTORWAY_LINK;
case 'k': return RoadType.UNCLASSIFIED; case 'f':
case 'l': return RoadType.ROAD; return RoadType.TRUNK_LINK;
case 'm': return RoadType.LIVING_STREET; case 'g':
case 'n': return RoadType.SERVICE; return RoadType.PRIMARY_LINK;
case 'o': return RoadType.ROUNDABOUT; case 'h':
case 'z': return RoadType.COASTLINE; return RoadType.SECONDARY_LINK;
case 'i':
return RoadType.TERTIARY;
case 'j':
return RoadType.RESIDENTIAL;
case 'k':
return RoadType.UNCLASSIFIED;
case 'l':
return RoadType.ROAD;
case 'm':
return RoadType.LIVING_STREET;
case 'n':
return RoadType.SERVICE;
case 'o':
return RoadType.ROUNDABOUT;
case 'z':
return RoadType.COASTLINE;
} }
return RoadType.UNCLASSIFIED; return RoadType.UNCLASSIFIED;
} }
@ -68,22 +84,29 @@ public class BinaryGraphReaderV2 extends BinaryReader implements GraphReader {
// Read map id. // Read map id.
int mapId = dis.readInt(); int mapId = dis.readInt();
observers.forEach((observer) -> observer.notifyStartReading(mapId));
// Number of descriptors and nodes. // Number of descriptors and nodes.
int nbDesc = dis.readInt(); int nbDesc = dis.readInt();
int nbNodes = dis.readInt(); int nbNodes = dis.readInt();
// Number of successors for each nodes. // Number of successors for each nodes.
int[] nbSuccessors = new int[nbNodes]; int[] nbSuccessors = new int[nbNodes];
int nbTotalSuccessors = 0;
// Construct an array list with initial capacity of nbNodes. // Construct an array list with initial capacity of nbNodes.
ArrayList<Node> nodes = new ArrayList<Node>(nbNodes); ArrayList<Node> nodes = new ArrayList<Node>(nbNodes);
// Read nodes. // Read nodes.
observers.forEach((observer) -> observer.notifyStartReadingNodes(nbNodes));
for (int node = 0; node < nbNodes; ++node) { for (int node = 0; node < nbNodes; ++node) {
float longitude = ((float) dis.readInt()) / 1E6f; float longitude = ((float) dis.readInt()) / 1E6f;
float latitude = ((float) dis.readInt()) / 1E6f; float latitude = ((float) dis.readInt()) / 1E6f;
nbSuccessors[node] = dis.readUnsignedByte(); nbSuccessors[node] = dis.readUnsignedByte();
nodes.add(new Node(node, new Point(longitude, latitude))); nbTotalSuccessors += nbSuccessors[node];
final Node aNode = new Node(node, new Point(longitude, latitude));
nodes.add(aNode);
observers.forEach((observer) -> observer.notifyNewNodeRead(aNode));
} }
// Check format. // Check format.
@ -93,14 +116,19 @@ public class BinaryGraphReaderV2 extends BinaryReader implements GraphReader {
RoadInformation[] descs = new RoadInformation[nbDesc]; RoadInformation[] descs = new RoadInformation[nbDesc];
// Read // Read
observers.forEach((observer) -> observer.notifyStartReadingDescriptors(nbDesc));
for (int descr = 0; descr < nbDesc; ++descr) { for (int descr = 0; descr < nbDesc; ++descr) {
descs[descr] = readRoadInformation(); final RoadInformation roadinf = readRoadInformation();
descs[descr] = roadinf;
observers.forEach((observer) -> observer.notifyNewDescriptorRead(roadinf));
} }
// Check format. // Check format.
checkByteOrThrow(254); checkByteOrThrow(254);
// Read successors and convert to arcs. // Read successors and convert to arcs.
final int copyNbTotalSuccesors = nbTotalSuccessors; // Stupid Java...
observers.forEach((observer) -> observer.notifyStartReadingArcs(copyNbTotalSuccesors));
for (int node = 0; node < nbNodes; ++node) { for (int node = 0; node < nbNodes; ++node) {
for (int succ = 0; succ < nbSuccessors[node]; ++succ) { for (int succ = 0; succ < nbSuccessors[node]; ++succ) {
@ -126,8 +154,7 @@ public class BinaryGraphReaderV2 extends BinaryReader implements GraphReader {
float dlon = (dis.readShort()) / 2.0e5f; float dlon = (dis.readShort()) / 2.0e5f;
float dlat = (dis.readShort()) / 2.0e5f; float dlat = (dis.readShort()) / 2.0e5f;
points.add(new Point(lastPoint.getLongitude() + dlon, points.add(new Point(lastPoint.getLongitude() + dlon, lastPoint.getLatitude() + dlat));
lastPoint.getLatitude() + dlat));
} }
points.add(nodes.get(destNode).getPoint()); points.add(nodes.get(destNode).getPoint());
@ -137,7 +164,7 @@ public class BinaryGraphReaderV2 extends BinaryReader implements GraphReader {
Node dest = nodes.get(destNode); Node dest = nodes.get(destNode);
// Add successor to initial arc. // Add successor to initial arc.
new Arc(orig, dest, length, info, points); Arc arc = new Arc(orig, dest, length, info, points);
// And reverse arc if its a two-way road. // And reverse arc if its a two-way road.
if (!info.isOneWay()) { if (!info.isOneWay()) {
@ -146,13 +173,15 @@ public class BinaryGraphReaderV2 extends BinaryReader implements GraphReader {
Collections.reverse(rPoints); Collections.reverse(rPoints);
new Arc(dest, orig, length, info, rPoints); new Arc(dest, orig, length, info, rPoints);
} }
observers.forEach((observer) -> observer.notifyNewArcRead(arc));
} }
} }
// Check format. // Check format.
checkByteOrThrow(253); checkByteOrThrow(253);
observers.forEach((observer) -> observer.notifyEndReading());
return new Graph(mapId, nodes); return new Graph(mapId, nodes);
} }

View File

@ -2,6 +2,8 @@ package org.insa.graph.io;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public abstract class BinaryReader { public abstract class BinaryReader {
@ -12,12 +14,22 @@ public abstract class BinaryReader {
// InputStream // InputStream
protected DataInputStream dis; protected DataInputStream dis;
// List of observers
protected List<GraphReaderObserver> observers = new ArrayList<>();
protected BinaryReader(int magicNumber, int version, DataInputStream dis) { protected BinaryReader(int magicNumber, int version, DataInputStream dis) {
this.magicNumber = magicNumber; this.magicNumber = magicNumber;
this.version = version; this.version = version;
this.dis = dis; this.dis = dis;
} }
/**
* {@inheritDoc}
*/
public void addObserver(GraphReaderObserver observer) {
observers.add(observer);
}
/** /**
* @param version * @param version
* @throws BadVersionException * @throws BadVersionException
@ -39,9 +51,8 @@ public abstract class BinaryReader {
} }
/** /**
* Check if the next byte in the input stream correspond to the * Check if the next byte in the input stream correspond to the given byte. This
* given byte. This function consumes the next byte in the input * function consumes the next byte in the input stream.
* stream.
* *
* @param i Byte to check against. * @param i Byte to check against.
* *

View File

@ -6,6 +6,13 @@ import org.insa.graph.Graph;
public interface GraphReader { public interface GraphReader {
/**
* Add a new observer to this graph reader.
*
* @param observer
*/
public void addObserver(GraphReaderObserver observer);
/** /**
* Read a graph an returns it. * Read a graph an returns it.
* *

View File

@ -0,0 +1,64 @@
package org.insa.graph.io;
import org.insa.graph.Arc;
import org.insa.graph.Node;
import org.insa.graph.RoadInformation;
public interface GraphReaderObserver {
/**
* Notify observer about information on the graph, this method is always the
* first called
*
* @param mapId ID of the graph.
*/
public void notifyStartReading(int mapId);
/**
* Notify that the graph has been fully read.
*/
public void notifyEndReading();
/**
* Notify that the reader is starting to read node.
*
* @param nNodes Number of nodes to read.
*/
public void notifyStartReadingNodes(int nNodes);
/**
* Notify that a new nodes has been read.
*
* @param node
*/
public void notifyNewNodeRead(Node node);
/**
* Notify that the reader is starting to read descriptor/road informations.
*
* @param nDesc Number of descriptors to read.
*/
public void notifyStartReadingDescriptors(int nDesc);
/**
* Notify that a new descriptor has been read.
*
* @param desc
*/
public void notifyNewDescriptorRead(RoadInformation desc);
/**
* Notify that the reader is starting to read arcs.
*
* @param nArcs Number of arcs to read (!= number of arcs in the graph).
*/
public void notifyStartReadingArcs(int nArcs);
/**
* Notify that a new arc has been read.
*
* @param arc
*/
public void notifyNewArcRead(Arc arc);
}

View File

@ -0,0 +1,131 @@
package org.insa.graphics;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;
import org.insa.graph.Arc;
import org.insa.graph.Node;
import org.insa.graph.RoadInformation;
import org.insa.graph.io.GraphReaderObserver;
/**
* One-time use GraphReaderObserver that display progress in three different
* JProgressBar.
*
* @author Mikael
*
*/
public class GraphReaderProgressBar extends JDialog implements GraphReaderObserver {
/**
*
*/
private static final long serialVersionUID = -1;
// Index...
private static final int NODE = 0, DESC = 1, ARC = 2;
// Progress bar
private final JProgressBar[] progressBars = new JProgressBar[3];
// Current element read, and modulo.
private int[] counters = new int[] { 0, 0, 0 };
private int[] modulos = new int[3];
public GraphReaderProgressBar(JFrame owner) {
super(owner);
this.setVisible(false);
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
final String[] infos = { "nodes", "road informations", "arcs" };
JPanel pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
pane.setBorder(new EmptyBorder(15, 15, 15, 15));
pane.add(Box.createVerticalGlue());
for (int i = 0; i < 3; ++i) {
JLabel label = new JLabel("Reading " + infos[i] + "... ");
label.setAlignmentX(Component.LEFT_ALIGNMENT);
progressBars[i] = new JProgressBar();
progressBars[i].setAlignmentX(Component.LEFT_ALIGNMENT);
pane.add(label);
pane.add(progressBars[i]);
}
pane.add(Box.createVerticalGlue());
pane.setPreferredSize(new Dimension(300, 120));
setContentPane(pane);
// setModal(true);
setLocationRelativeTo(owner);
pack();
}
@Override
public void notifyStartReading(int mapId) {
setTitle(String.format("Reading graph %#x... ", mapId));
setVisible(true);
}
@Override
public void notifyEndReading() {
setVisible(false);
}
protected void initProgressBar(int index, int max) {
progressBars[index].setMaximum(max);
modulos[index] = max / 100;
}
protected void incCounter(int index) {
counters[index] += 1;
if (counters[index] % modulos[index] == 0) {
progressBars[index].setValue(counters[index]);
}
}
@Override
public void notifyStartReadingNodes(int nNodes) {
initProgressBar(NODE, nNodes);
}
@Override
public void notifyNewNodeRead(Node node) {
incCounter(NODE);
}
@Override
public void notifyStartReadingDescriptors(int nDesc) {
initProgressBar(DESC, nDesc);
}
@Override
public void notifyNewDescriptorRead(RoadInformation desc) {
incCounter(DESC);
}
@Override
public void notifyStartReadingArcs(int nArcs) {
initProgressBar(ARC, nArcs);
}
@Override
public void notifyNewArcRead(Arc arc) {
incCounter(ARC);
}
}

View File

@ -518,6 +518,7 @@ public class MainWindow extends JFrame {
else { else {
reader = new BinaryGraphReader(stream); reader = new BinaryGraphReader(stream);
} }
reader.addObserver(new GraphReaderProgressBar(MainWindow.this));
try { try {
graph = reader.read(); graph = reader.read();
} }