Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature#480 maximum speed #740

Merged
merged 47 commits into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1b035b2
Integrating maximum_speed-weighting in development branch.
star-pirate Dec 24, 2019
c57f0b9
Continuing integration.
star-pirate Dec 24, 2019
84d6857
Added TODO list in files.
star-pirate Dec 24, 2019
97586f8
Working implementation of the MaximumSpeddCoreEdgeFilter and the Maxi…
star-pirate Jan 7, 2020
0ed73c5
Changes in RoutingProfile.
star-pirate Jan 7, 2020
9a9460f
Add max_speed in the app.config file under routing.profiles.default_p…
star-pirate Jan 7, 2020
7750fde
Changes in package names and comment additions.
star-pirate Jan 27, 2020
8d5b356
Added correct paths for MaximumSpeedCoreEdgeFilter and MaximumSpeedWe…
star-pirate Jan 27, 2020
e8661fc
Changes in .gitignore
star-pirate Feb 12, 2020
0890622
Commit for merge.
star-pirate Apr 2, 2020
9919410
Megre with development.
star-pirate Apr 2, 2020
2a242e3
Commit for testing purposes.
star-pirate Apr 2, 2020
d97e261
Changes in MaximumSpeedWeighting.
star-pirate Apr 7, 2020
1b1afbb
Merge with master.
star-pirate Apr 8, 2020
276b4f3
Minor changes.
star-pirate Apr 13, 2020
2187468
Fixed minor problems.
star-pirate Apr 13, 2020
b7d4608
Fully working MaximumSpeedWeighting.
star-pirate Apr 17, 2020
7d45c4f
Working MaximumSpeedWeighting plus a corresponding filter.
star-pirate Apr 20, 2020
398b467
Passed the tests performed using R.
star-pirate Apr 29, 2020
bbba0a0
Change app.config max_speed to maximum_speed.
star-pirate May 6, 2020
483caac
Minor fixes.
star-pirate May 6, 2020
f6e8596
Merge branch 'master' into maximum_speed_feature_development
star-pirate May 6, 2020
1a1635b
Fixed some errors.
star-pirate May 11, 2020
4f57113
Merge with master.
star-pirate May 11, 2020
683992b
Removed test variables.
star-pirate May 20, 2020
1e58369
Merge with master.
star-pirate May 20, 2020
50a8ca3
Revert changes in pom.xml.
star-pirate May 20, 2020
d24f98d
Remove app.config.
star-pirate May 20, 2020
bb6fb48
Require dynamic preprocessed algorithm when speed limit is provided
aoles May 21, 2020
eecd1e0
Cleanup and refactoring
aoles May 29, 2020
fbf1e2e
Merge with master before pull request.
star-pirate Jun 3, 2020
0f198da
Reviews.
star-pirate Jun 3, 2020
4308af5
More reviews.
star-pirate Jun 4, 2020
5d55972
More reviews.
star-pirate Jun 4, 2020
2923f36
Even more reviews.
star-pirate Jun 5, 2020
803ebfe
Revert pom.xml back to master form.
star-pirate Jun 5, 2020
e996df7
Fixed API test and some obsolete user_speed.
star-pirate Jun 5, 2020
f1e9dbb
Add tests checking the requirements of maximum speed feature
aoles Jun 6, 2020
977c6a3
Fixed ReultsTest.testMaximumSpeed(), moved maximum_speed_lower_bound …
star-pirate Jun 17, 2020
f25fdac
Fixed mistake in ResultsTest.
star-pirate Jun 17, 2020
11f2865
Fix broken API tests
aoles Jun 20, 2020
4d005e8
Fix MaximumSpeedWeighting and refactor API tests
aoles Jun 21, 2020
10a2b7e
Merge branch 'master' into feature#480-maximum_speed
takb Jun 22, 2020
efc0fbc
Merge branch 'master' into feature#480-maximum_speed
takb Jun 22, 2020
b97490c
Add CUSTOM_KEYS metadata to ApiModelProperty annotation
aoles Jun 22, 2020
1406052
Minor tweak to CUSTOM_KEYS metadata
aoles Jun 22, 2020
b96a110
Merge branch 'master' into feature#480-maximum_speed
takb Jun 23, 2020
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)

## [Unreleased]
### Added
* New `maximum_speed` parameter to the driving profiles of the directions API, for specifying a speed limit, above a certain threshold set in the config file.

### Fixed
### Changed
### Deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,28 @@ public void testOptimizedAndTurnRestrictions() {
.statusCode(200);
}

@Test
public void testMaximumSpeed() {
JSONObject body = new JSONObject();
body.put("coordinates", constructCoords("8.63348,49.41766|8.6441,49.4672"));
body.put("preference", getParameter("preference"));
body.put("maximum_speed",80);

//Test that the distance of the computed route.
aoles marked this conversation as resolved.
Show resolved Hide resolved
given()
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.pathParam("profile", "driving-car")
.body(body.toString())
.when()
.post(getEndPointPath() + "/{profile}")
.then()
.assertThat()
.body("any { it.key == 'routes' }", is(true))
.body("routes[0].summary.duration", is(1694.8f))
.statusCode(200);
}

@Test
public void testNoBearings() {
JSONObject body = new JSONObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class RouteRequest {
public static final String PARAM_SIMPLIFY_GEOMETRY = "geometry_simplify";
public static final String PARAM_SKIP_SEGMENTS = "skip_segments";
public static final String PARAM_ALTERNATIVE_ROUTES = "alternative_routes";
public static final String PARAM_MAXIMUM_SPEED = "maximum_speed";


@ApiModelProperty(name = PARAM_ID, value = "Arbitrary identification string of the request reflected in the meta information.",
example = "routing_request")
Expand Down Expand Up @@ -245,6 +247,11 @@ public class RouteRequest {
@JsonIgnore
private boolean hasAlternativeRoutes = false;

@ApiModelProperty(name = PARAM_MAXIMUM_SPEED, value = "The maximum speed specified by user.", example = "90")
@JsonProperty(PARAM_MAXIMUM_SPEED)
private double maximumSpeed;
@JsonIgnore
private boolean hasMaximumSpeed = false;

@JsonCreator
public RouteRequest(@JsonProperty(value = PARAM_COORDINATES, required = true) List<List<Double>> coordinates) {
Expand Down Expand Up @@ -504,6 +511,15 @@ public void setAlternativeRoutes(RouteRequestAlternativeRoutes alternativeRoutes
hasAlternativeRoutes = true;
}

public void setMaximumSpeed(Double maximumSpeed) {
this.maximumSpeed = maximumSpeed;
hasMaximumSpeed = true;
}

public double getMaximumSpeed() {
return maximumSpeed;
}

public boolean hasIncludeRoundaboutExitInfo() {
return hasIncludeRoundaboutExitInfo;
}
Expand Down Expand Up @@ -575,4 +591,8 @@ public boolean hasSimplifyGeometry() {
public boolean hasSkipSegments() { return hasSkipSegments;}

public boolean hasAlternativeRoutes() { return hasAlternativeRoutes; }

public boolean hasMaximumSpeed() {
return hasMaximumSpeed;
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public class RouteSearchParameters {
private int roundTripPoints = 2;
private long roundTripSeed = -1;

private double maximumSpeed;
private boolean hasMaximumSpeed = false;

private String options;

public int getProfileType() {
Expand Down Expand Up @@ -527,6 +530,19 @@ public long getRoundTripSeed() {
return roundTripSeed;
}

public double getMaximumSpeed() {
return maximumSpeed;
}

public void setMaximumSpeed(double maximumSpeed) {
this.maximumSpeed = maximumSpeed;
hasMaximumSpeed = true;
}

public boolean hasMaximumSpeed() {
return hasMaximumSpeed;
}

public boolean isProfileTypeDriving() {
return RoutingProfileType.isDriving(this.getProfileType());
}
Expand All @@ -543,7 +559,7 @@ public boolean requiresDynamicPreprocessedWeights() {
|| getConsiderTurnRestrictions()
|| isProfileTypeHeavyVehicle() && getVehicleType() > 0
|| isProfileTypeDriving() && hasParameters(VehicleParameters.class)
;
|| hasMaximumSpeed();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,10 @@ else if (bearings[1] == null)
req.getHints().put("alternative_route.max_share_factor", searchParams.getAlternativeRoutesShareFactor());
}

if(searchParams.hasMaximumSpeed()){
req.getHints().put("maximum_speed", searchParams.getMaximumSpeed());
}

if (directedSegment) {
resp = mGraphHopper.constructFreeHandRoute(req);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,10 @@ public RoutingProfile getRouteProfile(RoutingRequest req, boolean oneToMany) thr
}
}

if(searchParams.getMaximumSpeed() !=0 & searchParams.getMaximumSpeed() < config.getMaximumSpeedLowerBound()){
star-pirate marked this conversation as resolved.
Show resolved Hide resolved
throw new RuntimeException("The maximum speed must not be lower than " + config.getMaximumSpeedLowerBound() + " km/h.");
star-pirate marked this conversation as resolved.
Show resolved Hide resolved
}

return rp;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class RoutingRequest extends ServiceRequest {
private boolean continueStraight = false;
private List<Integer> skipSegments = new ArrayList<>();
private boolean includeCountryInfo = false;
private double maximumSpeed;

private String responseFormat = "json";

Expand Down Expand Up @@ -207,10 +208,18 @@ public boolean getIncludeCountryInfo() {
return includeCountryInfo;
}

public void setIncludeCountryInfo(boolean includeCountryInfo) {
public void setIncludeCountryInfo(boolean includeCountryImnfo) {
star-pirate marked this conversation as resolved.
Show resolved Hide resolved
this.includeCountryInfo = includeCountryInfo;
}

public void setMaximumSpeed(double maximumSpeed){
this.maximumSpeed = maximumSpeed;
}

public double getMaximumSpeed(){
return maximumSpeed;
}

public void setResponseFormat(String responseFormat) {
if (!Helper.isEmpty(responseFormat)) {
this.responseFormat = responseFormat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public class RouteProfileConfiguration {
private int locationIndexResolution = 500;
private int locationIndexSearchIterations = 4;

private double maximumSpeedLowerBound = 80;

public RouteProfileConfiguration() {
extStorages = new HashMap<>();
graphBuilders = new HashMap<>();
Expand Down Expand Up @@ -356,4 +358,12 @@ public int getLocationIndexSearchIterations() {
public void setLocationIndexSearchIterations(int locationIndexSearchIterations) {
this.locationIndexSearchIterations = locationIndexSearchIterations;
}

public void setMaximumSpeedLowerBound(double maximumSpeedLowerBound){
this.maximumSpeedLowerBound = maximumSpeedLowerBound;
}

public double getMaximumSpeedLowerBound(){
return maximumSpeedLowerBound;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class GraphProcessContext {
private GraphBuilder[] arrGraphBuilders;
private List<GraphStorageBuilder> storageBuilders;
private GraphStorageBuilder[] arrStorageBuilders;
private double maximumSpeedLowerBound;

public GraphProcessContext(RouteProfileConfiguration config) throws Exception {
bbox = config.getExtent();
Expand All @@ -59,6 +60,8 @@ public GraphProcessContext(RouteProfileConfiguration config) throws Exception {
arrGraphBuilders = graphBuilders.toArray(arrGraphBuilders);
}
}

maximumSpeedLowerBound = config.getMaximumSpeedLowerBound();
}

public void init(GraphHopper gh) {
Expand Down Expand Up @@ -208,4 +211,8 @@ public void finish() {
}
}
}

public double getMaximumSpeedLowerBound(){
return maximumSpeedLowerBound;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.AvoidFeaturesCoreEdgeFilter;
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.HeavyVehicleCoreEdgeFilter;
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.WheelchairCoreEdgeFilter;
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.MaximumSpeedCoreEdgeFilter;
import org.heigit.ors.routing.graphhopper.extensions.weighting.MaximumSpeedWeighting;
import org.heigit.ors.routing.graphhopper.extensions.util.ORSParameters;
import org.heigit.ors.util.CoordTools;
import org.slf4j.Logger;
Expand Down Expand Up @@ -76,6 +78,8 @@ public class ORSGraphHopper extends GraphHopper {

private final CoreLMAlgoFactoryDecorator coreLMFactoryDecorator = new CoreLMAlgoFactoryDecorator();

private double maximumSpeedLowerBound;

public ORSGraphHopper(GraphProcessContext procCntx) {
processContext = procCntx;
forDesktop();
Expand All @@ -85,6 +89,8 @@ public ORSGraphHopper(GraphProcessContext procCntx) {
algoDecorators.add(getCHFactoryDecorator());
algoDecorators.add(getLMFactoryDecorator());
processContext.init(this);
maximumSpeedLowerBound = procCntx.getMaximumSpeedLowerBound();

}


Expand All @@ -97,6 +103,7 @@ public GraphHopper init(CmdArgs args) {
GraphHopper ret = super.init(args);
minNetworkSize = args.getInt("prepare.min_network_size", minNetworkSize);
minOneWayNetworkSize = args.getInt("prepare.min_one_way_network_size", minOneWayNetworkSize);

return ret;
}

Expand Down Expand Up @@ -323,10 +330,17 @@ else if (ALT_ROUTE.equalsIgnoreCase(algoStr))
throw new IllegalArgumentException(
"The max_visited_nodes parameter has to be below or equal to:" + getMaxVisitedNodes());


if(hints.has("maximum_speed")) {
weighting = new MaximumSpeedWeighting(encoder, hints, weighting, maximumSpeedLowerBound);
}


int uTurnCosts = hints.getInt(Parameters.Routing.U_TURN_COSTS, INFINITE_U_TURN_COSTS);
weighting = createTurnWeighting(queryGraph, weighting, tMode, uTurnCosts);
if (weighting instanceof TurnWeighting)
((TurnWeighting)weighting).setInORS(true);

AlgorithmOptions algoOpts = AlgorithmOptions.start().algorithm(algoStr).traversalMode(tMode)
.weighting(weighting).maxVisitedNodes(maxVisitedNodesForRequest).hints(hints).build();

Expand Down Expand Up @@ -523,6 +537,17 @@ public void postProcessing() {
coreEdgeFilter.add(new WheelchairCoreEdgeFilter(gs));
}

/* Maximum Speed Filter */
star-pirate marked this conversation as resolved.
Show resolved Hide resolved
if ((routingProfileCategory & RoutingProfileCategory.DRIVING) !=0 ) {
FlagEncoder flagEncoder = null;
if(encodingManager.hasEncoder("heavyvehicle"))
flagEncoder = getEncodingManager().getEncoder("heavyvehicle");
else if(encodingManager.hasEncoder("car-ors"))
flagEncoder = getEncodingManager().getEncoder("car-ors");

coreEdgeFilter.add(new MaximumSpeedCoreEdgeFilter(flagEncoder, maximumSpeedLowerBound));
}

/* End filter sequence initialization */

//Create the core
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
import com.graphhopper.routing.util.HintsMap;
import com.graphhopper.routing.util.TraversalMode;
import com.graphhopper.routing.weighting.*;
import com.graphhopper.storage.Graph;
import com.graphhopper.storage.GraphHopperStorage;
import com.graphhopper.storage.TurnCostExtension;
import com.graphhopper.storage.index.LocationIndex;
import com.graphhopper.util.Helper;
import com.graphhopper.util.PMap;
import com.graphhopper.util.Parameters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,11 +509,11 @@ public RoutingAlgorithm createAlgo(Graph graph, AlgorithmOptions opts) {
String algoStr = ASTAR_BI;

if (ASTAR_BI.equals(algoStr)) {
CoreALT tmpAlgo = new CoreALT(graph, prepareWeighting, traversalMode);
CoreALT tmpAlgo = new CoreALT(graph,new PreparationWeighting(opts.getWeighting()), traversalMode);
sfendrich marked this conversation as resolved.
Show resolved Hide resolved
tmpAlgo.setApproximation(RoutingAlgorithmFactorySimple.getApproximation(ASTAR_BI, opts, graph.getNodeAccess()));
algo = tmpAlgo;
} else if (DIJKSTRA_BI.equals(algoStr)) {
algo = new CoreDijkstra(graph, prepareWeighting, traversalMode);
algo = new CoreDijkstra(graph, new PreparationWeighting(opts.getWeighting()), traversalMode);
sfendrich marked this conversation as resolved.
Show resolved Hide resolved
} else {
throw new IllegalArgumentException("Algorithm " + opts.getAlgorithm()
+ " not supported for Contraction Hierarchies. Try with ch.disable=true");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* This file is part of Openrouteservice.
*
* Openrouteservice 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 2.1
* of the License, or (at your option) any later version.

* This library 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 Lesser General Public License for more details.

* You should have received a copy of the GNU Lesser General Public License along with this library;
* if not, see <https://www.gnu.org/licenses/>.
*/
package org.heigit.ors.routing.graphhopper.extensions.edgefilters.core;

import com.graphhopper.routing.profiles.DecimalEncodedValue;
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.util.EdgeIteratorState;
import com.graphhopper.routing.util.FlagEncoder;
import org.heigit.ors.config.AppConfig;

/**
* This class includes in the core all edges with speed more than the one set in the app.config file max_speed.
*
* @author Athanasios Kogios
*/

public class MaximumSpeedCoreEdgeFilter implements EdgeFilter {
private double maximumSpeedLowerBound;
private double maxSpeed = ((AppConfig.getGlobal().getServiceParameter("routing.profiles.default_params","maximum_speed_lower_bound")) != null)
Copy link
Member

@aoles aoles Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handling of maximum_speed_lower_bound value from the config file still needs some refactoring. Currently there are 3 different places over the code where this value is parsed and if missing the hard-coded value of 80 is used. The default value, even if hard-coded, should appear only once in the whole codebase.

I suggest to use RouteProfileConfiguration class to store the value of maximumSpeedLowerBound. Have a look at the implementation of the maximum_distance parameter, it will be probably quite similar.

This change might require, for example, that maxSpeed value is resolved upstream in ORSGraphHopper from CmdArgs set in RoutingProfile, and passed to MaximumSpeedCoreEdgeFilter as a constructor argument.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: please use GraphProcessContext rather than CmdArgs for passing the maximum_speed_lower_bound.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The introduction of maximumSpeedLowerBound has made maxSpeed redundant, so please remove the latter.

? Double.parseDouble(AppConfig.getGlobal().getServiceParameter("routing.profiles.default_params","maximum_speed_lower_bound"))
: maximumSpeedLowerBound; //If there is a maximum_speed value in the app.config we use that. If not we set a default of 80.

private final DecimalEncodedValue avSpeedEnc;

public MaximumSpeedCoreEdgeFilter(FlagEncoder flagEncoder, double maximumSpeedLowerBound) {
this.maximumSpeedLowerBound = maximumSpeedLowerBound;
this.avSpeedEnc = flagEncoder.getAverageSpeedEnc();
}

@Override
public boolean accept(EdgeIteratorState edge) {
if ( (edge.get(avSpeedEnc) > maxSpeed) || (edge.getReverse(avSpeedEnc)) > maxSpeed ) {
star-pirate marked this conversation as resolved.
Show resolved Hide resolved
//If the max speed of the road is greater than that of the limit include it in the core.
return false;
} else {
return true;
}
}
}

Loading