/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.car.cluster.navigation;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
import android.annotation.SuppressLint;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.versionedparcelable.ParcelField;
import androidx.versionedparcelable.VersionedParcelable;
import androidx.versionedparcelable.VersionedParcelize;
import java.util.Objects;
/**
* Information about a maneuver that the driver will be required to perform.
*/
@VersionedParcelize
public final class Maneuver implements VersionedParcelable {
/**
* Possible maneuver types.
*/
public enum Type {
/**
* Maneuver type is unknown to the consumer, in which case the consumer shouldn't show any
* maneuver information.
*/
UNKNOWN,
/**
* Starting point of the navigation (e.g. "Start driving on Main St.")
*/
DEPART,
/**
* No turn, but the street name changes (e.g. "Continue on Main St.")
*/
NAME_CHANGE,
/**
* No turn (0-10 degrees). Used when we just wish to say "Keep left/right". Note that this
* is used in contrast to {@link Type#STRAIGHT} for disambiguating cases where there
* is more than one option to go into the same general direction.
*/
KEEP_LEFT,
/**
* @see #KEEP_LEFT
*/
KEEP_RIGHT,
/**
* Slight turn at an intersection (10-45 degrees).
*/
TURN_SLIGHT_LEFT,
/**
* @see #TURN_SLIGHT_LEFT
*/
TURN_SLIGHT_RIGHT,
/**
* Regular turn at an intersection (45-135 degrees).
*/
TURN_NORMAL_LEFT,
/**
* @see #TURN_NORMAL_LEFT
*/
TURN_NORMAL_RIGHT,
/**
* Sharp turn at an intersection (135-175 degrees).
*/
TURN_SHARP_LEFT,
/**
* @see #TURN_SHARP_LEFT
*/
TURN_SHARP_RIGHT,
/**
* A turn onto the opposite side of the same street (175-180 degrees).
*/
U_TURN_LEFT,
/**
* @see #U_TURN_LEFT
*/
U_TURN_RIGHT,
/**
* Slight turn (10-45 degrees) to enter a turnpike or freeway.
*/
ON_RAMP_SLIGHT_LEFT,
/**
* @see #ON_RAMP_SLIGHT_LEFT
*/
ON_RAMP_SLIGHT_RIGHT,
/**
* Regular turn (45-135 degrees) to enter a turnpike or freeway.
*/
ON_RAMP_NORMAL_LEFT,
/**
* @see #ON_RAMP_NORMAL_LEFT
*/
ON_RAMP_NORMAL_RIGHT,
/**
* Sharp turn (135-175 degrees) to enter a turnpike or freeway.
*/
ON_RAMP_SHARP_LEFT,
/**
* @see #ON_RAMP_SHARP_LEFT
*/
ON_RAMP_SHARP_RIGHT,
/**
* A turn onto the opposite side of the same street (175-180 degrees) to enter a turnpike or
* freeway.
*/
ON_RAMP_U_TURN_LEFT,
/**
* @see #ON_RAMP_U_TURN_LEFT
*/
ON_RAMP_U_TURN_RIGHT,
/**
* Slight turn (10-45 degrees) to exit a turnpike or freeway.
*/
OFF_RAMP_SLIGHT_LEFT,
/**
* @see #OFF_RAMP_SLIGHT_LEFT
*/
OFF_RAMP_SLIGHT_RIGHT,
/**
* Normal turn (45-135 degrees) to exit a turnpike or freeway.
*/
OFF_RAMP_NORMAL_LEFT,
/**
* @see #OFF_RAMP_NORMAL_LEFT
*/
OFF_RAMP_NORMAL_RIGHT,
/**
* Road diverges (e.g. "Keep left at the fork").
*/
FORK_LEFT,
/**
* @see #FORK_LEFT
*/
FORK_RIGHT,
/**
* Current road joins another (e.g. "Merge left onto Main St.").
*/
MERGE_LEFT,
/**
* @see #MERGE_LEFT
*/
MERGE_RIGHT,
/**
* Roundabout entrance on which the current road ends (e.g. "Enter the roundabout").
*/
ROUNDABOUT_ENTER,
/**
* Used when leaving a roundabout when the step starts in it (e.g. "Exit the roundabout").
*/
ROUNDABOUT_EXIT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is at sharp angle towards the right (135-175 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_SHARP_RIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is at normal angle towards the right (45-135 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_NORMAL_RIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is at slight angle towards the right (10-45 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_SLIGHT_RIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is straight ahead (0-10 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_STRAIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is at sharp angle towards the left (135-175 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_SHARP_LEFT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is at normal angle towards the left (45-135 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_NORMAL_LEFT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is at slight angle towards the left (10-45 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_SLIGHT_LEFT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a clockwise roundabout
* (as see from above) where the exit is on the opposite side of the road (175-180 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CW_U_TURN,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is at sharp angle towards the right
* (135-175 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_SHARP_RIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is at normal angle towards the right
* (45-135 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_NORMAL_RIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is at slight angle towards the right
* (10-45 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_SLIGHT_RIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is straight ahead (0-10 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_STRAIGHT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is at sharp angle towards the left
* (135-175 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_SHARP_LEFT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is at normal angle towards the left
* (45-135 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_NORMAL_LEFT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is at slight angle towards the left
* (10-45 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_SLIGHT_LEFT,
/**
* Entrance and exit (e.g. "At the roundabout, take Nth exit") on a counter-clockwise
* roundabout (as see from above) where the exit is on the opposite side of the road
* (175-180 degrees).
*/
ROUNDABOUT_ENTER_AND_EXIT_CCW_U_TURN,
/**
* Driver should steer straight.
*/
STRAIGHT,
/**
* Drive towards a boat ferry for vehicles (e.g. "Take the ferry").
*/
FERRY_BOAT,
/**
* Drive towards a train ferry for vehicles (e.g. "Take the train").
*/
FERRY_TRAIN,
/**
* Arrival to a destination.
*/
DESTINATION,
/**
* Arrival to a destination located straight ahead.
*/
DESTINATION_STRAIGHT,
/**
* Arrival to a destination located on the right side of the road.
*/
DESTINATION_LEFT,
/**
* @see #DESTINATION_LEFT
*/
DESTINATION_RIGHT,
}
@ParcelField(1)
EnumWrapper<Type> mType;
@ParcelField(2)
int mRoundaboutExitNumber;
@ParcelField(3)
ImageReference mIcon;
/**
* Used by {@link VersionedParcelable}
*
* @hide
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
Maneuver() {
}
/**
* @hide
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
Maneuver(@NonNull EnumWrapper<Type> type, int roundaboutExitNumber,
@Nullable ImageReference icon) {
mType = type;
mRoundaboutExitNumber = roundaboutExitNumber;
mIcon = icon;
}
/**
* Builder for creating a {@link Maneuver}
*/
public static final class Builder {
private EnumWrapper<Type> mType;
private int mRoundaboutExitNumber;
private ImageReference mIcon;
/**
* Sets the {@link Type} of maneuver, and any fallback values that could be used by the
* consumer if the type is unknown to it.
*
* @param type Main maneuver type
* @param fallbackTypes Variations of {@code type}, in case the consumer of this API doesn't
* know the main one (used for backward compatibility). For example,
* if the main type is {@link Type#OFF_RAMP_NORMAL_LEFT}, a fallback
* type could be {@link Type#TURN_NORMAL_LEFT}.
*/
@NonNull
public Builder setType(@NonNull Type type, @NonNull Type ... fallbackTypes) {
mType = EnumWrapper.of(type, fallbackTypes);
return this;
}
/**
* Sets the roundabout exit number, starting from 1 to designate the first exit after
* joining
* the roundabout, and increasing in circulation order. Only relevant if
* {@link #getType()} is
* {@link Type#ROUNDABOUT_EXIT} or any variation of ROUNDABOUT_ENTER_AND_EXIT.
*
* @return this object for chaining
* @see #getRoundaboutExitNumber() for more details.
*/
@NonNull
public Builder setRoundaboutExitNumber(int roundaboutExitNumber) {
mRoundaboutExitNumber = roundaboutExitNumber;
return this;
}
/**
* Sets a reference to an image presenting this maneuver. The provided image must be
* optimized to be presented in a square canvas (aspect ratio of 1:1).
*/
@NonNull
public Builder setIcon(@Nullable ImageReference icon) {
mIcon = icon;
return this;
}
/**
* Returns a {@link Maneuver} built with the provided information.
*/
@NonNull
public Maneuver build() {
return new Maneuver(mType, mRoundaboutExitNumber, mIcon);
}
}
/**
* Returns the maneuver type.
*/
@NonNull
public Type getType() {
return EnumWrapper.getValue(mType, Type.UNKNOWN);
}
/**
* Returns the roundabout exit number, starting from 1 to designate the first exit after joining
* the roundabout, and increasing in circulation order. Only relevant if {@link #getType()} is
* {@link Type#ROUNDABOUT_EXIT} or any variation of ROUNDABOUT_ENTER_AND_EXIT.
* <p>
* For example, if the driver is joining a counter-clockwise roundabout with 4 exits, then the
* exit to the right would be exit #1, the one straight ahead would be exit #2, the one to the
* left would be exit #3 and the one used by the driver to join the roundabout would be exit #4.
*/
public int getRoundaboutExitNumber() {
return mRoundaboutExitNumber;
}
/**
* Returns a reference to an image representing this maneuver, or null if image representation
* is not available. This image is optimized to be displayed in a square canvas (aspect ratio of
* 1:1).
*/
@Nullable
public ImageReference getIcon() {
return mIcon;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Maneuver maneuver = (Maneuver) o;
return getRoundaboutExitNumber() == maneuver.getRoundaboutExitNumber()
&& Objects.equals(getType(), maneuver.getType())
&& Objects.equals(getIcon(), maneuver.getIcon());
}
@Override
public int hashCode() {
return Objects.hash(getType(), getRoundaboutExitNumber(), getIcon());
}
// DefaultLocale suppressed as this method is only offered for debugging purposes.
@SuppressLint("DefaultLocale")
@Override
public String toString() {
return String.format("{type: %s, roundaboutExitNumer: %d, icon: %s}", mType,
mRoundaboutExitNumber, mIcon);
}
}