From 8acc13c7f6414c3eeaba7dc0a28ec9dc1b84d174 Mon Sep 17 00:00:00 2001 From: Holt59 Date: Sun, 4 Mar 2018 21:22:52 +0100 Subject: [PATCH] Change the way restrictions on arc are managed. --- .../org/insa/graph/AccessRestrictions.java | 62 ++++++++--- src/main/org/insa/graph/RoadInformation.java | 2 +- .../graph/io/BinaryGraphReaderInsa2018.java | 101 +++++++++++------- .../org/insa/graphics/AlgorithmPanel.java | 10 +- .../graphics/drawing/BasicGraphPalette.java | 8 +- src/test/org/insa/graph/PathTest.java | 4 +- 6 files changed, 122 insertions(+), 65 deletions(-) diff --git a/src/main/org/insa/graph/AccessRestrictions.java b/src/main/org/insa/graph/AccessRestrictions.java index 8d39f93..6bc55b3 100644 --- a/src/main/org/insa/graph/AccessRestrictions.java +++ b/src/main/org/insa/graph/AccessRestrictions.java @@ -23,7 +23,13 @@ public class AccessRestrictions { } public enum AccessRestriction { - ALLOWED, FORBIDDEN, PRIVATE, DESTINATION, FORESTRY, UNKNOWN + ALLOWED, FORBIDDEN, PRIVATE, DESTINATION, DELIVERY, CUSTOMERS, FORESTRY, UNKNOWN; + + // Not private or forbidden + public static final EnumSet ALLOWED_FOR_SOMETHING = EnumSet.of(AccessRestriction.ALLOWED, + AccessRestriction.DESTINATION, AccessRestriction.DESTINATION, AccessRestriction.DELIVERY, + AccessRestriction.CUSTOMERS, AccessRestriction.FORESTRY); + } // Map mode -> restriction @@ -39,35 +45,59 @@ public class AccessRestrictions { } } + public long value = 0; + /** * Create a new instance of access restrictions with the given restrictions. * * @param restrictions */ - public AccessRestrictions(EnumMap restrictions) { + public AccessRestrictions(EnumMap restrictions, long value) { this.restrictions = restrictions; + this.value = value; } /** - * // TODO: - * - * isRestrictedTo(AccessMode.FOOT, EnumSet.of(Restriction.PRIVATE, - * Restriction.DESTINATION)); + * @param mode * + * @return Restriction for the given mode. + */ + public AccessRestriction getRestrictionFor(AccessMode mode) { + return restrictions.getOrDefault(mode, AccessRestriction.UNKNOWN); + } + + /** * @param mode * @param restrictions - * @return + * + * @return true if the given mode is allowed for any of the given restrictions. */ public boolean isAllowedForAny(AccessMode mode, EnumSet restrictions) { - AccessRestriction modeRestrictions = this.restrictions.getOrDefault(mode, AccessRestriction.UNKNOWN); - if (modeRestrictions == AccessRestriction.UNKNOWN) { - return true; + return restrictions.contains(getRestrictionFor(mode)); + } + + /** + * @param mode + * @param restriction + * + * @return true if the given mode is allowed for the given restriction. + */ + public boolean isAllowedFor(AccessMode mode, AccessRestriction restriction) { + return getRestrictionFor(mode).equals(restriction); + } + + /** + * @param modes + * @param restrictions + * + * @return true if all the given modes are allowed for any of the given + * restrictions. + */ + public boolean areAllAllowedForAny(EnumSet modes, EnumSet restrictions) { + boolean allowed = true; + for (AccessMode mode: modes) { + allowed = allowed && isAllowedForAny(mode, restrictions); } - return restrictions.contains(modeRestrictions); + return allowed; } - - public boolean isAllowedFor(AccessMode mode, AccessRestriction restrictions) { - return isAllowedForAny(mode, EnumSet.of(restrictions)); - } - } diff --git a/src/main/org/insa/graph/RoadInformation.java b/src/main/org/insa/graph/RoadInformation.java index 996ca28..1208b3a 100644 --- a/src/main/org/insa/graph/RoadInformation.java +++ b/src/main/org/insa/graph/RoadInformation.java @@ -26,7 +26,7 @@ public class RoadInformation { SERVICE, ROUNDABOUT, PEDESTRIAN, - BICYCLE, + CYCLEWAY, COASTLINE } diff --git a/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java b/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java index 1d38017..9d95bc1 100644 --- a/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java +++ b/src/main/org/insa/graph/io/BinaryGraphReaderInsa2018.java @@ -5,9 +5,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.EnumMap; -import java.util.Map; import org.insa.graph.AccessRestrictions; +import org.insa.graph.AccessRestrictions.AccessMode; import org.insa.graph.AccessRestrictions.AccessRestriction; import org.insa.graph.Arc; import org.insa.graph.Graph; @@ -26,15 +26,38 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead // Length of the map id field (in bytes) protected static final int MAP_ID_FIELD_LENGTH = 32; - /** - * Create a new access information by parsing the given value (V6 version). + /* + * 4 bits are associated to each type of vehicle, these 4 bits represents the + * type of access (see below). * - * @param access - * @return + * Note: The highest 4 bits of the long are not used, for compatibility issue + * (unsigned/signed... ). */ - protected static AccessRestrictions toAccessInformationV7(long access) { - } + // @formatter:off + // These masks indicates which bit should be set for the access value. + public static final long + MASK_NO = 0x0L, // *=no, + MASK_YES = 0x111111111111111L, // *=yes + MASK_PRIVATE = 0x222222222222222L, // *=private + MASK_DESTINATION = 0x333333333333333L, // *=destination + MASK_DELIVERY = 0x444444444444444L, // *=delivery + MASK_CUSTOMERS = 0x555555555555555L, // *=customers, + MASK_FORESTRY = 0x666666666666666L, // *=forestry,*=agricultural + MASK_UNKNOWN = 0xfffffffffffffffL; + + // These masks indicates which parts of the long should be set for each type of + // vehicle + public static final long + MASK_FOOT = 0x00000000000000fL, // foot=* + MASK_BICYCLE = 0x000000000000f00L, // bicycle=* + MASK_SMALL_MOTORCYCLE = 0x00000000000f000L, // moped,mofa=* + MASK_AGRICULTURAL = 0x0000000000f0000L, // agricultural=* + MASK_MOTORCYCLE = 0x000000000f00000L, // motorcycle=* + MASK_MOTORCAR = 0x00000000f000000L, // motorcar=* + MASK_HEAVY_GOODS = 0x0000000f0000000L, // motorcar=* + MASK_PUBLIC_TRANSPORT = 0x0000f0000000000L; // psv,bus,minibus,share_taxi=* + // @formatter:on /** * Create a new access information by parsing the given value (V6 version). @@ -42,39 +65,33 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead * @param access * @return */ - protected static AccessRestrictions toAccessInformationV6(int access) { + protected static AccessRestrictions toAccessInformationV7(final long access) { + final AccessRestriction[] allRestrictions = new AccessRestriction[] { AccessRestriction.FORBIDDEN, + AccessRestriction.ALLOWED, AccessRestriction.PRIVATE, AccessRestriction.DESTINATION, + AccessRestriction.DELIVERY, AccessRestriction.CUSTOMERS, AccessRestriction.FORESTRY }; - // Some masks... - final int MASK_UNKNOWN = 0x01; - final int MASK_PRIVATE = 0x02; - @SuppressWarnings("unused") - final int MASK_AGRICULTURAL = 0x04; - @SuppressWarnings("unused") - final int MASK_SERVICE = 0x08; - final int MASK_PUBLIC_TRANSPORT = 0x10; + final AccessMode[] allModes = new AccessMode[] { AccessMode.FOOT, null, AccessMode.BICYCLE, + AccessMode.SMALL_MOTORCYCLE, AccessMode.AGRICULTURAL, AccessMode.MOTORCYCLE, AccessMode.MOTORCAR, + AccessMode.HEAVY_GOODS, null, AccessMode.PUBLIC_TRANSPORT }; - final int MASK_FOOT = 0x01 << 8; - final int MASK_BICYCLE = 0x02 << 8; - final int MASK_MOTORCYCLE = 0x0C << 8; - final int MASK_SMALL_MOTORCYCLE = 0x08 << 8; - final int MASK_MOTORCAR = 0x10 << 8; - final int MASK_BUS = 0x20 << 8; - - // Unknown -> Return default access information. - if ((access & MASK_UNKNOWN) != 0) { - return new AccessRestriction(); + // fill maps... + EnumMap restrictions = new EnumMap<>(AccessMode.class); + long copyAccess = access; + for (AccessMode mode: allModes) { + if (mode == null) { + continue; // filling cells + } + int value = (int) (copyAccess & 0xf); + if (value < allRestrictions.length) { + restrictions.put(mode, allRestrictions[value]); + } + else { + restrictions.put(mode, AccessRestriction.UNKNOWN); + } + copyAccess = copyAccess >> 4; } - Map allowedModes = new EnumMap<>(AccessMode.class); - - allowedModes.put(AccessMode.FOOT, (access & MASK_FOOT) != 0); - allowedModes.put(AccessMode.BICYCLE, (access & MASK_BICYCLE) != 0); - allowedModes.put(AccessMode.SMALL_MOTORCYCLE, (access & MASK_SMALL_MOTORCYCLE) != 0); - allowedModes.put(AccessMode.MOTORCYCLE, (access & MASK_MOTORCYCLE) != 0); - 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 AccessRestrictions(restrictions, access); } /** @@ -109,15 +126,20 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead case 'j': return RoadType.RESIDENTIAL; case 'k': - return RoadType.UNCLASSIFIED; case 'l': - return RoadType.ROAD; + return RoadType.UNCLASSIFIED; case 'm': return RoadType.LIVING_STREET; case 'n': return RoadType.SERVICE; case 'o': return RoadType.ROUNDABOUT; + case 'p': + return RoadType.PEDESTRIAN; + case 'r': + return RoadType.CYCLEWAY; + case 's': + return RoadType.TRACK; case 'z': return RoadType.COASTLINE; } @@ -273,9 +295,6 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead if (getCurrentVersion() >= 7) { access = toAccessInformationV7(dis.readLong()); } - else if (getCurrentVersion() >= 6) { - access = toAccessInformationV6(dis.readUnsignedShort()); - } return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF()); } diff --git a/src/main/org/insa/graphics/AlgorithmPanel.java b/src/main/org/insa/graphics/AlgorithmPanel.java index a6c7e04..e901a2a 100644 --- a/src/main/org/insa/graphics/AlgorithmPanel.java +++ b/src/main/org/insa/graphics/AlgorithmPanel.java @@ -10,6 +10,7 @@ import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import javax.swing.Box; @@ -29,9 +30,11 @@ import org.insa.algo.AbstractInputData; import org.insa.algo.AbstractInputData.ArcFilter; import org.insa.algo.AbstractInputData.Mode; import org.insa.algo.AlgorithmFactory; +import org.insa.graph.AccessRestrictions; +import org.insa.graph.AccessRestrictions.AccessMode; +import org.insa.graph.AccessRestrictions.AccessRestriction; import org.insa.graph.Arc; import org.insa.graph.Node; -import org.insa.graph.RoadInformation.AccessMode; import org.insa.graphics.NodesInputPanel.InputChangedEvent; public class AlgorithmPanel extends JPanel { @@ -182,8 +185,9 @@ public class AlgorithmPanel extends JPanel { }, new AbstractInputData.ArcFilter() { @Override public boolean isAllowed(Arc arc) { - return arc.getRoadInformation().getAccessRestrictions().isAllowedFor(AccessMode.MOTORCAR) - && !arc.getRoadInformation().getAccessRestrictions().isPrivate(); + AccessRestrictions restrictions = arc.getRoadInformation().getAccessRestrictions(); + return restrictions.isAllowedForAny(AccessMode.MOTORCAR, EnumSet + .complementOf(EnumSet.of(AccessRestriction.PRIVATE, AccessRestriction.FORBIDDEN))); } @Override diff --git a/src/main/org/insa/graphics/drawing/BasicGraphPalette.java b/src/main/org/insa/graphics/drawing/BasicGraphPalette.java index 5107bf2..bce9674 100644 --- a/src/main/org/insa/graphics/drawing/BasicGraphPalette.java +++ b/src/main/org/insa/graphics/drawing/BasicGraphPalette.java @@ -52,10 +52,12 @@ public class BasicGraphPalette implements GraphPalette { case TERTIARY: case RESIDENTIAL: case UNCLASSIFIED: - case ROAD: case LIVING_STREET: case SERVICE: case ROUNDABOUT: + case PEDESTRIAN: + case CYCLEWAY: + case TRACK: color = smallroad; break; case COASTLINE: @@ -86,10 +88,12 @@ public class BasicGraphPalette implements GraphPalette { case TERTIARY: case RESIDENTIAL: case UNCLASSIFIED: - case ROAD: case LIVING_STREET: case SERVICE: case ROUNDABOUT: + case PEDESTRIAN: + case CYCLEWAY: + case TRACK: width = 1; break; case COASTLINE: diff --git a/src/test/org/insa/graph/PathTest.java b/src/test/org/insa/graph/PathTest.java index b1b8025..4aef38f 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, null, true, 36, ""), - speed20 = new RoadInformation(RoadType.ROAD, null, true, 72, ""); + RoadInformation speed10 = new RoadInformation(RoadType.MOTORWAY, null, true, 36, ""), + speed20 = new RoadInformation(RoadType.MOTORWAY, null, true, 72, ""); // Create nodes nodes = new Node[5];