Skip to content

Commit

Permalink
refactor: cleanup class routing profile (#1958)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfendrich authored Jan 27, 2025
2 parents b59881b + b697c17 commit 726b1ac
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,9 @@
*/
package org.heigit.ors.routing;

import com.graphhopper.GHRequest;
import com.graphhopper.config.CHProfile;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.storage.ConditionalEdges;
import com.graphhopper.storage.GraphHopperStorage;
import com.graphhopper.storage.StorableProperties;
import com.graphhopper.util.Parameters;
import org.apache.log4j.Logger;
import org.heigit.ors.config.EngineProperties;
import org.heigit.ors.config.profile.ExecutionProperties;
Expand All @@ -30,7 +25,6 @@
import org.heigit.ors.routing.graphhopper.extensions.storages.builders.BordersGraphStorageBuilder;
import org.heigit.ors.routing.graphhopper.extensions.storages.builders.GraphStorageBuilder;
import org.heigit.ors.routing.pathprocessors.ORSPathProcessorFactory;
import org.heigit.ors.util.ProfileTools;
import org.heigit.ors.util.TimeUtility;

import java.io.File;
Expand Down Expand Up @@ -184,55 +178,6 @@ public Double getAstarEpsilon() {
return astarEpsilon;
}

/**
* Set the speedup techniques used for calculating the route.
* Reults in usage of CH, Core or ALT/AStar, if they are enabled.
*
* @param req Request whose hints will be set
* @param useCH Should CH be enabled
* @param useCore Should Core be enabled
* @param useALT Should ALT be enabled
*/
public void setSpeedups(GHRequest req, boolean useCH, boolean useCore, boolean useALT, String profileNameCH) {
String requestProfileName = req.getProfile();

//Priority: CH->Core->ALT
String profileNameNoTC = requestProfileName.replace("_with_turn_costs", "");

useCH = useCH && mGraphHopper.isCHAvailable(profileNameCH);
useCore = useCore && !useCH && (mGraphHopper.isCoreAvailable(requestProfileName) || mGraphHopper.isCoreAvailable(profileNameNoTC));
useALT = useALT && !useCH && !useCore && mGraphHopper.isLMAvailable(requestProfileName);

req.getHints().putObject(ProfileTools.KEY_CH_DISABLE, !useCH);
req.getHints().putObject(ProfileTools.KEY_CORE_DISABLE, !useCore);
req.getHints().putObject(ProfileTools.KEY_LM_DISABLE, !useALT);

if (useCH) {
req.setAlgorithm(Parameters.Algorithms.DIJKSTRA_BI);
req.setProfile(profileNameCH);
}
if (useCore && !mGraphHopper.isCoreAvailable(requestProfileName) && mGraphHopper.isCoreAvailable(profileNameNoTC))
// fallback to a core profile without turn costs if one is available
req.setProfile(profileNameNoTC);

}

boolean requiresTimeDependentAlgorithm(RouteSearchParameters searchParams, RouteSearchContext searchCntx) {
if (!searchParams.isTimeDependent())
return false;

FlagEncoder flagEncoder = searchCntx.getEncoder();

if (flagEncoder.hasEncodedValue(EncodingManager.getKey(flagEncoder, ConditionalEdges.ACCESS)))
return true;

if (WeightingMethod.SHORTEST == searchParams.getWeightingMethod())
return false;

return flagEncoder.hasEncodedValue(EncodingManager.getKey(flagEncoder, ConditionalEdges.SPEED))
|| mGraphHopper.isTrafficEnabled();
}

public boolean equals(Object o) {
return o != null && o.getClass().equals(RoutingProfile.class) && this.hashCode() == o.hashCode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.gtfs.*;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.storage.ConditionalEdges;
import com.graphhopper.util.*;
import com.graphhopper.util.exceptions.MaximumNodesExceededException;
import com.graphhopper.util.shapes.GHPoint;
Expand Down Expand Up @@ -468,7 +471,7 @@ else if (bearings[1] == null)

if (TemporaryUtilShelter.supportWeightingMethod(profileType)) {
ProfileTools.setWeightingMethod(req.getHints(), weightingMethod, profileType, TemporaryUtilShelter.hasTimeDependentSpeed(searchParams, searchCntx));
if (routingProfile.requiresTimeDependentAlgorithm(searchParams, searchCntx))
if (requiresTimeDependentAlgorithm(searchCntx))
flexibleMode = ProfileTools.KEY_FLEX_PREPROCESSED;
flexibleMode = TemporaryUtilShelter.getFlexibilityMode(flexibleMode, searchParams, profileType);
} else
Expand All @@ -477,15 +480,15 @@ else if (bearings[1] == null)
if (flexibleMode == ProfileTools.KEY_FLEX_STATIC)
//Speedup order: useCH, useCore, useALT
// TODO Future improvement: profileNameCH is an ugly hack and is required because of the hard-coded turnCost=false for CH
routingProfile.setSpeedups(req, true, true, true, searchCntx.profileNameCH());
setSpeedups(req, true, true, true, searchCntx.profileNameCH());

if (flexibleMode == ProfileTools.KEY_FLEX_PREPROCESSED) {
routingProfile.setSpeedups(req, false, optimized, true, searchCntx.profileNameCH());
setSpeedups(req, false, optimized, true, searchCntx.profileNameCH());
}

//cannot use CH or CoreALT with requests where the weighting of non-predefined edges might change
if (flexibleMode == ProfileTools.KEY_FLEX_FULLY)
routingProfile.setSpeedups(req, false, false, true, searchCntx.profileNameCH());
setSpeedups(req, false, false, true, searchCntx.profileNameCH());

if (searchParams.isTimeDependent()) {
String key;
Expand All @@ -501,7 +504,7 @@ else if (bearings[1] == null)
Instant time = dateTime.atZone(ZoneId.of("Europe/Berlin")).toInstant();
req.getHints().putObject(key, time);

if (routingProfile.requiresTimeDependentAlgorithm(searchParams, searchCntx)) {
if (requiresTimeDependentAlgorithm(searchCntx)) {
req.getHints().putObject("time", time.toEpochMilli());
req.setAlgorithm(Parameters.Algorithms.TD_ASTAR);
}
Expand Down Expand Up @@ -585,7 +588,7 @@ private GHResponse computeRoundTripRoute(double lat0, double lon0, WayPointBeari
throw new IllegalArgumentException("Unsupported weighting " + weightingMethod + " for profile + " + profileType);

//Roundtrip not possible with preprocessed edges.
routingProfile.setSpeedups(req, false, false, true, searchCntx.profileNameCH());
setSpeedups(req, false, false, true, searchCntx.profileNameCH());

if (routingProfile.getAstarEpsilon() != null)
req.getHints().putObject("astarbi.epsilon", routingProfile.getAstarEpsilon());
Expand Down Expand Up @@ -882,4 +885,58 @@ private RouteResult[] computeLinearRoute() throws Exception {
}
return new RouteResultBuilder().createRouteResults(routes, this, extraInfos);
}

boolean requiresTimeDependentAlgorithm(RouteSearchContext searchCntx) {
RouteSearchParameters searchParams = getSearchParameters();

if (!searchParams.isTimeDependent())
return false;

FlagEncoder flagEncoder = searchCntx.getEncoder();

if (flagEncoder.hasEncodedValue(EncodingManager.getKey(flagEncoder, ConditionalEdges.ACCESS)))
return true;

if (WeightingMethod.SHORTEST == searchParams.getWeightingMethod())
return false;

return flagEncoder.hasEncodedValue(EncodingManager.getKey(flagEncoder, ConditionalEdges.SPEED))
|| profile().getGraphhopper().isTrafficEnabled();
}

/**
* Set the speedup techniques used for calculating the route.
* Reults in usage of CH, Core or ALT/AStar, if they are enabled.
*
* @param req Request whose hints will be set
* @param useCH Should CH be enabled
* @param useCore Should Core be enabled
* @param useALT Should ALT be enabled
* @param profileNameCH
*/
public void setSpeedups(GHRequest req, boolean useCH, boolean useCore, boolean useALT, String profileNameCH) {
String requestProfileName = req.getProfile();

//Priority: CH->Core->ALT
String profileNameNoTC = requestProfileName.replace("_with_turn_costs", "");

ORSGraphHopper gh = profile().getGraphhopper();

useCH = useCH && gh.isCHAvailable(profileNameCH);
useCore = useCore && !useCH && (gh.isCoreAvailable(requestProfileName) || gh.isCoreAvailable(profileNameNoTC));
useALT = useALT && !useCH && !useCore && gh.isLMAvailable(requestProfileName);

req.getHints().putObject(ProfileTools.KEY_CH_DISABLE, !useCH);
req.getHints().putObject(ProfileTools.KEY_CORE_DISABLE, !useCore);
req.getHints().putObject(ProfileTools.KEY_LM_DISABLE, !useALT);

if (useCH) {
req.setAlgorithm(Parameters.Algorithms.DIJKSTRA_BI);
req.setProfile(profileNameCH);
}
if (useCore && !gh.isCoreAvailable(requestProfileName) && gh.isCoreAvailable(profileNameNoTC))
// fallback to a core profile without turn costs if one is available
req.setProfile(profileNameNoTC);

}
}
4 changes: 2 additions & 2 deletions ors-test-scenarios/src/test/resources/Builder.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ARG CONTAINER_WORK_DIR=/home/ors/openrouteservice

FROM docker.io/maven:3.9.9-amazoncorretto-21-alpine AS ors-test-scenarios-builder

RUN apk add --no-cache bash=5.2.26-r0 yq=4.44.1-r2 zip=3.0-r12 && \
RUN apk add --no-cache bash~=5 yq~=4 zip~=3 && \
rm -rf /var/cache/apk/*

ARG CONTAINER_BUILD_DIR
Expand Down Expand Up @@ -101,7 +101,7 @@ ENV JAVA_OPTS="-Xmx350M"

FROM docker.io/amazoncorretto:21.0.4-alpine3.20 AS ors-test-scenarios-jar-builder
# Build: docker build --target ors-test-scenarios-jar-bare --tag ors-test-scenarios-jar-bare:latest -f ors-test-scenarios/src/test/resources/Dockerfile .
RUN apk add --no-cache bash=5.2.26-r0 yq=4.44.1-r2 zip=3.0-r12
RUN apk add --no-cache bash~=5 yq~=4 zip~=3

ARG CONTAINER_WORK_DIR
ARG CONTAINER_BUILD_DIR
Expand Down

0 comments on commit 726b1ac

Please sign in to comment.