Add extra information in graph.
This commit is contained in:
		| @@ -14,14 +14,25 @@ public class Graph { | ||||
|     // Nodes of the graph. | ||||
|     private final List<Node> nodes; | ||||
|  | ||||
|     // Graph information of this graph. | ||||
|     private final GraphInformation graphInfo; | ||||
|  | ||||
|     /** | ||||
|      * @param mapId ID of 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.mapName = mapName; | ||||
|         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); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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. | ||||
|      */ | ||||
|   | ||||
							
								
								
									
										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.Graph; | ||||
| import org.insa.graph.GraphInformation; | ||||
| import org.insa.graph.Node; | ||||
| import org.insa.graph.Point; | ||||
| 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.BUS, (access & MASK_BUS) != 0); | ||||
|  | ||||
|         return new AccessRestriction((access & MASK_PRIVATE) != 0, | ||||
|                 (access & MASK_PUBLIC_TRANSPORT) != 0, allowedModes); | ||||
|         return new AccessRestriction((access & MASK_PRIVATE) != 0, (access & MASK_PUBLIC_TRANSPORT) != 0, allowedModes); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -138,9 +138,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead | ||||
|             mapId = "0x" + Integer.toHexString(dis.readInt()); | ||||
|         } | ||||
|         else { | ||||
|             byte[] byteId = new byte[MAP_ID_FIELD_LENGTH]; | ||||
|             dis.read(byteId); | ||||
|             mapId = new String(byteId, "UTF-8"); | ||||
|             mapId = readFixedLengthString(MAP_ID_FIELD_LENGTH, "UTF-8"); | ||||
|             mapName = dis.readUTF(); | ||||
|         } | ||||
|  | ||||
| @@ -177,16 +175,21 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead | ||||
|  | ||||
|         // Read | ||||
|         observers.forEach((observer) -> observer.notifyStartReadingDescriptors(nbDesc)); | ||||
|         int maxSpeed = 0; | ||||
|         for (int descr = 0; descr < nbDesc; ++descr) { | ||||
|             final RoadInformation roadinf = readRoadInformation(); | ||||
|             descs[descr] = roadinf; | ||||
|             observers.forEach((observer) -> observer.notifyNewDescriptorRead(roadinf)); | ||||
|  | ||||
|             // Update max speed | ||||
|             maxSpeed = Math.max(roadinf.getMaximumSpeed(), maxSpeed); | ||||
|         } | ||||
|  | ||||
|         // Check format. | ||||
|         checkByteOrThrow(254); | ||||
|  | ||||
|         // Read successors and convert to arcs. | ||||
|         int maxLength = 0; | ||||
|         final int copyNbTotalSuccesors = nbTotalSuccessors; // Stupid Java... | ||||
|         observers.forEach((observer) -> observer.notifyStartReadingArcs(copyNbTotalSuccesors)); | ||||
|         for (int node = 0; node < nbNodes; ++node) { | ||||
| @@ -200,6 +203,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead | ||||
|  | ||||
|                 // Length of the arc. | ||||
|                 int length = dis.readUnsignedShort(); | ||||
|                 maxLength = Math.max(length, maxLength); | ||||
|  | ||||
|                 // Number of segments. | ||||
|                 int nbSegments = dis.readUnsignedShort(); | ||||
| @@ -214,8 +218,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead | ||||
|                     float dlon = (dis.readShort()) / 2.0e5f; | ||||
|                     float dlat = (dis.readShort()) / 2.0e5f; | ||||
|  | ||||
|                     points.add(new Point(lastPoint.getLongitude() + dlon, | ||||
|                             lastPoint.getLatitude() + dlat)); | ||||
|                     points.add(new Point(lastPoint.getLongitude() + dlon, lastPoint.getLatitude() + dlat)); | ||||
|                 } | ||||
|  | ||||
|                 points.add(nodes.get(destNode).getPoint()); | ||||
| @@ -243,7 +246,9 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead | ||||
|  | ||||
|         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) { | ||||
|             access = toAccessInformation(dis.readUnsignedShort()); | ||||
|         } | ||||
|         return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5, | ||||
|                 dis.readUTF()); | ||||
|         return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF()); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -26,10 +26,7 @@ public class BinaryPathReader extends BinaryReader implements PathReader { | ||||
|         checkVersionOrThrow(dis.readInt()); | ||||
|  | ||||
|         // Read map ID and check against graph. | ||||
|         byte[] mapIdBytes = new byte[BinaryGraphReaderInsa2018.MAP_ID_FIELD_LENGTH]; | ||||
|         dis.read(mapIdBytes); | ||||
|  | ||||
|         String mapId = new String(mapIdBytes, "UTF-8"); | ||||
|         String mapId = readFixedLengthString(BinaryGraphReaderInsa2018.MAP_ID_FIELD_LENGTH, "UTF-8"); | ||||
|  | ||||
|         if (!mapId.equals(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. | ||||
|      *  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user