Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
hannesj committed Dec 19, 2016
2 parents d2f1db6 + 9089fcf commit f6656c3
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 29 deletions.
2 changes: 1 addition & 1 deletion docs/Deployments.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Following are known deployments of OTP in an agency-sponsored production capacity.

* **New York State** Department of Transportation's 511 [transit trip planner](http://511ny.org/tripplanner/default.aspx) provides itineraries for public transit systems throughout the state in a single unified OTP instance.
* **Arlington, Virginia**'s [commute planning site](http://www.carfreea2z.com/) for the Washington, DC metropolitan area depends on OpenTripPlanner to weigh the costs and benefits of various travel options, making use of profile routing.
* **Arlington, Virginia**'s [commute planning site](http://www.carfreeatoz.com/) for the Washington, DC metropolitan area depends on OpenTripPlanner to weigh the costs and benefits of various travel options, making use of profile routing.
* **Portland, Oregon, USA** TriMet [Regional Trip Planner](http://ride.trimet.org), the agency originally behind OpenTripPlanner.
* The **Helsinki** Regional Transport Authority (HSL) [trip planner](https://digitransit.fi/en/) based on OpenTripPlanner is in public beta as of spring 2016. Source code for their new UI is [available on Github](https://github.com/HSLdevcom/digitransit-ui).
* [**Valencia, Spain**](http://www.emtvalencia.es/geoportal/?lang=en_otp) from the Municipal Transport Company of Valencia S.A.U.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@
<dependency>
<groupId>org.onebusaway</groupId>
<artifactId>onebusaway-gtfs</artifactId>
<version>1.3.5-conveyal-SNAPSHOT</version>
<version>1.3.5-conveyal-SNAPSHOT-2</version>
</dependency>
<!-- Processing is used for the debug GUI (though we could probably use just Java2D) -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ public abstract class RoutingResource {
@QueryParam("maxHours")
private Double maxHours;

@QueryParam("disableAlertFiltering")
private Boolean disableAlertFiltering;

/*
* somewhat ugly bug fix: the graphService is only needed here for fetching per-graph time zones.
* this should ideally be done when setting the routing context, but at present departure/
Expand Down Expand Up @@ -539,6 +542,9 @@ protected RoutingRequest buildRequest() throws ParameterException {
if (maxHours != null)
request.maxHours = maxHours;

if (disableAlertFiltering != null)
request.disableAlertFiltering = disableAlertFiltering;

//getLocale function returns defaultLocale if locale is null
request.locale = ResourceBundleSingleton.INSTANCE.getLocale(locale);
return request;
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/org/opentripplanner/api/model/Leg.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ public class Leg {
@JsonSerialize
public String agencyUrl;

@XmlAttribute
@JsonSerialize
public String agencyBrandingUrl;

@XmlAttribute
@JsonSerialize
public int agencyTimeZoneOffset;
Expand Down Expand Up @@ -193,8 +197,15 @@ public class Leg {
@XmlAttribute
@JsonSerialize
public String serviceDate = null;

/**

/**
* For transit leg, the route's branding URL (if one exists). For non-transit legs, null.
*/
@XmlAttribute
@JsonSerialize
public String routeBrandingUrl = null;

/**
* The Place where the leg originates.
*/
public Place from = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static TripPlan generatePlan(List<GraphPath> paths, RoutingRequest reques
TripPlan plan = new TripPlan(from, to, request.getDateTime());

for (GraphPath path : paths) {
Itinerary itinerary = generateItinerary(path, request.showIntermediateStops, requestedLocale);
Itinerary itinerary = generateItinerary(path, request.showIntermediateStops, request.disableAlertFiltering, requestedLocale);
itinerary = adjustItinerary(request, itinerary);
plan.addItinerary(itinerary);
}
Expand Down Expand Up @@ -129,7 +129,7 @@ private static Itinerary adjustItinerary(RoutingRequest request, Itinerary itine
* @param showIntermediateStops Whether to include intermediate stops in the itinerary or not
* @return The generated itinerary
*/
public static Itinerary generateItinerary(GraphPath path, boolean showIntermediateStops, Locale requestedLocale) {
public static Itinerary generateItinerary(GraphPath path, boolean showIntermediateStops, boolean disableAlertFiltering, Locale requestedLocale) {
Itinerary itinerary = new Itinerary();

State[] states = new State[path.states.size()];
Expand All @@ -150,7 +150,7 @@ public static Itinerary generateItinerary(GraphPath path, boolean showIntermedia
}

for (State[] legStates : legsStates) {
itinerary.addLeg(generateLeg(graph, legStates, showIntermediateStops, requestedLocale));
itinerary.addLeg(generateLeg(graph, legStates, showIntermediateStops, disableAlertFiltering, requestedLocale));
}

addWalkSteps(graph, itinerary.legs, legsStates, requestedLocale);
Expand Down Expand Up @@ -287,7 +287,7 @@ private static State[][] sliceStates(State[] states) {
* @param showIntermediateStops Whether to include intermediate stops in the leg or not
* @return The generated leg
*/
private static Leg generateLeg(Graph graph, State[] states, boolean showIntermediateStops, Locale requestedLocale) {
private static Leg generateLeg(Graph graph, State[] states, boolean showIntermediateStops, boolean disableAlertFiltering, Locale requestedLocale) {
Leg leg = new Leg();

Edge[] edges = new Edge[states.length - 1];
Expand Down Expand Up @@ -320,7 +320,7 @@ private static Leg generateLeg(Graph graph, State[] states, boolean showIntermed

leg.rentedBike = states[0].isBikeRenting() && states[states.length - 1].isBikeRenting();

addModeAndAlerts(graph, leg, states, requestedLocale);
addModeAndAlerts(graph, leg, states, disableAlertFiltering, requestedLocale);
if (leg.isTransitLeg()) addRealTimeData(leg, states);

return leg;
Expand Down Expand Up @@ -517,7 +517,7 @@ private static void calculateElevations(Itinerary itinerary, Edge[] edges) {
* @param leg The leg to add the mode and alerts to
* @param states The states that go with the leg
*/
private static void addModeAndAlerts(Graph graph, Leg leg, State[] states, Locale requestedLocale) {
private static void addModeAndAlerts(Graph graph, Leg leg, State[] states, boolean disableAlertFiltering, Locale requestedLocale) {
for (State state : states) {
TraverseMode mode = state.getBackMode();
Set<Alert> alerts = graph.streetNotesService.getNotes(state);
Expand All @@ -534,7 +534,7 @@ private static void addModeAndAlerts(Graph graph, Leg leg, State[] states, Local
}

for (AlertPatch alertPatch : graph.getAlertPatches(edge)) {
if (alertPatch.displayDuring(state)) {
if (disableAlertFiltering || alertPatch.displayDuring(state)) {
if (alertPatch.hasTrip()) {
// If the alert patch contains a trip and that trip match this leg only add the alert for
// this leg.
Expand Down Expand Up @@ -567,6 +567,7 @@ private static void addTripFields(Leg leg, State[] states, Locale requestedLocal
leg.agencyId = agency.getId();
leg.agencyName = agency.getName();
leg.agencyUrl = agency.getUrl();
leg.agencyBrandingUrl = agency.getBrandingUrl();
leg.headsign = states[1].getBackDirection();
leg.route = states[states.length - 1].getBackEdge().getName(requestedLocale);
leg.routeColor = route.getColor();
Expand All @@ -575,6 +576,7 @@ private static void addTripFields(Leg leg, State[] states, Locale requestedLocal
leg.routeShortName = route.getShortName();
leg.routeTextColor = route.getTextColor();
leg.routeType = route.getType();
leg.routeBrandingUrl = route.getBrandingUrl();
leg.tripId = trip.getId();
leg.tripShortName = trip.getTripShortName();
leg.tripBlockId = trip.getBlockId();
Expand Down Expand Up @@ -732,6 +734,22 @@ public static List<WalkStep> generateWalkSteps(Graph graph, State[] states, Walk

State onBikeRentalState = null, offBikeRentalState = null;

// Check if this leg is a SimpleTransfer; if so, rebuild state array based on stored transfer edges
if (states.length == 2 && states[1].getBackEdge() instanceof SimpleTransfer) {
SimpleTransfer transferEdge = ((SimpleTransfer) states[1].getBackEdge());
List<Edge> transferEdges = transferEdge.getEdges();
if (transferEdges != null) {
State s = new State(transferEdges.get(0).getFromVertex(), states[0].getOptions());
ArrayList<State> transferStates = new ArrayList<>();
transferStates.add(s);
for (Edge e : transferEdges) {
s = e.traverse(s);
transferStates.add(s);
}
states = transferStates.toArray(new State[transferStates.size()]);
}
}

for (int i = 0; i < states.length - 1; i++) {
State backState = states[i];
State forwardState = states[i + 1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@ public static GraphBuilder forDirectory(CommandLineParameters params, File dir)
osmModule.staticBikeParkAndRide = builderParams.staticBikeParkAndRide;
osmModule.staticParkAndRide = builderParams.staticParkAndRide;
graphBuilder.addModule(osmModule);
graphBuilder.addModule(new PruneFloatingIslands());
PruneFloatingIslands pruneFloatingIslands = new PruneFloatingIslands();
pruneFloatingIslands.setPruningThresholdIslandWithoutStops(builderParams.pruningThresholdIslandWithoutStops);
pruneFloatingIslands.setPruningThresholdIslandWithStops(builderParams.pruningThresholdIslandWithStops);
graphBuilder.addModule(pruneFloatingIslands);
}
if ( hasGTFS ) {
List<GtfsBundle> gtfsBundles = Lists.newArrayList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) {
for (NearbyStopFinder.StopAtDistance sd : nearbyStopFinder.findNearbyStopsConsideringPatterns(ts0)) {
/* Skip the origin stop, loop transfers are not needed. */
if (sd.tstop == ts0 || pathwayDestinations.contains(sd.tstop)) continue;
new SimpleTransfer(ts0, sd.tstop, sd.dist, sd.geom);
new SimpleTransfer(ts0, sd.tstop, sd.dist, sd.geom, sd.edges);
n += 1;
}
LOG.debug("Linked stop {} to {} nearby stops on other patterns.", ts0.getStop(), n);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ public static class StopAtDistance implements Comparable<StopAtDistance> {
public TransitStop tstop;
public double dist;
public LineString geom;
public List<Edge> edges;

public StopAtDistance(TransitStop tstop, double dist) {
this.tstop = tstop;
Expand Down Expand Up @@ -203,6 +204,7 @@ public static StopAtDistance stopAtDistanceForState (State state) {
double distance = 0.0;
GraphPath graphPath = new GraphPath(state, false);
CoordinateArrayListSequence coordinates = new CoordinateArrayListSequence();
List<Edge> edges = new ArrayList<>();
for (Edge edge : graphPath.edges) {
if (edge instanceof StreetEdge) {
LineString geometry = edge.getGeometry();
Expand All @@ -215,6 +217,7 @@ public static StopAtDistance stopAtDistanceForState (State state) {
}
distance += edge.getDistance();
}
edges.add(edge);
}
if (coordinates.size() < 2) { // Otherwise the walk step generator breaks.
ArrayList<Coordinate> coordinateList = new ArrayList<Coordinate>(2);
Expand All @@ -225,6 +228,7 @@ public static StopAtDistance stopAtDistanceForState (State state) {
}
StopAtDistance sd = new StopAtDistance((TransitStop) state.getVertex(), distance);
sd.geom = geometryFactory.createLineString(new PackedCoordinateSequence.Double(coordinates.toCoordinateArray()));
sd.edges = edges;
return sd;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public class PruneFloatingIslands implements GraphBuilderModule {
* this field indicate the maximum size for island without stops
* island under this size will be pruned.
*/
private int islandWithoutStopsMaxSize = 40;
private int pruningThresholdIslandWithoutStops;

/**
* this field indicate the maximum size for island with stops
* island under this size will be pruned.
*/
private int islandWithStopsMaxSize = 5;
private int pruningThresholdIslandWithStops;

/**
* The name for output file for this process. The file will store information about the islands
Expand Down Expand Up @@ -72,8 +72,8 @@ public List<String> getPrerequisites() {
public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) {
LOG.info("Pruning isolated islands in street network");

StreetUtils.pruneFloatingIslands(graph, islandWithoutStopsMaxSize,
islandWithStopsMaxSize, islandLogFile);
StreetUtils.pruneFloatingIslands(graph, pruningThresholdIslandWithoutStops,
pruningThresholdIslandWithStops, islandLogFile);
if (transitToStreetNetwork == null) {
LOG.debug("TransitToStreetNetworkGraphBuilder was not provided to PruneFloatingIslands. Not attempting to reconnect stops.");
} else {
Expand All @@ -87,5 +87,11 @@ public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) {
public void checkInputs() {
//no inputs
}
public void setPruningThresholdIslandWithoutStops(int pruningThresholdIslandWithoutStops) {
this.pruningThresholdIslandWithoutStops = pruningThresholdIslandWithoutStops;
}
public void setPruningThresholdIslandWithStops(int pruningThresholdIslandWithStops) {
this.pruningThresholdIslandWithStops = pruningThresholdIslandWithStops;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ private void createSegments(OSMNode fromNode, OSMNode toNode, IntersectionVertex
}

if (areaEntity.isTagFalse("wheelchair")) {
street.setWheelchairAccessible(false);
backStreet.setWheelchairAccessible(false);
}

backStreet.setStreetClass(cls);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public StreetSegment (State state) {
}
//TODO: localize
try {
Itinerary itin = GraphPathToTripPlanConverter.generateItinerary(path, false, new Locale("en"));
Itinerary itin = GraphPathToTripPlanConverter.generateItinerary(path, false, true, new Locale("en"));
for (Leg leg : itin.legs) {
// populate the streetEdges array
for (WalkStep walkStep : leg.walkSteps) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ public class RoutingRequest implements Cloneable, Serializable {
/** Accept only paths that use transit (no street-only paths). */
public boolean onlyTransitTrips = false;

/** Option to disable the default filtering of GTFS-RT alerts by time. */
public boolean disableAlertFiltering = false;

/** Saves split edge which can be split on origin/destination search
*
* This is used so that TrivialPathException is thrown if origin and destination search would split the same edge
Expand Down Expand Up @@ -953,7 +956,8 @@ public boolean equals(Object o) {
&& ignoreRealtimeUpdates == other.ignoreRealtimeUpdates
&& disableRemainingWeightHeuristic == other.disableRemainingWeightHeuristic
&& Objects.equal(startingTransitTripId, other.startingTransitTripId)
&& useTraffic == other.useTraffic;
&& useTraffic == other.useTraffic
&& disableAlertFiltering == other.disableAlertFiltering;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ the License, or (at your option) any later version.
import org.opentripplanner.routing.vertextype.TransitStop;

import com.vividsolutions.jts.geom.LineString;

import java.util.List;
import java.util.Locale;

/**
Expand All @@ -34,11 +36,17 @@ public class SimpleTransfer extends Edge {
private double distance;

private LineString geometry;
private List<Edge> edges;

public SimpleTransfer(TransitStop from, TransitStop to, double distance, LineString geometry) {
public SimpleTransfer(TransitStop from, TransitStop to, double distance, LineString geometry, List<Edge> edges) {
super(from, to);
this.distance = distance;
this.geometry = geometry;
this.edges = edges;
}

public SimpleTransfer(TransitStop from, TransitStop to, double distance, LineString geometry) {
this(from, to, distance, geometry, null);
}

@Override
Expand Down Expand Up @@ -89,11 +97,13 @@ public double getDistance(){
}


@Override
public LineString getGeometry(){
@Override
public LineString getGeometry(){
return this.geometry;
}

public List<Edge> getEdges() { return this.edges; }

@Override
public String toString() {
return "SimpleTransfer " + getName();
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/org/opentripplanner/routing/edgetype/StreetEdge.java
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,10 @@ public P2<StreetEdge> split(SplitterVertex v, boolean destructive) {
e1 = new StreetEdge((StreetVertex) fromv, v, geoms.first, name, 0, permission, this.isBack());
e2 = new StreetEdge(v, (StreetVertex) tov, geoms.second, name, 0, permission, this.isBack());

// copy the wayId to the split edges, so we can trace them back to their parent if need be
e1.wayId = this.wayId;
e2.wayId = this.wayId;

// figure the lengths, ensuring that they sum to the length of this edge
e1.calculateLengthFromGeometry();
e2.calculateLengthFromGeometry();
Expand All @@ -829,6 +833,16 @@ public P2<StreetEdge> split(SplitterVertex v, boolean destructive) {
e1.length_mm = length_mm - e2.length_mm;
}

// TODO: better handle this temporary fix to handle bad edge distance calculation
if (e1.length_mm < 0) {
LOG.error("Edge 1 ({}) split at vertex at {},{} has length {} mm. Setting to 1 mm.", e1.wayId, v.getLat(), v.getLon(), e1.length_mm);
e1.length_mm = 1;
}
if (e2.length_mm < 0) {
LOG.error("Edge 2 ({}) split at vertex at {},{} has length {} mm. Setting to 1 mm.", e2.wayId, v.getLat(), v.getLon(), e2.length_mm);
e2.length_mm = 1;
}

if (e1.length_mm < 0 || e2.length_mm < 0) {
e1.tov.removeIncoming(e1);
e1.fromv.removeOutgoing(e1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ public class GraphBuilderParameters {
* Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle
*/
public int maxInterlineDistance = 200;

/**
* This field indicates the pruning threshold for islands without stops.
* Any such island under this size will be pruned.
*/
public final int pruningThresholdIslandWithoutStops;

/**
* This field indicates the pruning threshold for islands with stops.
* Any such island under this size will be pruned.
*/
public final int pruningThresholdIslandWithStops;

/**
* Set all parameters from the given Jackson JSON tree, applying defaults.
Expand Down Expand Up @@ -144,6 +156,8 @@ public GraphBuilderParameters(JsonNode config) {
staticBikeParkAndRide = config.path("staticBikeParkAndRide").asBoolean(false);
maxHtmlAnnotationsPerFile = config.path("maxHtmlAnnotationsPerFile").asInt(1000);
maxInterlineDistance = config.path("maxInterlineDistance").asInt(200);
pruningThresholdIslandWithoutStops = config.path("islandWithoutStopsMaxSize").asInt(40);
pruningThresholdIslandWithStops = config.path("islandWithStopsMaxSize").asInt(5);
}

}
Loading

0 comments on commit f6656c3

Please sign in to comment.