diff --git a/src/main/org/insa/graph/RoadInformation.java b/src/main/org/insa/graph/RoadInformation.java index c68e14a..7596e97 100644 --- a/src/main/org/insa/graph/RoadInformation.java +++ b/src/main/org/insa/graph/RoadInformation.java @@ -28,9 +28,36 @@ public class RoadInformation { COASTLINE } + /** + * Access mode. + */ + public enum AccessMode { + FOOT, BICYCLE, SMALL_MOTORCYCLE, MOTORCYCLE, MOTORCAR, BUS + } + + // Some masks... + @SuppressWarnings("unused") + private static final int MASK_UNKNOWN = 0x01; + private static final int MASK_PRIVATE = 0x02; + @SuppressWarnings("unused") + private static final int MASK_AGRICULTURAL = 0x04; + @SuppressWarnings("unused") + private static final int MASK_SERVICE = 0x08; + private static final int MASK_PUBLIC_TRANSPORT = 0x10; + + private static final int MASK_FOOT = 0x01 << 8; + private static final int MASK_BICYCLE = 0x02 << 8; + private static final int MASK_MOTORCYCLE = 0x0C << 8; + private static final int MASK_SMALL_MOTORCYCLE = 0x08 << 8; + private static final int MASK_MOTORCAR = 0x10 << 8; + private static final int MASK_BUS = 0x20 << 8; + // Type of the road (see above). private final RoadType type; + // Access information + private final int access; + // One way road? private final boolean oneway; @@ -40,13 +67,64 @@ public class RoadInformation { // Name of the road. private final String name; - public RoadInformation(RoadType roadType, boolean isOneWay, int maxSpeed, String name) { + public RoadInformation(RoadType roadType, int access, boolean isOneWay, int maxSpeed, + String name) { this.type = roadType; + this.access = access; this.oneway = isOneWay; this.maxSpeed = maxSpeed; this.name = name; } + // Access information + + /** + * @return true if this is a private road. + */ + public boolean isPrivate() { + return (this.access & MASK_PRIVATE) != 0; + } + + /** + * @return true if this road is reserved for public transport. + */ + public boolean isPublicTransport() { + return (this.access & MASK_PUBLIC_TRANSPORT) != 0; + } + + /** + * @param mode + * + * @return true if this road is allowed for the specified mode. + */ + public boolean isAllowedFor(AccessMode mode) { + if ((this.access & MASK_UNKNOWN) != 0) { + return true; + } + int maskedAccess = 0; + switch (mode) { + case FOOT: + maskedAccess = access & MASK_FOOT; + break; + case BICYCLE: + maskedAccess = access & MASK_BICYCLE; + break; + case SMALL_MOTORCYCLE: + maskedAccess = access & MASK_SMALL_MOTORCYCLE; + break; + case MOTORCYCLE: + maskedAccess = access & MASK_MOTORCYCLE; + break; + case MOTORCAR: + maskedAccess = access & MASK_MOTORCAR; + break; + case BUS: + maskedAccess = access & MASK_BUS; + break; + } + return maskedAccess != 0; + } + /** * @return Type of the road. */ @@ -77,7 +155,6 @@ public class RoadInformation { /* * (non-Javadoc) - * * @see java.lang.Object#toString() */ @Override @@ -89,7 +166,8 @@ public class RoadInformation { if (getType() == RoadType.MOTORWAY) { typeAsString = "highway"; } - return typeAsString + " : " + getName() + " " + (isOneWay() ? " (oneway) " : "") + maxSpeed + " km/h (max.)"; + return typeAsString + " : " + getName() + " " + (isOneWay() ? " (oneway) " : "") + maxSpeed + + " km/h (max.)"; } } diff --git a/src/main/org/insa/graph/io/BinaryGraphReaderInsa2016.java b/src/main/org/insa/graph/io/BinaryGraphReaderInsa2016.java index f19d874..e18ea0b 100644 --- a/src/main/org/insa/graph/io/BinaryGraphReaderInsa2016.java +++ b/src/main/org/insa/graph/io/BinaryGraphReaderInsa2016.java @@ -148,7 +148,8 @@ public class BinaryGraphReaderInsa2016 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()); @@ -188,7 +189,8 @@ public class BinaryGraphReaderInsa2016 extends BinaryReader implements GraphRead private RoadInformation readRoadInformation() throws IOException { char type = (char) dis.readUnsignedByte(); int x = dis.readUnsignedByte(); - return new RoadInformation(toRoadType(type), (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF()); + return new RoadInformation(toRoadType(type), 0, (x & 0x80) > 0, (x & 0x7F) * 5, + dis.readUTF()); } } diff --git a/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java b/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java index 225b260..4d900bc 100644 --- a/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java +++ b/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java @@ -154,7 +154,8 @@ 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()); @@ -193,7 +194,12 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead private RoadInformation readRoadInformation() throws IOException { char type = (char) dis.readUnsignedByte(); int x = dis.readUnsignedByte(); - return new RoadInformation(toRoadType(type), (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF()); + int access = 0xFF00; + if (getCurrentVersion() >= 6) { + access = dis.readUnsignedShort(); + } + return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5, + dis.readUTF()); } } diff --git a/src/main/org/insa/graph/io/BinaryReader.java b/src/main/org/insa/graph/io/BinaryReader.java index 2992316..5f27b39 100644 --- a/src/main/org/insa/graph/io/BinaryReader.java +++ b/src/main/org/insa/graph/io/BinaryReader.java @@ -8,7 +8,8 @@ import java.util.List; public abstract class BinaryReader { // Map version and magic number targeted for this reader. - private int version; + private int minVersion; + private int curVersion; private int magicNumber; // InputStream @@ -17,9 +18,9 @@ public abstract class BinaryReader { // List of observers protected List observers = new ArrayList<>(); - protected BinaryReader(int magicNumber, int version, DataInputStream dis) { + protected BinaryReader(int magicNumber, int minVersion, DataInputStream dis) { this.magicNumber = magicNumber; - this.version = version; + this.minVersion = minVersion; this.dis = dis; } @@ -31,20 +32,31 @@ public abstract class BinaryReader { } /** + * Check if the given version is greater than the minimum version, and update + * the current version if it is. + * * @param version * @throws BadVersionException */ - public void checkVersionOrThrow(int version) throws BadVersionException { - if (this.version != version) { - throw new BadVersionException(version, this.version); + protected void checkVersionOrThrow(int version) throws BadVersionException { + if (version < this.minVersion) { + throw new BadVersionException(version, this.minVersion); } + this.curVersion = version; + } + + /** + * @return the current version. + */ + protected int getCurrentVersion() { + return this.curVersion; } /** * @param magicNumber * @throws BadMagicNumberException */ - public void checkMagicNumberOrThrow(int magicNumber) throws BadMagicNumberException { + protected void checkMagicNumberOrThrow(int magicNumber) throws BadMagicNumberException { if (this.magicNumber != magicNumber) { throw new BadMagicNumberException(magicNumber, this.magicNumber); } @@ -58,7 +70,7 @@ public abstract class BinaryReader { * * @throws IOException */ - public void checkByteOrThrow(int i) throws IOException { + protected void checkByteOrThrow(int i) throws IOException { if (dis.readUnsignedByte() != i) { throw new BadFormatException(); } diff --git a/src/test/org/insa/graph/PathTest.java b/src/test/org/insa/graph/PathTest.java index e9627d9..8479607 100644 --- a/src/test/org/insa/graph/PathTest.java +++ b/src/test/org/insa/graph/PathTest.java @@ -31,8 +31,8 @@ public class PathTest { public static void initAll() throws IOException { // 10 and 20 meters per seconds - RoadInformation speed10 = new RoadInformation(RoadType.ROAD, true, 36, ""), - speed20 = new RoadInformation(RoadType.ROAD, true, 72, ""); + RoadInformation speed10 = new RoadInformation(RoadType.ROAD, 0, true, 36, ""), + speed20 = new RoadInformation(RoadType.ROAD, 0, true, 72, ""); // Create nodes nodes = new Node[5]; @@ -55,11 +55,12 @@ public class PathTest { graph = new Graph(0, Arrays.asList(nodes)); emptyPath = new Path(graph, new ArrayList()); - shortPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1 })); - longPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1, d2e })); - loopPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1, d2a })); - longLoopPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1, d2a, a2c, c2d_3, d2a, a2b, b2c })); - invalidPath = new Path(graph, Arrays.asList(new Arc[] { a2b, c2d_1, d2e })); + shortPath = new Path(graph, Arrays.asList(new Arc[]{ a2b, b2c, c2d_1 })); + longPath = new Path(graph, Arrays.asList(new Arc[]{ a2b, b2c, c2d_1, d2e })); + loopPath = new Path(graph, Arrays.asList(new Arc[]{ a2b, b2c, c2d_1, d2a })); + longLoopPath = new Path(graph, + Arrays.asList(new Arc[]{ a2b, b2c, c2d_1, d2a, a2c, c2d_3, d2a, a2b, b2c })); + invalidPath = new Path(graph, Arrays.asList(new Arc[]{ a2b, c2d_1, d2e })); } @@ -124,8 +125,9 @@ public class PathTest { Arc[] expected; // Simple construction - path = Path.createFastestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2] })); - expected = new Arc[] { a2b, b2c }; + path = Path.createFastestPathFromNodes(graph, + Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2] })); + expected = new Arc[]{ a2b, b2c }; assertEquals(expected.length, path.getArcs().size()); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], path.getArcs().get(i)); @@ -133,8 +135,8 @@ public class PathTest { // Not so simple construction path = Path.createFastestPathFromNodes(graph, - Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2], nodes[3] })); - expected = new Arc[] { a2b, b2c, c2d_3 }; + Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2], nodes[3] })); + expected = new Arc[]{ a2b, b2c, c2d_3 }; assertEquals(expected.length, path.getArcs().size()); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], path.getArcs().get(i)); @@ -147,8 +149,9 @@ public class PathTest { Arc[] expected; // Simple construction - path = Path.createShortestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2] })); - expected = new Arc[] { a2b, b2c }; + path = Path.createShortestPathFromNodes(graph, + Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2] })); + expected = new Arc[]{ a2b, b2c }; assertEquals(expected.length, path.getArcs().size()); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], path.getArcs().get(i)); @@ -156,8 +159,8 @@ public class PathTest { // Not so simple construction path = Path.createShortestPathFromNodes(graph, - Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2], nodes[3] })); - expected = new Arc[] { a2b, b2c, c2d_2 }; + Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2], nodes[3] })); + expected = new Arc[]{ a2b, b2c, c2d_2 }; assertEquals(expected.length, path.getArcs().size()); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], path.getArcs().get(i)); @@ -166,12 +169,12 @@ public class PathTest { @Test(expected = IllegalArgumentException.class) public void testCreateFastestPathFromNodesException() { - Path.createFastestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[1], nodes[0] })); + Path.createFastestPathFromNodes(graph, Arrays.asList(new Node[]{ nodes[1], nodes[0] })); } @Test(expected = IllegalArgumentException.class) public void testCreateShortestPathFromNodesException() { - Path.createShortestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[1], nodes[0] })); + Path.createShortestPathFromNodes(graph, Arrays.asList(new Node[]{ nodes[1], nodes[0] })); } }