/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.routing.edgetype; import java.util.Map; import java.util.HashMap; import java.util.EnumSet; import org.opentripplanner.routing.core.TraverseMode; import org.opentripplanner.routing.core.TraverseModeSet; import lombok.Getter; /** * Who can traverse a street in a single direction. * */ public enum StreetTraversalPermission { NONE(0), PEDESTRIAN(1), BICYCLE(2), PEDESTRIAN_AND_BICYCLE(2 | 1), CAR(4), PEDESTRIAN_AND_CAR(4 | 1), BICYCLE_AND_CAR(4 | 2), PEDESTRIAN_AND_BICYCLE_AND_CAR(4 | 2 | 1), // This is a configurable motor vehicle that is not a vanilla car. // e.g. truck, motor bike, etc. CUSTOM_MOTOR_VEHICLE(8), PEDESTRIAN_AND_CUSTOM_MOTOR_VEHICLE(8 | 1), BICYCLE_AND_CUSTOM_MOTOR_VEHICLE(8 | 2), PEDESTRIAN_BICYCLE_MOTOR(8 | 2 | 1), ALL_DRIVING(8 | 4), PEDESTRIAN_AND_DRIVING(8 | 4 | 1), BICYCLE_AND_DRIVING(8 | 4 | 2), ALL(8 | 4 | 2 | 1), CROSSHATCHED(16); // this street exists in both Beszel and Ul Qoma; traffic direction may depend on which city you're in. private static final Map<Integer, StreetTraversalPermission> lookup = new HashMap<Integer, StreetTraversalPermission>(); static { for (StreetTraversalPermission s : EnumSet.allOf(StreetTraversalPermission.class)) lookup.put(s.getCode(), s); } @Getter private int code; private StreetTraversalPermission(int code) { this.code = code; } public static StreetTraversalPermission get(int code) { return lookup.get(code); } public StreetTraversalPermission add(StreetTraversalPermission perm) { return get(this.getCode() | perm.getCode()); } public StreetTraversalPermission remove(StreetTraversalPermission perm) { return get(this.getCode() & ~perm.getCode()); } public StreetTraversalPermission modify(boolean permissive, StreetTraversalPermission perm) { return permissive ? add(perm) : remove(perm); } public boolean allows(StreetTraversalPermission perm) { return (code & perm.code) != 0; } /** * Returns true if any of these modes are allowed. * @param modes * @return */ public boolean allows(TraverseModeSet modes) { if (modes.getWalk() && allows(StreetTraversalPermission.PEDESTRIAN)) { return true; } else if (modes.getBicycle() && allows(StreetTraversalPermission.BICYCLE)) { return true; } else if (modes.getCar() && allows(StreetTraversalPermission.CAR)) { return true; } else if (modes.getCustomMotorVehicle() && allows(StreetTraversalPermission.CUSTOM_MOTOR_VEHICLE)) { return true; } return false; } /** * Returns true if this mode is allowed. * @param mode * @return */ public boolean allows(TraverseMode mode) { if (mode == TraverseMode.WALK && allows(StreetTraversalPermission.PEDESTRIAN)) { return true; } else if (mode == TraverseMode.BICYCLE && allows(StreetTraversalPermission.BICYCLE)) { return true; } else if (mode == TraverseMode.CAR && allows(StreetTraversalPermission.CAR)) { return true; } else if (mode == TraverseMode.CUSTOM_MOTOR_VEHICLE && allows(StreetTraversalPermission.CUSTOM_MOTOR_VEHICLE)) { return true; } return false; } /** * Returns true if there are any modes allowed by this permission. * @return */ public boolean allowsAnything() { return !this.allowsNothing(); } /** * Returns true if there no modes are by this permission. * @return */ public boolean allowsNothing() { // TODO(flamholz): what about CROSSHATCHED? return this == StreetTraversalPermission.NONE; } }