1 package org.opentrafficsim.core.network; 2 3 import java.util.Arrays; 4 import java.util.LinkedHashSet; 5 6 import org.djutils.immutablecollections.Immutable; 7 import org.djutils.immutablecollections.ImmutableHashSet; 8 import org.djutils.immutablecollections.ImmutableSet; 9 import org.opentrafficsim.core.gtu.GTUDirectionality; 10 11 /** 12 * Permitted longitudinal driving directions. 13 * <p> 14 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 15 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>. 16 * <p> 17 * $LastChangedDate: 2020-02-24 11:14:29 +0100 (Mon, 24 Feb 2020) $, @version $Revision: 6393 $, by $Author: pknoppers $, 18 * initial version Oct 15, 2014 <br> 19 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 20 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 21 * @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a> 22 */ 23 public enum LongitudinalDirectionality 24 { 25 /** Direction the same as the direction of the graph, increasing fractional position when driving in this direction. */ 26 DIR_PLUS(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS }), 27 /** Direction opposite to the direction of the graph, decreasing fractional position when driving in this direction. */ 28 DIR_MINUS(new GTUDirectionality[] { GTUDirectionality.DIR_MINUS }), 29 /** Bidirectional. */ 30 DIR_BOTH(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS, GTUDirectionality.DIR_MINUS }), 31 /** No traffic possible. */ 32 DIR_NONE(new GTUDirectionality[] {}); 33 34 /** Array of permitted driving directions. */ 35 private final ImmutableSet<GTUDirectionality> directions; 36 37 /** 38 * Construct a new LongitudinalDirectionality. 39 * @param directions GTUDirectionality[]; array containing the permitted driving directions 40 */ 41 LongitudinalDirectionality(final GTUDirectionality[] directions) 42 { 43 this.directions = new ImmutableHashSet<>(new LinkedHashSet<>(Arrays.asList(directions)), Immutable.WRAP); 44 } 45 46 /** 47 * Retrieve the permitted driving directions. 48 * @return ImmutableSet<GTUDirectionality>; immutable set containing the permitted driving directions 49 */ 50 public final ImmutableSet<GTUDirectionality> getDirectionalities() 51 { 52 return this.directions; 53 } 54 55 /** 56 * This method looks if this directionality "contains" the provided other directionality. The logic table looks as follows: 57 * <table border="1"> 58 * <caption> </caption> 59 * <tr> 60 * <td><b>THIS ↓ OTHER →</b></td> 61 * <td><b>DIR_BOTH </b></td> 62 * <td><b>DIR_PLUS </b></td> 63 * <td><b>DIR_MINUS</b></td> 64 * <td><b>DIR_NONE </b></td> 65 * </tr> 66 * <tr> 67 * <td><b>DIR_BOTH</b></td> 68 * <td>true</td> 69 * <td>true</td> 70 * <td>true</td> 71 * <td>true</td> 72 * </tr> 73 * <tr> 74 * <td><b>DIR_PLUS</b></td> 75 * <td>false</td> 76 * <td>true</td> 77 * <td>false</td> 78 * <td>true</td> 79 * </tr> 80 * <tr> 81 * <td><b>DIR_MINUS</b></td> 82 * <td>false</td> 83 * <td>false</td> 84 * <td>true</td> 85 * <td>true</td> 86 * </tr> 87 * <tr> 88 * <td><b>DIR_NONE</b></td> 89 * <td>false</td> 90 * <td>false</td> 91 * <td>false</td> 92 * <td>true</td> 93 * </tr> 94 * </table> 95 * @param directionality LongitudinalDirectionality; the directionality to compare with 96 * @return whether this directionality "contains" the provided other directionality 97 */ 98 public final boolean contains(final LongitudinalDirectionality directionality) 99 { 100 return (this.equals(directionality) || this.equals(DIR_BOTH) || directionality.equals(DIR_NONE)) ? true : false; 101 } 102 103 /** 104 * Easy access method to test if the directionality is FORWARD or BOTH. 105 * @return whether the directionality is FORWARD or BOTH 106 */ 107 public final boolean isForwardOrBoth() 108 { 109 return this.equals(DIR_PLUS) || this.equals(DIR_BOTH); 110 } 111 112 /** 113 * Easy access method to test if the directionality is BACKWARD or BOTH. 114 * @return whether the directionality is BACKWARD or BOTH 115 */ 116 public final boolean isBackwardOrBoth() 117 { 118 return this.equals(DIR_MINUS) || this.equals(DIR_BOTH); 119 } 120 121 /** 122 * Easy access method to test if the directionality is FORWARD. 123 * @return whether the directionality is FORWARD 124 */ 125 public final boolean isForward() 126 { 127 return this.equals(DIR_PLUS); 128 } 129 130 /** 131 * Easy access method to test if the directionality is BACKWARD. 132 * @return whether the directionality is BACKWARD 133 */ 134 public final boolean isBackward() 135 { 136 return this.equals(DIR_MINUS); 137 } 138 139 /** 140 * Easy access method to test if the directionality is BACKWARD or BOTH. 141 * @return whether the directionality is BACKWARD or BOTH 142 */ 143 public final boolean isBoth() 144 { 145 return this.equals(DIR_BOTH); 146 } 147 148 /** 149 * Easy access method to test if the directionality is NONE. 150 * @return whether the directionality is NONE 151 */ 152 public final boolean isNone() 153 { 154 return this.equals(DIR_NONE); 155 } 156 157 /** 158 * Compute the intersection of this LongitudinalDirectionality with another LongitudinalDirectionality. 159 * @param other LongitudinalDirectionality; the other LongitudinalDirectionality 160 * @return LongitudinalDirectionality; the intersection of <code>this</code> and <code>other</code> 161 */ 162 public final LongitudinalDirectionalityonality.html#LongitudinalDirectionality">LongitudinalDirectionality intersect(final LongitudinalDirectionality other) 163 { 164 if (null == other) 165 { 166 System.err.println("other LongitudinalDirectionality should not be null; returning DIR_NONE"); 167 return DIR_NONE; 168 } 169 switch (other) 170 { 171 case DIR_BOTH: 172 return this; 173 case DIR_MINUS: 174 if (this.equals(other)) 175 { 176 return this; 177 } 178 if (this.equals(DIR_BOTH)) 179 { 180 return other; 181 } 182 return DIR_NONE; 183 case DIR_NONE: 184 return other; 185 case DIR_PLUS: 186 if (this.equals(other)) 187 { 188 return this; 189 } 190 if (this.equals(DIR_BOTH)) 191 { 192 return other; 193 } 194 return DIR_NONE; 195 default: 196 // Cannot happen (unless someone manages to change this enum). 197 System.err.println("intersect with ???? (returns DIR_NONE)"); 198 return DIR_NONE; 199 } 200 } 201 202 /** 203 * Check if a direction is permitted by this LongitudinalDirectionality. 204 * @param direction GTUDirectionality; the direction of motion in which a GTU moves, or wants to move 205 * @return boolean; true if the direction is permitted by this LongitudinalDirectionality; false if it is not permitted 206 */ 207 public final boolean permits(final GTUDirectionality direction) 208 { 209 switch (direction) 210 { 211 case DIR_MINUS: 212 return isBackwardOrBoth(); 213 case DIR_PLUS: 214 return isForwardOrBoth(); 215 default: 216 System.out.println("Bad direction: " + direction); 217 return false; 218 } 219 } 220 221 /** 222 * Return the inverse if this LongitudinalDirectionality. 223 * @return LongitudinalDirectionality; the directional inverse of this LongitudinalDirectionality 224 */ 225 public LongitudinalDirectionality invert() 226 { 227 switch (this) 228 { 229 case DIR_BOTH: 230 return this; 231 case DIR_MINUS: 232 return DIR_PLUS; 233 case DIR_NONE: 234 return this; 235 case DIR_PLUS: 236 return DIR_MINUS; 237 default: 238 return this; // cannot happen 239 } 240 } 241 242 }