Add extra information in graph.
This commit is contained in:
parent
2e7a1c564a
commit
ae082d0b8a
@ -14,14 +14,25 @@ public class Graph {
|
|||||||
// Nodes of the graph.
|
// Nodes of the graph.
|
||||||
private final List<Node> nodes;
|
private final List<Node> nodes;
|
||||||
|
|
||||||
|
// Graph information of this graph.
|
||||||
|
private final GraphInformation graphInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapId ID of this graph.
|
* @param mapId ID of this graph.
|
||||||
* @param list List of nodes for this graph.
|
* @param list List of nodes for this graph.
|
||||||
*/
|
*/
|
||||||
public Graph(String mapId, String mapName, List<Node> list) {
|
public Graph(String mapId, String mapName, List<Node> list, GraphInformation graphInformation) {
|
||||||
this.mapId = mapId;
|
this.mapId = mapId;
|
||||||
this.mapName = mapName;
|
this.mapName = mapName;
|
||||||
this.nodes = list;
|
this.nodes = list;
|
||||||
|
this.graphInfo = graphInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return GraphInformation of this graph.
|
||||||
|
*/
|
||||||
|
public GraphInformation getGraphInformation() {
|
||||||
|
return this.graphInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,26 +42,6 @@ public class Graph {
|
|||||||
return Collections.unmodifiableList(nodes);
|
return Collections.unmodifiableList(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the closet node to the given point.
|
|
||||||
*
|
|
||||||
* @param point
|
|
||||||
*
|
|
||||||
* @return Closest node to the given point.
|
|
||||||
*/
|
|
||||||
public Node findClosestNode(Point point) {
|
|
||||||
Node node = null;
|
|
||||||
double minDis = Double.POSITIVE_INFINITY;
|
|
||||||
for (int n = 0; n < nodes.size(); ++n) {
|
|
||||||
double dis = point.distanceTo(nodes.get(n).getPoint());
|
|
||||||
if (dis < minDis) {
|
|
||||||
node = nodes.get(n);
|
|
||||||
minDis = dis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Map ID of this graph.
|
* @return Map ID of this graph.
|
||||||
*/
|
*/
|
||||||
|
39
src/main/org/insa/graph/GraphInformation.java
Normal file
39
src/main/org/insa/graph/GraphInformation.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package org.insa.graph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class that stores some information for a graph that are no easy to
|
||||||
|
* access quickly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GraphInformation {
|
||||||
|
|
||||||
|
// Maximum speed on this graph (in kmph).
|
||||||
|
private final int maximumSpeed;
|
||||||
|
|
||||||
|
// Maximum length of any arc on this graph.
|
||||||
|
private final int maximumLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maximumSpeed
|
||||||
|
* @param maximumLength
|
||||||
|
*/
|
||||||
|
public GraphInformation(int maximumSpeed, int maximumLength) {
|
||||||
|
this.maximumLength = maximumLength;
|
||||||
|
this.maximumSpeed = maximumSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Maximum speed of any arc in the graph.
|
||||||
|
*/
|
||||||
|
public int getMaximumSpeed() {
|
||||||
|
return this.maximumSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Maximum length of any arc in the graph.
|
||||||
|
*/
|
||||||
|
public int getMaximumLength() {
|
||||||
|
return this.maximumLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,197 +0,0 @@
|
|||||||
package org.insa.graph.io;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import org.insa.graph.Arc;
|
|
||||||
import org.insa.graph.Graph;
|
|
||||||
import org.insa.graph.Node;
|
|
||||||
import org.insa.graph.Point;
|
|
||||||
import org.insa.graph.RoadInformation;
|
|
||||||
import org.insa.graph.RoadInformation.AccessRestriction;
|
|
||||||
import org.insa.graph.RoadInformation.RoadType;
|
|
||||||
|
|
||||||
public class BinaryGraphReaderInsa2016 extends BinaryReader implements GraphReader {
|
|
||||||
|
|
||||||
// Map version and magic number targeted for this reader.
|
|
||||||
private static final int VERSION = 4;
|
|
||||||
private static final int MAGIC_NUMBER = 0xbacaff;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a character to its corresponding road type.
|
|
||||||
*
|
|
||||||
* @param ch Character to convert.
|
|
||||||
*
|
|
||||||
* @return Road type corresponding to ch.
|
|
||||||
*
|
|
||||||
* @see http://wiki.openstreetmap.org/wiki/Highway_tag_usage.
|
|
||||||
*/
|
|
||||||
public static RoadType toRoadType(char ch) {
|
|
||||||
switch (ch) {
|
|
||||||
case 'a':
|
|
||||||
return RoadType.MOTORWAY;
|
|
||||||
case 'b':
|
|
||||||
return RoadType.TRUNK;
|
|
||||||
case 'c':
|
|
||||||
return RoadType.PRIMARY;
|
|
||||||
case 'd':
|
|
||||||
return RoadType.SECONDARY;
|
|
||||||
case 'e':
|
|
||||||
return RoadType.MOTORWAY_LINK;
|
|
||||||
case 'f':
|
|
||||||
return RoadType.TRUNK_LINK;
|
|
||||||
case 'g':
|
|
||||||
return RoadType.PRIMARY_LINK;
|
|
||||||
case 'h':
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new BinaryGraphReader using the given DataInputStream.
|
|
||||||
*
|
|
||||||
* @param dis
|
|
||||||
*/
|
|
||||||
public BinaryGraphReaderInsa2016(DataInputStream dis) {
|
|
||||||
super(MAGIC_NUMBER, VERSION, dis);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Graph read() throws IOException {
|
|
||||||
|
|
||||||
// Read and check magic number and file version.
|
|
||||||
checkMagicNumberOrThrow(dis.readInt());
|
|
||||||
checkVersionOrThrow(dis.readInt());
|
|
||||||
|
|
||||||
// Read map id.
|
|
||||||
int mapId = dis.readInt();
|
|
||||||
|
|
||||||
// Read zone.
|
|
||||||
int graphZone = dis.readInt();
|
|
||||||
|
|
||||||
// Number of descriptors and nodes.
|
|
||||||
int nbDesc = dis.readInt();
|
|
||||||
int nbNodes = dis.readInt();
|
|
||||||
|
|
||||||
// Number of successors for each nodes.
|
|
||||||
int[] nbSuccessors = new int[nbNodes];
|
|
||||||
|
|
||||||
// Construct an array list with initial capacity of nbNodes.
|
|
||||||
ArrayList<Node> nodes = new ArrayList<Node>(nbNodes);
|
|
||||||
|
|
||||||
// Read nodes.
|
|
||||||
for (int node = 0; node < nbNodes; ++node) {
|
|
||||||
float longitude = ((float) dis.readInt()) / 1E6f;
|
|
||||||
float latitude = ((float) dis.readInt()) / 1E6f;
|
|
||||||
nbSuccessors[node] = dis.readUnsignedByte();
|
|
||||||
nodes.add(new Node(node, new Point(longitude, latitude)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check format.
|
|
||||||
checkByteOrThrow(255);
|
|
||||||
|
|
||||||
// Read descriptors.
|
|
||||||
RoadInformation[] descs = new RoadInformation[nbDesc];
|
|
||||||
|
|
||||||
// Read
|
|
||||||
for (int descr = 0; descr < nbDesc; ++descr) {
|
|
||||||
descs[descr] = readRoadInformation();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check format.
|
|
||||||
checkByteOrThrow(254);
|
|
||||||
|
|
||||||
// Read successors and convert to arcs.
|
|
||||||
for (int node = 0; node < nbNodes; ++node) {
|
|
||||||
for (int succ = 0; succ < nbSuccessors[node]; ++succ) {
|
|
||||||
|
|
||||||
// Read destination zone.
|
|
||||||
int destZone = dis.readUnsignedByte();
|
|
||||||
|
|
||||||
// Read target node number.
|
|
||||||
int destNode = this.read24bits();
|
|
||||||
|
|
||||||
// Read information number.
|
|
||||||
int descrNum = this.read24bits();
|
|
||||||
|
|
||||||
// Length of the arc.
|
|
||||||
int length = dis.readUnsignedShort();
|
|
||||||
|
|
||||||
// Number of segments.
|
|
||||||
int nbSegments = dis.readUnsignedShort();
|
|
||||||
|
|
||||||
// Chain of points corresponding to the segments.
|
|
||||||
ArrayList<Point> points = new ArrayList<Point>(nbSegments + 2);
|
|
||||||
points.add(nodes.get(node).getPoint());
|
|
||||||
|
|
||||||
for (int seg = 0; seg < nbSegments; ++seg) {
|
|
||||||
Point lastPoint = points.get(points.size() - 1);
|
|
||||||
|
|
||||||
float dlon = (dis.readShort()) / 2.0e5f;
|
|
||||||
float dlat = (dis.readShort()) / 2.0e5f;
|
|
||||||
|
|
||||||
points.add(new Point(lastPoint.getLongitude() + dlon,
|
|
||||||
lastPoint.getLatitude() + dlat));
|
|
||||||
}
|
|
||||||
|
|
||||||
points.add(nodes.get(destNode).getPoint());
|
|
||||||
|
|
||||||
if (graphZone == destZone) {
|
|
||||||
|
|
||||||
RoadInformation info = descs[descrNum];
|
|
||||||
Node orig = nodes.get(node);
|
|
||||||
Node dest = nodes.get(destNode);
|
|
||||||
|
|
||||||
// Add successor to initial arc.
|
|
||||||
new Arc(orig, dest, length, info, points);
|
|
||||||
|
|
||||||
// And reverse arc if its a two-way road.
|
|
||||||
if (!info.isOneWay()) {
|
|
||||||
// Add without segments.
|
|
||||||
ArrayList<Point> rPoints = new ArrayList<Point>(points);
|
|
||||||
Collections.reverse(rPoints);
|
|
||||||
new Arc(dest, orig, length, info, rPoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check format.
|
|
||||||
checkByteOrThrow(253);
|
|
||||||
|
|
||||||
return new Graph(Integer.toHexString(mapId), "", nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the next road information from the stream.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private RoadInformation readRoadInformation() throws IOException {
|
|
||||||
char type = (char) dis.readUnsignedByte();
|
|
||||||
int x = dis.readUnsignedByte();
|
|
||||||
return new RoadInformation(toRoadType(type), new AccessRestriction(), (x & 0x80) > 0,
|
|
||||||
(x & 0x7F) * 5, dis.readUTF());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.insa.graph.Arc;
|
import org.insa.graph.Arc;
|
||||||
import org.insa.graph.Graph;
|
import org.insa.graph.Graph;
|
||||||
|
import org.insa.graph.GraphInformation;
|
||||||
import org.insa.graph.Node;
|
import org.insa.graph.Node;
|
||||||
import org.insa.graph.Point;
|
import org.insa.graph.Point;
|
||||||
import org.insa.graph.RoadInformation;
|
import org.insa.graph.RoadInformation;
|
||||||
@ -63,8 +64,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
allowedModes.put(AccessMode.MOTORCAR, (access & MASK_MOTORCAR) != 0);
|
allowedModes.put(AccessMode.MOTORCAR, (access & MASK_MOTORCAR) != 0);
|
||||||
allowedModes.put(AccessMode.BUS, (access & MASK_BUS) != 0);
|
allowedModes.put(AccessMode.BUS, (access & MASK_BUS) != 0);
|
||||||
|
|
||||||
return new AccessRestriction((access & MASK_PRIVATE) != 0,
|
return new AccessRestriction((access & MASK_PRIVATE) != 0, (access & MASK_PUBLIC_TRANSPORT) != 0, allowedModes);
|
||||||
(access & MASK_PUBLIC_TRANSPORT) != 0, allowedModes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,9 +138,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
mapId = "0x" + Integer.toHexString(dis.readInt());
|
mapId = "0x" + Integer.toHexString(dis.readInt());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
byte[] byteId = new byte[MAP_ID_FIELD_LENGTH];
|
mapId = readFixedLengthString(MAP_ID_FIELD_LENGTH, "UTF-8");
|
||||||
dis.read(byteId);
|
|
||||||
mapId = new String(byteId, "UTF-8");
|
|
||||||
mapName = dis.readUTF();
|
mapName = dis.readUTF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,16 +175,21 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
|
|
||||||
// Read
|
// Read
|
||||||
observers.forEach((observer) -> observer.notifyStartReadingDescriptors(nbDesc));
|
observers.forEach((observer) -> observer.notifyStartReadingDescriptors(nbDesc));
|
||||||
|
int maxSpeed = 0;
|
||||||
for (int descr = 0; descr < nbDesc; ++descr) {
|
for (int descr = 0; descr < nbDesc; ++descr) {
|
||||||
final RoadInformation roadinf = readRoadInformation();
|
final RoadInformation roadinf = readRoadInformation();
|
||||||
descs[descr] = roadinf;
|
descs[descr] = roadinf;
|
||||||
observers.forEach((observer) -> observer.notifyNewDescriptorRead(roadinf));
|
observers.forEach((observer) -> observer.notifyNewDescriptorRead(roadinf));
|
||||||
|
|
||||||
|
// Update max speed
|
||||||
|
maxSpeed = Math.max(roadinf.getMaximumSpeed(), maxSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check format.
|
// Check format.
|
||||||
checkByteOrThrow(254);
|
checkByteOrThrow(254);
|
||||||
|
|
||||||
// Read successors and convert to arcs.
|
// Read successors and convert to arcs.
|
||||||
|
int maxLength = 0;
|
||||||
final int copyNbTotalSuccesors = nbTotalSuccessors; // Stupid Java...
|
final int copyNbTotalSuccesors = nbTotalSuccessors; // Stupid Java...
|
||||||
observers.forEach((observer) -> observer.notifyStartReadingArcs(copyNbTotalSuccesors));
|
observers.forEach((observer) -> observer.notifyStartReadingArcs(copyNbTotalSuccesors));
|
||||||
for (int node = 0; node < nbNodes; ++node) {
|
for (int node = 0; node < nbNodes; ++node) {
|
||||||
@ -200,6 +203,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
|
|
||||||
// Length of the arc.
|
// Length of the arc.
|
||||||
int length = dis.readUnsignedShort();
|
int length = dis.readUnsignedShort();
|
||||||
|
maxLength = Math.max(length, maxLength);
|
||||||
|
|
||||||
// Number of segments.
|
// Number of segments.
|
||||||
int nbSegments = dis.readUnsignedShort();
|
int nbSegments = dis.readUnsignedShort();
|
||||||
@ -214,8 +218,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
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());
|
||||||
@ -243,7 +246,9 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
|
|
||||||
observers.forEach((observer) -> observer.notifyEndReading());
|
observers.forEach((observer) -> observer.notifyEndReading());
|
||||||
|
|
||||||
return new Graph(mapId, mapName, nodes);
|
this.dis.close();
|
||||||
|
|
||||||
|
return new Graph(mapId, mapName, nodes, new GraphInformation(maxSpeed, maxLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,8 +263,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
if (getCurrentVersion() >= 6) {
|
if (getCurrentVersion() >= 6) {
|
||||||
access = toAccessInformation(dis.readUnsignedShort());
|
access = toAccessInformation(dis.readUnsignedShort());
|
||||||
}
|
}
|
||||||
return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5,
|
return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF());
|
||||||
dis.readUTF());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,7 @@ public class BinaryPathReader extends BinaryReader implements PathReader {
|
|||||||
checkVersionOrThrow(dis.readInt());
|
checkVersionOrThrow(dis.readInt());
|
||||||
|
|
||||||
// Read map ID and check against graph.
|
// Read map ID and check against graph.
|
||||||
byte[] mapIdBytes = new byte[BinaryGraphReaderInsa2018.MAP_ID_FIELD_LENGTH];
|
String mapId = readFixedLengthString(BinaryGraphReaderInsa2018.MAP_ID_FIELD_LENGTH, "UTF-8");
|
||||||
dis.read(mapIdBytes);
|
|
||||||
|
|
||||||
String mapId = new String(mapIdBytes, "UTF-8");
|
|
||||||
|
|
||||||
if (!mapId.equals(graph.getMapId())) {
|
if (!mapId.equals(graph.getMapId())) {
|
||||||
throw new MapMismatchException(mapId, graph.getMapId());
|
throw new MapMismatchException(mapId, graph.getMapId());
|
||||||
|
@ -76,6 +76,22 @@ public abstract class BinaryReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an bytes array of fixed length from the input and convert it to a string
|
||||||
|
* using the given charset, removing any trailing '\0'.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* @param charset
|
||||||
|
*
|
||||||
|
* @return an UTF-8 string read from the input.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected String readFixedLengthString(int length, String charset) throws IOException {
|
||||||
|
byte[] bytes = new byte[length];
|
||||||
|
this.dis.read(bytes);
|
||||||
|
return new String(bytes, "UTF-8").trim();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read 24 bits from the stream and return the corresponding integer value.
|
* Read 24 bits from the stream and return the corresponding integer value.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user