Skip to content

Commit

Permalink
fix(isochrones): use correct edge filter for snapping (#1568)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelsJP authored Oct 17, 2023
2 parents dd765d8 + 9769eb9 commit 79f3e8c
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 66 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ RELEASING:
- Upgrade org.geotools.gt-epsg-hsql to version 29.1. ([#1479](https://github.com/GIScience/openrouteservice/issues/1479))
- various style and low level code problems ([#1489](https://github.com/GIScience/openrouteservice/pull/1489))
- Fix the max visited nodes bug for fast-isochrones ([#1538](https://github.com/GIScience/openrouteservice/pull/1538))
- fix isochrones snapping ([#1568](https://github.com/GIScience/openrouteservice/pull/1568))

## [7.1.0] - 2023-06-13
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,29 @@

import com.carrotsearch.hppc.IntObjectMap;
import com.graphhopper.GraphHopper;
import com.graphhopper.routing.SPTEntry;
import com.graphhopper.routing.ev.Subnetwork;
import com.graphhopper.routing.querygraph.QueryGraph;
import com.graphhopper.routing.util.DefaultSnapFilter;
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.routing.util.TraversalMode;
import com.graphhopper.routing.weighting.FastestWeighting;
import com.graphhopper.routing.weighting.ShortestWeighting;
import com.graphhopper.routing.weighting.Weighting;
import com.graphhopper.storage.GraphHopperStorage;
import com.graphhopper.routing.SPTEntry;
import com.graphhopper.storage.index.Snap;
import com.graphhopper.util.shapes.GHPoint3D;
import org.locationtech.jts.geom.Coordinate;
import org.heigit.ors.common.TravelRangeType;
import org.heigit.ors.exceptions.InternalServerException;
import org.heigit.ors.routing.RouteSearchContext;
import org.heigit.ors.routing.algorithms.DijkstraCostCondition;
import org.heigit.ors.routing.algorithms.TDDijkstraCostCondition;
import org.heigit.ors.routing.graphhopper.extensions.AccessibilityMap;
import org.heigit.ors.routing.graphhopper.extensions.ORSEdgeFilterFactory;
import org.heigit.ors.routing.graphhopper.extensions.weighting.DistanceWeighting;
import org.heigit.ors.routing.traffic.TrafficSpeedCalculator;
import org.heigit.ors.util.ProfileTools;
import org.locationtech.jts.geom.Coordinate;

import java.time.ZonedDateTime;
import java.util.ArrayList;
Expand All @@ -47,10 +50,12 @@ private GraphEdgeMapFinder() {
public static AccessibilityMap findEdgeMap(RouteSearchContext searchCntx, IsochroneSearchParameters parameters) throws Exception {
GraphHopper gh = searchCntx.getGraphHopper();
FlagEncoder encoder = searchCntx.getEncoder();
Weighting weighting = createWeighting(parameters, encoder);
String profileName = ProfileTools.makeProfileName(encoder.toString(), weighting.getName(), false);
GraphHopperStorage graph = gh.getGraphHopperStorage();

ORSEdgeFilterFactory edgeFilterFactory = new ORSEdgeFilterFactory();
EdgeFilter edgeFilter = edgeFilterFactory.createEdgeFilter(searchCntx.getProperties(), encoder, graph);
EdgeFilter defaultSnapFilter = new DefaultSnapFilter(weighting, graph.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileName)));
ORSEdgeFilterFactory edgeFilterFactory = new ORSEdgeFilterFactory();
EdgeFilter edgeFilter = edgeFilterFactory.createEdgeFilter(searchCntx.getProperties(), encoder, graph, defaultSnapFilter);

Coordinate loc = parameters.getLocation();
Snap res = gh.getLocationIndex().findClosest(loc.y, loc.x, edgeFilter);
Expand All @@ -64,7 +69,6 @@ public static AccessibilityMap findEdgeMap(RouteSearchContext searchCntx, Isochr

if (fromId == -1)
throw new InternalServerException(IsochronesErrorCodes.UNKNOWN, "The closest node is null.");
Weighting weighting = createWeighting(parameters, encoder);

if (parameters.isTimeDependent()) {
return calculateTimeDependentAccessibilityMap(parameters, encoder, graph, edgeFilter, queryGraph, snappedPosition, fromId, weighting);
Expand Down Expand Up @@ -114,6 +118,6 @@ private static AccessibilityMap calculateTimeDependentAccessibilityMap(Isochrone

private static Weighting createWeighting(IsochroneSearchParameters parameters, FlagEncoder encoder) {
return parameters.getRangeType() == TravelRangeType.TIME ? new FastestWeighting(encoder)
: new DistanceWeighting(encoder);
: new ShortestWeighting(encoder);
}
}
Original file line number Diff line number Diff line change
@@ -1,58 +0,0 @@
/* 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.weighting;

import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.routing.weighting.AbstractWeighting;
import com.graphhopper.util.EdgeIteratorState;

public class DistanceWeighting extends AbstractWeighting {
public DistanceWeighting(FlagEncoder encoder) {
super(encoder);
}

@Override
public double calcEdgeWeight(EdgeIteratorState edge, boolean reverse) {
double speed = flagEncoder.getAverageSpeedEnc().getDecimal(reverse, edge.getFlags());
if (speed == 0)
return Double.POSITIVE_INFINITY;

return edge.getDistance();
}

@Override
public double getMinWeight(double distance) {
return 0;
}

@Override
public String getName() {
return "distance";
}

@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final DistanceWeighting other = (DistanceWeighting) obj;
return toString().equals(other.toString());
}

@Override
public int hashCode() {
return ("DistanceWeighting" + this).hashCode();
}
}
103 changes: 103 additions & 0 deletions ors-engine/src/main/java/org/heigit/ors/util/ProfileTools.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.heigit.ors.util;

import com.graphhopper.util.PMap;
import org.heigit.ors.routing.RoutingProfileType;
import org.heigit.ors.routing.WeightingMethod;
import org.heigit.ors.routing.graphhopper.extensions.util.ORSParameters;

public class ProfileTools {
public static final String VAL_RECOMMENDED = "recommended";
private static final String KEY_WEIGHTING = "weighting";
private static final String KEY_WEIGHTING_METHOD = "weighting_method";
public static final String KEY_CH_DISABLE = "ch.disable";
public static final String KEY_LM_DISABLE = "lm.disable";
public static final String KEY_CORE_DISABLE = "core.disable";
public static final String KEY_PREPARE_CORE_WEIGHTINGS = "prepare.core.weightings";
public static final String KEY_PREPARE_FASTISOCHRONE_WEIGHTINGS = "prepare.fastisochrone.weightings";
public static final String KEY_METHODS_CH = "methods.ch";
public static final String KEY_ENABLED = "enabled";
public static final String KEY_THREADS = "threads";
public static final String KEY_WEIGHTINGS = "weightings";
public static final String KEY_LMSETS = "lmsets";
public static final String KEY_MAXCELLNODES = "maxcellnodes";
public static final String KEY_METHODS_LM = "methods.lm";
public static final String KEY_LANDMARKS = "landmarks";
public static final String KEY_METHODS_CORE = "methods.core";
public static final String KEY_DISABLING_ALLOWED = "disabling_allowed";
public static final String KEY_ACTIVE_LANDMARKS = "active_landmarks";
public static final String KEY_TOTAL_POP = "total_pop";
public static final String KEY_TOTAL_AREA_KM = "total_area_km";
public static final int KEY_FLEX_STATIC = 0;
public static final int KEY_FLEX_PREPROCESSED = 1;
public static final int KEY_FLEX_FULLY = 2;
public static final String KEY_CUSTOM_WEIGHTINGS = "custom_weightings";
public static final String VAL_SHORTEST = "shortest";
public static final String VAL_FASTEST = "fastest";

public static String makeProfileName(String vehicleName, String weightingName, boolean hasTurnCosts) {
String profileName = vehicleName + "_" + weightingName;
if (hasTurnCosts)
profileName += "_with_turn_costs";
return profileName;
}

/**
* Set the weightingMethod for the request based on input weighting.
*
* @param map Hints map for setting up the request
* @param requestWeighting Originally requested weighting
* @param profileType Necessary for HGV
*/
public static void setWeightingMethod(PMap map, int requestWeighting, int profileType, boolean hasTimeDependentSpeed) {
//Defaults
String weightingMethod = VAL_RECOMMENDED;

if (requestWeighting == WeightingMethod.SHORTEST)
weightingMethod = VAL_SHORTEST;

//For a requested recommended weighting, use recommended for bike, walking and hgv. Use fastest for car.
if (requestWeighting == WeightingMethod.RECOMMENDED || requestWeighting == WeightingMethod.FASTEST) {
if (profileType == RoutingProfileType.DRIVING_CAR) {
weightingMethod = VAL_FASTEST;
}
if (RoutingProfileType.isHeavyVehicle(profileType) || RoutingProfileType.isCycling(profileType) || RoutingProfileType.isWalking(profileType)) {
weightingMethod = VAL_RECOMMENDED;
}
}

map.putObject(KEY_WEIGHTING_METHOD, weightingMethod);

if (hasTimeDependentSpeed)
map.putObject(ORSParameters.Weighting.TIME_DEPENDENT_SPEED_OR_ACCESS, true);
}

/**
* Set the weighting for the request based on input weighting.
*
* @param map Hints map for setting up the request
* @param requestWeighting Originally requested weighting
* @param profileType Necessary for HGV
*/
public static void setWeighting(PMap map, int requestWeighting, int profileType, boolean hasTimeDependentSpeed) {
//Defaults
String weighting = VAL_RECOMMENDED;

if (requestWeighting == WeightingMethod.SHORTEST)
weighting = VAL_SHORTEST;

//For a requested recommended weighting, use recommended for bike, walking and hgv. Use fastest for car.
if (requestWeighting == WeightingMethod.RECOMMENDED || requestWeighting == WeightingMethod.FASTEST) {
if (profileType == RoutingProfileType.DRIVING_CAR) {
weighting = VAL_FASTEST;
}
if (RoutingProfileType.isHeavyVehicle(profileType) || RoutingProfileType.isCycling(profileType) || RoutingProfileType.isWalking(profileType)) {
weighting = VAL_RECOMMENDED;
}
}

map.putObject(KEY_WEIGHTING, weighting);

if (hasTimeDependentSpeed)
map.putObject(ORSParameters.Weighting.TIME_DEPENDENT_SPEED_OR_ACCESS, true);
}
}

0 comments on commit 79f3e8c

Please sign in to comment.