Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- Fix for traveling back in time when optimize transfers [#3491](https://github.com/opentripplanner/OpenTripPlanner/pull/3491)
- Transit reluctance per transit mode [#3440](https://github.com/opentripplanner/OpenTripPlanner/issues/3440)
- Allow the removal of P+R results consisting only of driving of walking [#3515](https://github.com/opentripplanner/OpenTripPlanner/pull/3515)
- Add reluctance to "walk" over certain surfaces (for wheelchairs) [#3524](https://github.com/opentripplanner/OpenTripPlanner/issues/3524)

## 2.0.0 (2020-11-27)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ public abstract class RoutingResource {
@QueryParam("waitAtBeginningFactor")
protected Double waitAtBeginningFactor;

/**
* How should different road/surface types be preferred? Each "surfaceReluctance" would be a
* comma-separated pair, of "surface_key" * (as detailed at
* https://wiki.openstreetmap.org/wiki/Key:surface) and the reluctance factor (>1). Each
* "surfaceReluctance" pair should be separated by a semi-colon (;).
*/
@QueryParam("surfaceReluctances")
protected String surfaceReluctances;

/** The user's walking speed in meters/second. Defaults to approximately 3 MPH. */
@QueryParam("walkSpeed")
protected Double walkSpeed;
Expand Down Expand Up @@ -700,6 +709,9 @@ protected RoutingRequest buildRequest() throws ParameterException {
if (waitAtBeginningFactor != null)
request.setWaitAtBeginningFactor(waitAtBeginningFactor);

if (surfaceReluctances != null)
request.setSurfaceReluctances(surfaceReluctances);

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.opentripplanner.api.resource;

import javax.ws.rs.WebApplicationException;
import org.glassfish.grizzly.http.server.Request;
import org.opentripplanner.api.common.Message;
import org.opentripplanner.api.common.ParameterException;
import org.opentripplanner.api.common.RoutingResource;
import org.opentripplanner.api.mapping.PlannerErrorMapper;
import org.opentripplanner.api.mapping.TripPlanMapper;
Expand Down Expand Up @@ -92,6 +94,12 @@ public TripPlannerResponse plan(@Context UriInfo uriInfo, @Context Request grizz

response.debugOutput = res.getDebugAggregator().finishedRendering();
}
catch (ParameterException ex) {
// probably shouldn't log it, since it is a user/parameter error, just report it back
PlannerError error = new PlannerError();
error.setMsg(ex.message);
response.setError(error);
}
catch (Exception e) {
LOG.error("System error", e);
PlannerError error = new PlannerError();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.Iterables;
import gnu.trove.iterator.TLongIterator;
import gnu.trove.list.TLongList;
import java.util.Optional;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
Expand Down Expand Up @@ -1174,6 +1175,7 @@ private StreetEdge getEdgeForStreet(OsmVertex startEndpoint, OsmVertex endEndpoi
street.setHasBogusName(true);
}
street.setStairs(steps);
Optional.ofNullable(way.getSurface()).ifPresent(street::setSurface);

/* TODO: This should probably generalized somehow? */
if (!ignoreWheelchairAccessibility
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
import gnu.trove.list.TLongList;
import gnu.trove.list.array.TLongArrayList;

import java.util.ArrayList;
import java.util.List;

public class OSMWay extends OSMWithTags {

private TLongList nodes = new TLongArrayList();
Expand Down Expand Up @@ -128,4 +125,15 @@ public boolean isOpposableCycleway() {
|| (cyclewayLeft != null && cyclewayLeft.startsWith("opposite"))
|| (cyclewayRight != null && cyclewayRight.startsWith("opposite"));
}

/**
* The possible surface values' documentation can be <a
* href="https://wiki.openstreetmap.org/wiki/Key:surface">seen here</a>. And an enumeration of
* all existing values <a href="https://taginfo.openstreetmap.org/keys/surface#values">can be
* found here</a>.
* @return The value of the {@code surface} tag of this way.
*/
public String getSurface() {
return getTag("surface");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public static RaptorRequest<TripSchedule> mapRequest(
}

builder.mcCostFactors()
.surfaceReluctanceFactors(request.surfaceReluctances)
.waitReluctanceFactor(request.waitReluctance);

if(request.modes.accessMode == StreetMode.WALK) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.opentripplanner.routing.api.request;

import gnu.trove.map.TObjectDoubleMap;
import gnu.trove.map.hash.TObjectDoubleHashMap;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
Expand Down Expand Up @@ -427,6 +429,8 @@ public class RoutingRequest implements AutoCloseable, Cloneable, Serializable {
@Deprecated
public double waitAtBeginningFactor = 0.4;

public TObjectDoubleMap<String> surfaceReluctances = new TObjectDoubleHashMap<>(0);

/**
* This prevents unnecessary transfers by adding a cost for boarding a vehicle. This is in
* addition to the cost of the transfer(walking) and waiting-time. It is also in addition to
Expand Down Expand Up @@ -1328,6 +1332,30 @@ public void setWaitAtBeginningFactor(double waitAtBeginningFactor) {
}
}

public void setSurfaceReluctances(String surfaceReluctances) throws ParameterException {
if (surfaceReluctances == null) {
return;
}
String[] reluctanceSegments = surfaceReluctances.split(";");
this.surfaceReluctances = new TObjectDoubleHashMap<>(reluctanceSegments.length);
for (String reluctanceWithSurface : reluctanceSegments) {
String[] surfaceAndReluctance = reluctanceWithSurface.split(",");
if (surfaceAndReluctance.length != 2) {
throw new ParameterException(Message.BOGUS_PARAMETER);
}
String surface = surfaceAndReluctance[0];
try {
double reluctance = Double.parseDouble(surfaceAndReluctance[1]);
if (reluctance < 1) {
throw new ParameterException(Message.BOGUS_PARAMETER);
}
this.surfaceReluctances.put(surface, reluctance);
} catch (NumberFormatException ex) {
throw new ParameterException(Message.BOGUS_PARAMETER);
}
}
}

public Set<FeedScopedId> getBannedRoutes(Collection<Route> routes) {
Set<FeedScopedId> bannedRoutes = new HashSet<>();
for (Route route : routes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ public class StreetEdge extends Edge implements Cloneable, CarPickupableEdge {
/** The angle at the start of the edge geometry. Internal representation like that of inAngle. */
private byte outAngle;

private String surface;

public StreetEdge(StreetVertex v1, StreetVertex v2, LineString geometry,
I18NString name, double length,
StreetTraversalPermission permission, boolean back) {
Expand Down Expand Up @@ -381,6 +383,13 @@ private StateEditor doTraverse(State s0, RoutingRequest options, TraverseMode tr
// TODO: this is being applied even when biking or driving.
weight *= options.walkReluctance;
}
for (String surfaceToCheck : options.surfaceReluctances.keys(new String[0])) {
if (surfaceToCheck.equals(this.surface)) {
weight *= options.surfaceReluctances.get(surfaceToCheck);
// only up to one surface can match
break;
}
}

StateEditor s1 = s0.edit(this);
s1.setBackMode(traverseMode);
Expand Down Expand Up @@ -736,6 +745,14 @@ public void setSlopeOverride(boolean slopeOverride) {
flags = BitSetUtils.set(flags, SLOPEOVERRIDE_FLAG_INDEX, slopeOverride);
}

public String getSurface() {
return surface;
}

public void setSurface(String surface) {
this.surface = surface;
}

/**
* Return the azimuth of the first segment in this edge in integer degrees clockwise from South.
* TODO change everything to clockwise from North
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.opentripplanner.transit.raptor.api.request;


import gnu.trove.TCollections;
import gnu.trove.map.TObjectDoubleMap;
import gnu.trove.map.hash.TObjectDoubleHashMap;
import javax.annotation.Nullable;
import org.opentripplanner.routing.api.request.RoutingRequest;

Expand All @@ -20,6 +23,7 @@ public class McCostParams {
private final double[] transitReluctanceFactors;
private final double walkReluctanceFactor;
private final double waitReluctanceFactor;
private final TObjectDoubleMap<String> surfaceReluctanceFactors;

/**
* Default constructor defines default values. These defaults are
Expand All @@ -31,6 +35,7 @@ private McCostParams() {
this.transitReluctanceFactors = null;
this.walkReluctanceFactor = 4.0;
this.waitReluctanceFactor = 1.0;
this.surfaceReluctanceFactors = new TObjectDoubleHashMap<>(0);
}

McCostParams(McCostParamsBuilder builder) {
Expand All @@ -39,6 +44,7 @@ private McCostParams() {
this.transitReluctanceFactors = builder.transitReluctanceFactors();
this.walkReluctanceFactor = builder.walkReluctanceFactor();
this.waitReluctanceFactor = builder.waitReluctanceFactor();
this.surfaceReluctanceFactors = TCollections.unmodifiableMap(builder.surfaceReluctanceFactors());
}

public int boardCost() {
Expand Down Expand Up @@ -77,13 +83,18 @@ public double waitReluctanceFactor() {
return waitReluctanceFactor;
}

public TObjectDoubleMap<String> surfaceReluctanceFactors() {
return surfaceReluctanceFactors;
}

@Override
public String toString() {
return "McCostParams{" +
"boardCost=" + boardCost +
", transferCost=" + transferCost +
", transferReluctanceFactor=" + walkReluctanceFactor +
", waitReluctanceFactor=" + waitReluctanceFactor +
", surfaceReluctanceFactors=" + surfaceReluctanceFactors +
'}';
}

Expand All @@ -94,12 +105,13 @@ public boolean equals(Object o) {
McCostParams that = (McCostParams) o;
return boardCost == that.boardCost &&
transferCost == that.transferCost &&
surfaceReluctanceFactors.equals(that.surfaceReluctanceFactors) &&
Double.compare(that.walkReluctanceFactor, walkReluctanceFactor) == 0 &&
Double.compare(that.waitReluctanceFactor, waitReluctanceFactor) == 0;
}

@Override
public int hashCode() {
return Objects.hash(boardCost, transferCost, walkReluctanceFactor, waitReluctanceFactor);
return Objects.hash(boardCost, transferCost, walkReluctanceFactor, waitReluctanceFactor, surfaceReluctanceFactors);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.opentripplanner.transit.raptor.api.request;


import gnu.trove.map.TObjectDoubleMap;

/**
* Mutable version of the {@link McCostParams}.
*/
Expand All @@ -11,6 +13,7 @@ public class McCostParamsBuilder {
private double[] transitReluctanceFactors;
private double walkReluctanceFactor;
private double waitReluctanceFactor;
private TObjectDoubleMap<String> surfaceReluctanceFactors;


McCostParamsBuilder(McCostParams defaults) {
Expand All @@ -19,6 +22,7 @@ public class McCostParamsBuilder {
this.transitReluctanceFactors = defaults.transitReluctanceFactors();
this.walkReluctanceFactor = defaults.walkReluctanceFactor();
this.waitReluctanceFactor = defaults.waitReluctanceFactor();
this.surfaceReluctanceFactors = defaults.surfaceReluctanceFactors();
}

public int boardCost() {
Expand Down Expand Up @@ -65,4 +69,13 @@ public McCostParamsBuilder waitReluctanceFactor(double waitReluctanceFactor) {
this.waitReluctanceFactor = waitReluctanceFactor;
return this;
}

public TObjectDoubleMap<String> surfaceReluctanceFactors() {
return surfaceReluctanceFactors;
}

public McCostParamsBuilder surfaceReluctanceFactors(TObjectDoubleMap<String> surfaceReluctanceFactors) {
this.surfaceReluctanceFactors = surfaceReluctanceFactors;
return this;
}
}
Loading