1 package org.opentrafficsim.core.network; 2 3 import java.util.Arrays; 4 import java.util.LinkedHashSet; 5 6 import org.opentrafficsim.core.gtu.GTUDirectionality; 7 8 import nl.tudelft.simulation.immutablecollections.Immutable; 9 import nl.tudelft.simulation.immutablecollections.ImmutableHashSet; 10 import nl.tudelft.simulation.immutablecollections.ImmutableSet; 11 12 /** 13 * Permitted longitudinal driving directions. 14 * <p> 15 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 16 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>. 17 * <p> 18 * $LastChangedDate: 2018-09-19 13:55:45 +0200 (Wed, 19 Sep 2018) $, @version $Revision: 4006 $, by $Author: averbraeck $, 19 * initial version Oct 15, 2014 <br> 20 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 21 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 22 * @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a> 23 */ 24 public enum LongitudinalDirectionality 25 { 26 /** Direction the same as the direction of the graph, increasing fractional position when driving in this direction. */ 27 DIR_PLUS(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS }), 28 /** Direction opposite to the direction of the graph, decreasing fractional position when driving in this direction. */ 29 DIR_MINUS(new GTUDirectionality[] { GTUDirectionality.DIR_MINUS }), 30 /** Bidirectional. */ 31 DIR_BOTH(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS, GTUDirectionality.DIR_MINUS }), 32 /** No traffic possible. */ 33 DIR_NONE(new GTUDirectionality[] {}); 34 35 /** Array of permitted driving directions. */ 36 private final ImmutableSet<GTUDirectionality> directions; 37 38 /** 39 * Construct a new LongitudinalDirectionality. 40 * @param directions GTUDirectionality[]; array containing the permitted driving directions 41 */ 42 LongitudinalDirectionality(final GTUDirectionality[] directions) 43 { 44 this.directions = new ImmutableHashSet<>(new LinkedHashSet<>(Arrays.asList(directions)), Immutable.WRAP); 45 } 46 47 /** 48 * Retrieve the permitted driving directions. 49 * @return ImmutableSet<GTUDirectionality>; immutable set containing the permitted driving directions 50 */ 51 public final ImmutableSet<GTUDirectionality> getDirectionalities() 52 { 53 return this.directions; 54 } 55 56 /** 57 * This method looks if this directionality "contains" the provided other directionality. The logic table looks as follows: 58 * <table border="1" summary=""> 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 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 * Compute the intersection of this LongitudinalDirectionality with another LongitudinalDirectionality. 150 * @param other LongitudinalDirectionality; the other LongitudinalDirectionality 151 * @return LongitudinalDirectionality; the intersection of <code>this</code> and <code>other</code> 152 */ 153 public final LongitudinalDirectionality intersect(final LongitudinalDirectionality other) 154 { 155 switch (other) 156 { 157 case DIR_BOTH: 158 return this; 159 case DIR_MINUS: 160 if (this.equals(other)) 161 { 162 return this; 163 } 164 if (this.equals(DIR_BOTH)) 165 { 166 return other; 167 } 168 return DIR_NONE; 169 case DIR_NONE: 170 return other; 171 case DIR_PLUS: 172 if (this.equals(other)) 173 { 174 return this; 175 } 176 if (this.equals(DIR_BOTH)) 177 { 178 return other; 179 } 180 return DIR_NONE; 181 default: 182 System.err.println("intersect with null (returns DIR_NONE)"); 183 return DIR_NONE; 184 } 185 } 186 187 /** 188 * Check if a direction is permitted by this LongitudinalDirectionality. 189 * @param direction GTUDirectionality; the direction of motion in which a GTU moves, or wants to move 190 * @return boolean; true if the direction is permitted by this LongitudinalDirectionality; false if it is not permitted 191 */ 192 public final boolean permits(final GTUDirectionality direction) 193 { 194 switch (direction) 195 { 196 case DIR_MINUS: 197 return isBackwardOrBoth(); 198 case DIR_PLUS: 199 return isForwardOrBoth(); 200 default: 201 System.out.println("Bad direction: " + direction); 202 return false; 203 } 204 } 205 206 /** 207 * Return the inverse if this LongitudinalDirectionality. 208 * @return LongitudinalDirectionality; the directional inverse of this LongitudinalDirectionality 209 */ 210 public LongitudinalDirectionality invert() 211 { 212 switch (this) 213 { 214 case DIR_BOTH: 215 return this; 216 case DIR_MINUS: 217 return DIR_PLUS; 218 case DIR_NONE: 219 return this; 220 case DIR_PLUS: 221 return DIR_MINUS; 222 default: 223 return this; // cannot happen 224 } 225 } 226 227 }