org.opentripplanner.model.plan.WalkStep Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.model.plan;
import com.google.common.collect.Lists;
import org.opentripplanner.common.model.P2;
import org.opentripplanner.model.VehicleRentalStationInfo;
import org.opentripplanner.model.StreetNote;
import org.opentripplanner.model.WgsCoordinate;
import org.opentripplanner.routing.graph.Edge;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.opentripplanner.util.I18NString;
/**
* Represents one instruction in walking directions. Three examples from New York City:
*
* Turn onto Broadway from W 57th St (coming from 7th Ave):
* distance = 100 (say)
* walkDirection = RIGHT
* streetName = Broadway
* everything else null/false
*
*
* Now, turn from Broadway onto Central Park S via Columbus Circle
* distance = 200 (say)
* walkDirection = CIRCLE_COUNTERCLOCKWISE
* streetName = Central Park S
* exit = 1 (first exit)
* immediately everything else false
*
*
* Instead, go through the circle to continue on Broadway
* distance = 100 (say)
* walkDirection = CIRCLE_COUNTERCLOCKWISE
* streetName = Broadway
* exit = 3
* stayOn = true
* everything else false
*
*/
public class WalkStep {
/**
* The distance in meters that this step takes.
*/
public double distance = 0;
/**
* The relative direction of this step.
*/
public RelativeDirection relativeDirection;
/**
* The name of the street.
*/
public I18NString streetName;
/**
* The absolute direction of this step.
*/
public AbsoluteDirection absoluteDirection;
/**
* When exiting a highway or traffic circle, the exit name/number.
*/
public String exit;
/**
* Indicates whether or not a street changes direction at an intersection.
*/
public Boolean stayOn = false;
/**
* This step is on an open area, such as a plaza or train platform, and thus the directions should say something like "cross"
*/
public Boolean area = false;
/**
* The name of this street was generated by the system, so we should only display it once, and generally just display right/left directions
*/
public Boolean bogusName = false;
/**
* The coordinate of start of the step
*/
public WgsCoordinate startLocation;
/**
* The elevation profile as a comma-separated list of x,y values. x is the distance from the start of the step, y is the elevation at this
* distance.
*/
public List> elevation;
public final Set streetNotes = new HashSet<>();
public double angle;
/**
* Is this step walking with a bike?
*/
public boolean walkingBike;
/**
* The street edges that make up this walkStep.
* Used only in generating the streetEdges array in StreetSegment; not serialized.
*/
public List edges = Lists.newArrayList();
/**
* The vehicle rental on/off station info.
* Used only in generating the streetEdges array in StreetSegment; not serialized.
*/
public VehicleRentalStationInfo vehicleRentalOnStation;
public VehicleRentalStationInfo vehicleRentalOffStation;
public void setDirections(double lastAngle, double thisAngle, boolean roundabout) {
relativeDirection = getRelativeDirection(lastAngle, thisAngle, roundabout);
setAbsoluteDirection(thisAngle);
}
public void setAbsoluteDirection(double thisAngle) {
int octant = (int) (8 + Math.round(thisAngle * 8 / (Math.PI * 2))) % 8;
absoluteDirection = AbsoluteDirection.values()[octant];
}
public List> getElevation() {
return elevation;
}
public void addStreetNotes(Collection streetNotes) {
if(streetNotes == null) { return; }
this.streetNotes.addAll(streetNotes);
}
public static RelativeDirection getRelativeDirection(double lastAngle, double thisAngle,
boolean roundabout) {
double angleDiff = thisAngle - lastAngle;
if (angleDiff < 0) {
angleDiff += Math.PI * 2;
}
double ccwAngleDiff = Math.PI * 2 - angleDiff;
if (roundabout) {
// roundabout: the direction we turn onto it implies the circling direction
if (angleDiff > ccwAngleDiff) {
return RelativeDirection.CIRCLE_CLOCKWISE;
} else {
return RelativeDirection.CIRCLE_COUNTERCLOCKWISE;
}
}
// less than 0.3 rad counts as straight, to simplify walking instructions
if (angleDiff < 0.3 || ccwAngleDiff < 0.3) {
return RelativeDirection.CONTINUE;
} else if (angleDiff < 0.7) {
return RelativeDirection.SLIGHTLY_RIGHT;
} else if (ccwAngleDiff < 0.7) {
return RelativeDirection.SLIGHTLY_LEFT;
} else if (angleDiff < 2) {
return RelativeDirection.RIGHT;
} else if (ccwAngleDiff < 2) {
return RelativeDirection.LEFT;
} else if (angleDiff < Math.PI) {
return RelativeDirection.HARD_RIGHT;
} else {
return RelativeDirection.HARD_LEFT;
}
}
public String streetNameNoParens() {
int idx = streetName.toString().indexOf('(');
if (idx <= 0) {
return streetName.toString();
}
return streetName.toString().substring(0, idx - 1);
}
@Override
public String toString() {
String direction = absoluteDirection.toString();
if (relativeDirection != null) {
direction = relativeDirection.toString();
}
return "WalkStep(" + direction + " on " + streetName + " for " + distance + ")";
}
}