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
Move ProfileResolver out of GraphHopper class #1958
Conversation
…r instead, many tests failing
…, use profiles for non-prepared too
@@ -34,6 +34,9 @@ | |||
*/ | |||
public class GHRequest { | |||
private List<GHPoint> points; | |||
// todonow: keep this here or put it into hints, and even more important: can we remove vehicle+weighting from | |||
// hints? | |||
private String profile = ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we discussed this in #1859 already: We'll def. remove vehicle+weighting from the HintsMap, but maybe in a follow-up PR? Since the profile parameter will be required it makes sense to keep it as a separate field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I would also use it here and remove weighting and vehicle in a later PR
@@ -824,6 +809,9 @@ public boolean load(String graphHopperFolder) { | |||
} | |||
|
|||
private void checkProfilesConsistency() { | |||
if (profilesByName.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few odd cases where we do not use GraphHopper
for routing (like NearestResource
) so these do not necessarily require profiles. Not sure, to me this seems rather the exception so I am checking the existence of at least one profile here. Once we do #1901 we can move this check into GraphHopperRouter
's constructor for example.
// todonow: maybe still allow something like running a (non CH) profile edge-based or not (if no turn costs or something)?, also see traversal mode below | ||
if (!request.getHints().get(Routing.EDGE_BASED, "").isEmpty()) | ||
throw new IllegalArgumentException("GHRequest may no longer contain the edge_based=true/false parameter, use the profile parameter instead, see #todonow"); | ||
// todonow: do not allow things like short_fastest.distance_factor or u_turn_costs unless CH is disabled and only under certain conditions for LM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is about the 'merging' feature where some properties are set right in the profile (like distance_factor), but they might be overwritten per request. The problem is that this does not work with CH (and only some special cases work for LM), so I am a bit unsure where to put these checks. They cannot really go into createWeighting
(where the merging will happen?!), because in this method we do not 'know' whether the weighting is created for CH or not...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for now we are just blindly merging the hints, later we will add these kind of checks here to be more strict
if (!profile.isTurnCosts() && !request.getCurbsides().isEmpty()) | ||
throw new IllegalArgumentException("To make use of the " + CURBSIDE + " parameter you need to use a profile that supports turn costs"); | ||
|
||
// todonow: should we be able to control this using the edge_based parameter? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can do this later, see #1702.
Boolean edgeBased = getEdgeBased(hintsMap); | ||
Integer uTurnCosts = getUTurnCosts(hintsMap); | ||
return (edgeBased == null || p.isTurnCosts() == edgeBased) && | ||
(uTurnCosts == null || uTurnCosts.equals(getUTurnCosts(p.getHints()))) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are now selecting a CHProfileConfig
instead of a CHProfile
we can deal with the case of multiple edge-based profiles with different u_turn_costs again (c.f. #1949). This should also help to get rid of Weighting#getFlagEncoder
in the long run.
docs/web/api-doc.md
Outdated
@@ -71,6 +71,7 @@ empty list for `profiles_ch`. | |||
Parameter | Default | Description | |||
:----------------|:-----------|:----------- | |||
ch.disable | `false` | Use this parameter in combination with one or more parameters of this table | |||
# todonow: update docs regarding profile etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is supposed to describe the web-api, but this documentation also is available on the directions-api documentation website. Does it make sense to keep this updated here? Or should this be rather about the documentation of the parameters of the open source server?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, definitely this is different. This doc should should show all the features, e.g. including public transit and mvt endpoint etc that we do not have in the GraphHopper Directions API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so this file is actually the documentation of the open source server then? I will try to make this a bit more clear and for the hosted service point to the online docs then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to avoid doing "advertisements" here, but probably you are right and this would be more clear.
@@ -73,6 +75,7 @@ | |||
private final Map<String, Object> properties = new TreeMap<>(); | |||
private long seed; | |||
private int maxNode; | |||
private String vehicle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I thought the measurements are running only for one vehicle anyway (and if we want to test others we might as well start the measurement again for the other vehicle), so it makes sense to keep the vehicle as a class variable (just like weighting) rather than pass it with every querysetting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the CustomWeighting branch I already use profile
and then I do not want the vehicle in the request: https://github.com/graphhopper/graphhopper/pull/1841/files#diff-cd749cc545f8b84137c2b75b2d174b72 but probably this can be still done somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok yes vehicle and weihgting should be mostly removed from measurement and only profile should be left then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but let's do this later :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There isn't really anything to do. vehicle&weighting are only used to create the profile initially.
# Conflicts: # core/src/main/java/com/graphhopper/routing/ProfileResolver.java # core/src/test/java/com/graphhopper/routing/RoutingAlgorithmIT.java # reader-osm/src/test/java/com/graphhopper/GraphHopperIT.java # reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java # tools/src/main/java/com/graphhopper/tools/CHMeasurement.java # tools/src/main/java/com/graphhopper/tools/Measurement.java # web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java # web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java
# Conflicts: # core/src/main/java/com/graphhopper/routing/ProfileResolver.java # reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java # reader-gtfs/src/test/java/com/graphhopper/ExtendedRouteTypeIT.java # reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java # reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java # reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java # reader-osm/src/test/java/com/graphhopper/GraphHopperIT.java # reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java # web/src/test/java/com/graphhopper/http/SpatialRulesTest.java # web/src/test/java/com/graphhopper/http/resources/ChangeGraphResourceTest.java # web/src/test/java/com/graphhopper/http/resources/GtfsTest.java # web/src/test/java/com/graphhopper/http/resources/I18nResourceTest.java # web/src/test/java/com/graphhopper/http/resources/IsochroneResourceTest.java # web/src/test/java/com/graphhopper/http/resources/MvtResourceTest.java # web/src/test/java/com/graphhopper/http/resources/NearestResourceTest.java # web/src/test/java/com/graphhopper/http/resources/NearestResourceWithEleTest.java # web/src/test/java/com/graphhopper/http/resources/PtIsochroneTest.java # web/src/test/java/com/graphhopper/http/resources/RouteResourceWithEleTest.java # web/src/test/java/com/graphhopper/http/resources/SPTResourceTest.java
// Merge profile hints with request hints, the request hints take precedence. | ||
// Note that so far we do not check if overwriting the profile hints actually works with the preparation | ||
// for LM/CH. Later we should also limit the number of parameters that can be used to modify the profile. | ||
PMap hints = new PMap(); | ||
hints.putAll(profile.getHints()); | ||
hints.putAll(requestHints); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are (the very simple) rules how we merge the profile hints with the request hints. The only thing I am wondering now is how we do this for block_area? Shall we do this in a similar way (use hints from profile and overwrite with request hints)? Do we need this here or is it ok to only create block areas from request hints (not the profile) here, and add this in #1776? Its still a bit unfortunate that we do not do the block_area stuff inside createWeighting
. Now it looks all we are missing to do this in createWeighting
are the points
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing I am wondering now is how we do this for block_area?
Hmmh, we would need to add it to the list of shapes
Do we need this here or is it ok to only create block areas from request hints (not the profile) here
I would postpone this and properly support this in CustomWeighting.
Now it looks all we are missing to do this in createWeighting are the points
Yeah, although we only need this because of the is-in-area check which we could keep out of the Weighting creation somehow.
# Conflicts: # core/src/main/java/com/graphhopper/routing/ProfileResolver.java # tools/src/main/java/com/graphhopper/tools/Measurement.java
# Conflicts: # core/src/main/java/com/graphhopper/routing/ProfileResolver.java # web/src/test/java/com/graphhopper/http/resources/RouteResourceProfileSelectionTest.java
In this PR I moved the
ProfileResolver
out ofGraphHopper
and into theRoute/Isochrone/SPTResource
. This means:GraphHopper#route
only considers theprofile
parameter (instead ofvehicle,weighting,edge_based
). At the moment it even throws an error if these parameters are set. Is that ok or should we go for a 'softer' migration and change this to an error log only? A missingprofile
parameter is definitely an error, I just wonder if its too strict to throw an error in case there is alsovehicle/weighting
(which are not used anyway).To make use of the
profile
parameter we now have to add routing profiles also for non-prepared (no CH or LM) algorithms. GH configs without profiles lead to an error with this PR!ProfileResolver
does the conversion of thevehicle/weighting/edge_based
parameters and the profile name is passed toGraphHopper
. Therefore the actual behavior of the GH server should not be changed (unless there is a bug).Another change that is done here is that we no longer use the first flag encoder as default vehicle. We already did this for CH before, but now its the same for CH/LM/flex. If the vehicle parameter is not set (and ch.disable=true) we are trying to find a matching profile based on the other parameters. If there are multiple matches there will now be an error (previously we would have used the first encoder as default vehicle).
I think it might be useful to merge these changes before in #1859 we:
Actually expose the new
profile
parameter via the web api. We probably also want to adjust the integration tests then and only keep a few that test the parameter conversion (profile selection). The good thing with this PR is that we can check if the conversion works before changing the tests etc.Implement the merging rules between profile parameters and hints (e.g. take distance factor for short_fastest weighting from profile, but overwrite if given in request hints and not CH etc.)
Current todos for this PR:
config-example.yml