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-2019 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: 2019-03-16 19:17:15 +0100 (Sat, 16 Mar 2019) $, @version $Revision: 5157 $, by $Author: averbraeck $, 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" summary=""> 58 * <tr> 59 * <td><b>THIS ↓ OTHER →</b></td> 60 * <td><b>DIR_BOTH </b></td> 61 * <td><b>DIR_PLUS </b></td> 62 * <td><b>DIR_MINUS</b></td> 63 * <td><b>DIR_NONE </b></td> 64 * </tr> 65 * <tr> 66 * <td><b>DIR_BOTH</b></td> 67 * <td>true</td> 68 * <td>true</td> 69 * <td>true</td> 70 * <td>true</td> 71 * </tr> 72 * <tr> 73 * <td><b>DIR_PLUS</b></td> 74 * <td>false</td> 75 * <td>true</td> 76 * <td>false</td> 77 * <td>true</td> 78 * </tr> 79 * <tr> 80 * <td><b>DIR_MINUS</b></td> 81 * <td>false</td> 82 * <td>false</td> 83 * <td>true</td> 84 * <td>true</td> 85 * </tr> 86 * <tr> 87 * <td><b>DIR_NONE</b></td> 88 * <td>false</td> 89 * <td>false</td> 90 * <td>false</td> 91 * <td>true</td> 92 * </tr> 93 * </table> 94 * @param directionality LongitudinalDirectionality; the directionality to compare with 95 * @return whether this directionality "contains" the provided other directionality 96 */ 97 public final boolean contains(final LongitudinalDirectionality directionality) 98 { 99 return (this.equals(directionality) || this.equals(DIR_BOTH) || directionality.equals(DIR_NONE)) ? true : false; 100 } 101 102 /** 103 * Easy access method to test if the directionality is FORWARD or BOTH. 104 * @return whether the directionality is FORWARD or BOTH 105 */ 106 public final boolean isForwardOrBoth() 107 { 108 return this.equals(DIR_PLUS) || this.equals(DIR_BOTH); 109 } 110 111 /** 112 * Easy access method to test if the directionality is BACKWARD or BOTH. 113 * @return whether the directionality is BACKWARD or BOTH 114 */ 115 public final boolean isBackwardOrBoth() 116 { 117 return this.equals(DIR_MINUS) || this.equals(DIR_BOTH); 118 } 119 120 /** 121 * Easy access method to test if the directionality is FORWARD. 122 * @return whether the directionality is FORWARD 123 */ 124 public final boolean isForward() 125 { 126 return this.equals(DIR_PLUS); 127 } 128 129 /** 130 * Easy access method to test if the directionality is BACKWARD. 131 * @return whether the directionality is BACKWARD 132 */ 133 public final boolean isBackward() 134 { 135 return this.equals(DIR_MINUS); 136 } 137 138 /** 139 * Easy access method to test if the directionality is BACKWARD or BOTH. 140 * @return whether the directionality is BACKWARD or BOTH 141 */ 142 public final boolean isBoth() 143 { 144 return this.equals(DIR_BOTH); 145 } 146 147 /** 148 * Compute the intersection of this LongitudinalDirectionality with another LongitudinalDirectionality. 149 * @param other LongitudinalDirectionality; the other LongitudinalDirectionality 150 * @return LongitudinalDirectionality; the intersection of <code>this</code> and <code>other</code> 151 */ 152 public final LongitudinalDirectionality intersect(final LongitudinalDirectionality other) 153 { 154 switch (other) 155 { 156 case DIR_BOTH: 157 return this; 158 case DIR_MINUS: 159 if (this.equals(other)) 160 { 161 return this; 162 } 163 if (this.equals(DIR_BOTH)) 164 { 165 return other; 166 } 167 return DIR_NONE; 168 case DIR_NONE: 169 return other; 170 case DIR_PLUS: 171 if (this.equals(other)) 172 { 173 return this; 174 } 175 if (this.equals(DIR_BOTH)) 176 { 177 return other; 178 } 179 return DIR_NONE; 180 default: 181 System.err.println("intersect with null (returns DIR_NONE)"); 182 return DIR_NONE; 183 } 184 } 185 186 /** 187 * Check if a direction is permitted by this LongitudinalDirectionality. 188 * @param direction GTUDirectionality; the direction of motion in which a GTU moves, or wants to move 189 * @return boolean; true if the direction is permitted by this LongitudinalDirectionality; false if it is not permitted 190 */ 191 public final boolean permits(final GTUDirectionality direction) 192 { 193 switch (direction) 194 { 195 case DIR_MINUS: 196 return isBackwardOrBoth(); 197 case DIR_PLUS: 198 return isForwardOrBoth(); 199 default: 200 System.out.println("Bad direction: " + direction); 201 return false; 202 } 203 } 204 205 /** 206 * Return the inverse if this LongitudinalDirectionality. 207 * @return LongitudinalDirectionality; the directional inverse of this LongitudinalDirectionality 208 */ 209 public LongitudinalDirectionality invert() 210 { 211 switch (this) 212 { 213 case DIR_BOTH: 214 return this; 215 case DIR_MINUS: 216 return DIR_PLUS; 217 case DIR_NONE: 218 return this; 219 case DIR_PLUS: 220 return DIR_MINUS; 221 default: 222 return this; // cannot happen 223 } 224 } 225 226 }