-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
European toll fallback rules #2450
Conversation
@karussell anything missing? |
This is a nice addition, thank you! The main problem I have with continuing this path for CountryRules is that I'm unsure if we should add a new method for every encoded value we want to modify - see also e.g. #2402. |
Adding more methods is not really problematic because they all come with a default implementation. Child classes only need to implement them when it makes sense to do so. Making the interface more generic just moves the ugliness into the rules themselves. I'd rather have a larger but well-defined interface than having to write boilerplate code in every rule. |
But what would be the alternative? We could keep the encoded values separate from each other by putting all the country-specific stuff into the parsers directly, i.e. the TollParsers knows everything about Toll and also about Toll in the different countries. But then the country-specific stuff is spread over several parsers. Or we use separate country rules for each country and for each encoded value, like
Yes, this saves some work when someone wants to add such a method (for another or custom encoded value).
You mean we could use some kind of generic method in the interface CountryRule {
Object getXYZ(ReaderWay way, ...);
}
class MyCountryRule implements CountryRule {
Object getXYZ(ReaderWay way, ...) {
if (thisIsAboutToll(way, ...)) {
Toll toll = determineToll(way, ...);
return toll;
} else if (thisIsAboutMaxSpeed(way, ...)) {
double maxSpeed = determineMaxSpeed(way, ...);
return maxSpeed;
}
}
} Yes, I don't like this either. |
Actually I am more worried about the signature of the CountryRule methods. What is the TransportationMode supposed to do here? These encoded values aren't meant to be 'vehicle' specific, are they? And what is |
Maybe public interface CountryRule {
default double modifyMaxSpeed(ReaderWay readerWay, double maxSpeed) {
return maxSpeed;
}
default RoadAccess modifyRoadAccess(ReaderWay readerWay, RoadAccess roadAccess) {
return roadAccess;
}
default Toll modifyToll(ReaderWay readerWay, Toll toll) {
return toll;
}
} I know, not directly what this PR is about, but now we are at it... |
MaxSpeed and RoadAccess are both dependant on the TransportationMode. Or better, they should be. e.g maxspeed for motorcar vs hgv
CountryRules could also cap values. So they're not restricted to providing fallback values.
Correct. |
Right. But so far they are not :) And certainly not all encoded values depend on the transportation mode. Then again there is no reason all the CountryRule methods need to have the same signature. We should just not add the TransportationMode parameter to all methods when it is not needed, just because some others have it.
Sure, this not what I meant. I meant that the parsers determine some kind of value (what we currently call default double modifyMaxSpeed(ReaderWay readerWay, double maxSpeed) {
return maxSpeed;
} |
It wouldn't be one EV per TransportationMode. E.g. although a "scooter" or "motorcycle" has a lower possible speed (and different road access properties) it still uses the "normal" max_speed (IMO bikes use them too), i.e. there are no special signs on the street. But max_speed_hgv can act as a different data source (filled from different tags) and might have other defaults in different countries. |
core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java
Show resolved
Hide resolved
Btw did you take the toll information for the different countries from a wiki table? Is there such a table? Where? Or did you take this data from somewhere else? I still think we should write a (semi-automatic) code generator to parse these wiki tables (same for max speed and access) at some point (##2392), but that is for another issue. |
Sadly not. I had to compile the rules from various sources. But i think it might be worth to create a wikipage for it and maintain it there. |
core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java
Outdated
Show resolved
Hide resolved
Thanks a lot for this! |
* fix travis release for tagged commits; use jdk 17 instead of 11 for github releases * allow skipping the LM constraint check for A* (graphhopper#2544) * LM constraint should be ignored for A* * make it possible to skip checkLMConstraints call * move checkLMConstraints call to LMSolver. Fix createSolver for mixed preparations * avoid fundamental default change but throw proper exception when lm.disable parameter missing * Add names for travis build jobs (to be shown under 'Jobs and Stages on GitHub)' * Disable doclint explicitly * travis: only keep release build, related to graphhopper#2552 * Clean up javadoc comments (graphhopper#2569) * fix javadoc errors * remove javadoc plugin * make comment more readable * include javadoc again, revert unreadable comments * disable doclint for javadoc * Add flex alternatives to measurement * Do not remove SPT elements from the priority queue, speeds up flexible algorithms (graphhopper#2571) * Split flag encoders into encoded values and tag parsers (graphhopper#2561) * Remove final from VehicleEncodedValues * Log available country rules (graphhopper#2579) Co-authored-by: Thomas Butz <thomas.butz@optitool.de> * Give access to vehicle tag parsers * Update bestFwd/BwdEntry for flexible algorithms when deleting SPT entries, fix graphhopper#2581 * Travis: Fix warnings in build config validation It said: Build config validation root: deprecated key sudo (The key `sudo` has no effect anymore.) root: missing os, using the default linux root: key matrix is an alias for jobs, using jobs * Add VehicleEncodedValues#isHGV * Use more recent node/npm versions to fix the build (graphhopper#2583) * Update readme for 5.3 * update deployment guide (graphhopper#2576) * update deployment guide * Update deploy.md * review comments * mention max_visited_nodes * Replace deprecated dropwizard parameter types (graphhopper#2574) Co-authored-by: Thomas Butz <thomas.butz@optitool.de> * Use epsilon=0.9 for LM map-matching * Update changelog * Use edge keys consistently, store keys in CH shortcuts (graphhopper#2567) * Add comment about slow non-CH alternatives * Remove outdated/wrong comments * Add a mapmatching test * Remove 'shared' encoded values with $ sign in name (graphhopper#2585) * remove OSMAccessParser * removed $ from encoded values * no if clause necessary * fix changelog * downgrade todonow * Matrix client improvements (graphhopper#2587) * tmp * fix tests * update okhttp to 4.9.3 * fixes regarding code review Co-authored-by: easbar <easbar.mail@posteo.net> * European toll fallback rules (graphhopper#2450) Co-authored-by: Thomas Butz <thomas.butz@optitool.de> * use for loop in PathDetailsBuilderFactory as discussed in graphhopper#2585 (graphhopper#2589) * Fix: Put back block_private and block_fords for racingbike, this got lost in graphhopper#2561 * Make motor vehicle and hgv properties configurable for roads encoder (graphhopper#2594) * Disable edge+alt measurements, they take too long * Use separate deleted flag for SPTEntry, prevent exception when calculating routes with non-feasible approximator (graphhopper#2600) Also revert epsilon=0.9 'fix' in map matching now that we know what is going on * LMApproximator: Align variable names with equation numbers * Log map-matching took value in ms instead of seconds (graphhopper#2591) Co-authored-by: Andi <easbar.mail@posteo.net> * rename StringIndex to EdgeKVStorage in preparation for graphhopper#2597 * windows does not need a separate documentation due to WSL (graphhopper#2599) * windows does not need a separate documentation due to WSL * link to install steps directly * EdgeKVStorage: store more than Strings (graphhopper#2597) * copied code and tests from byteindex branch * a bit more docu and tests * behaviour change: throw exception if string is too long and so cut string before storing way_name * renamed StringIndex -> EdgeKVStorage * more consistent: reject null values for all cases * include lost changes again * ensure same version of storage is used * changes from review * fix variable names for key handling * comments to javadoc * better 'compression' in case of identical map with byte[] array * throw exception earlier * Fix bug in non-CH AlternativeRoute (graphhopper#2603) * fix plateau-end check * Revert "Disable edge+alt measurements, they take too long" This reverts commit fb39266. * increase count to 10 for Measurement * AlternativeRoute: follow up refactoring, graphhopper#2603 * MiniGraphUI fixes to make it work again * move quickstart info into more prominent installation of README (graphhopper#2605) * Measurement: reduce routingCH_alt after it was accidentally raised in graphhopper#2603 * Remove GraphHopperStorage (graphhopper#2606) * Rename: GraphHopper#getGraphHopperStorage -> GraphHopper#getBaseGraph * Remove GraphHopperStorage * reduce benchmark load e.g. exclude too slow LM16 case * AlternativeRoute: closer to CH version; default is now a better compromise of speed vs. alternatives found (alternative rate is 1.8 for DE and 1.9 for bavaria) * Move/Rename: EncodingManager.Access -> WayAccess * AlternativeRoute: fix test * Clean up EncodingManager Builder * minor: Use Bike/FootNetwork.KEY * Rename freshFlags -> refreshFlags * BaseGraph: remove copying flags on write, see graphhopper#2593 * added elevation data to reduce internet-dependence while running test * Add comment about GraphHopper#init * Merged graphhopper#2593, i.e. revert b8d9b55 Co-authored-by: Andi <contactammmagamma@gmail.com> Co-authored-by: Thomas Butz <thomas.butz@optitool.de> * Add another elevation file used in tests * Use access and speed EVs rather than flag encoder for GHUtility#setSpeed * Fix broken imports * More use access and speed EVs instead of encoder for GHUtility#setSpeed * Replace flag encoder with turn cost encoded value in turn cost provider * Remove FlagEncoder from ShortestWeighting and CustomWeighting * Find strongly-connected components of station (stop) graph (graphhopper#2608) * Load EncodingManager from properties instead of config (graphhopper#2607) * Helper.cutString should be only for KVStorage and reduce length to 250 to fix graphhopper#2609 * CHPreparationGraph bug fix: unsigned shift required (and increase limit for getKeyWithFlags graphhopper#2567) * make error message more clear * CHPreparationGraph: revert to previously correct signed shift * Increase maximum edge-based CH key for preparation to 2^30 again (graphhopper#2612) * Add test for large edge ID, graphhopper#2612 * custom_model: introduce value expression (graphhopper#2568) * value expression: findMax needs to be evaluated * less strict if * or + operator * refactored to findMinMax * made core tests pass * fix some more tests * fix more tests * add encoded values to initialization plus tests * check minimum for custom_model of query * improve on check of minimum and negative factors * less overhead for constant values * use Double.parse instead of ExpressionEvaluator if number to significantly improve speed * minor cosmetics * clarify LATER and removed TODO NOW * adapted docs * minor optimization and cleanup * fix FindMinMax.checkLMConstraints call * do not allow / as operation * reduce power and complexity of right hand side a bit more and allow only a single EncodedValue for now * better readable via extra MinMax class instead of double[] * exclude changes from master * a bit more comments * Create weighting after graph in two tests * Update custom model editor: operator values are strings now * Update custom model editor: validation + auto-complete for rhs expressions (graphhopper#2615) * Allow graph.encoded_values for which there is no tag parser * Use actual speed maximum rather than flagEncoder#getMaxSpeed() for weighting.getMinWeight() (graphhopper#2614) * Rename getMin/MaxInt -> getMin/MaxStorableInt, getMaxSetValueOrMax -> getMaxOrMaxStorable (graphhopper#2616) * Remove FlagEncoder#getMaxSpeed() (graphhopper#2619) * Remove car/bike_access evs from DefaultEncodedValueFactory, was added only for graphhopper#2523 * CustomModelParser: no need for max speed * EdgeKVStorage: store name and ref tags separately (graphhopper#2598) * copied code and tests from byteindex branch * a bit more docu and tests * behaviour change: throw exception if string is too long and so cut string before storing way_name * renamed StringIndex -> EdgeKVStorage * store name and ref tags separately; create separate path detail for ref; use ref as fallback in instruction text * added text to changelog * minor comment changes * review: fix comments * review comments and add getValue method to avoid creating HashMaps * try if speed up was really from the change getKeyValues->edge.getValue * Revert "try if speed up was really from the change getKeyValues->edge.getValue" This reverts commit 58a34d6. Co-authored-by: easbar <easbar.mail@posteo.net> * update i18n * Remove FlagEncoder (graphhopper#2611) * EdgeKVStorage: remove smallCache as too much complexity. we accept disk usage increases by 12% and more uniq keys later possible * Move outdoor vehicles list * Relax speed EV requirement for EncodingManager#getVehicles * Check vehicle instead of access/speed in checkProfilesConsistency * reduce distance when average_speed path details can be missing, fixes graphhopper#2620 * Valid if PathDetail is null (graphhopper#2618) * Valid if object is null * Adding my name in contributors * Adjusting indentation * Update CONTRIBUTORS.md Co-authored-by: Rafael Telles <rafael@bzion.com.br> Co-authored-by: Peter <graphhopper@gmx.de> * Support for forward & backward key value pairs (graphhopper#2622) * fix test * minor update to docs for map matching * Update README.md * add more info to exception * profiles.md: updated rhs to strings * minor test change to avoid downloading elevation tile * CustomModelParser: minor cleanup * EncodedValue: bug fix for negateReverseDirection * ConditionalExpressionVisitor: allow '-' as unary operation * fixed link to CGIAR attribution * make global time&distance values consistent with path details and instructions (graphhopper#2626) * make global time&distance values consistent with time&distance path details and also the sum of time&distance of the instructions * minor simplification * mention change in changelog * minor comment fix for graphhopper#2626 * Update github actions v2->v3 * Include destination in instructions (graphhopper#2624) * support for destination and add test for non repetitive instructions when destination is included * include destination:ref * add missing osm file * try getKeyValues instead getValue * try speed of getKeyValues (fetching REVERSE_STATE necessary as getKeyValues is align with 'internal' storage direction) * use simpler edge.getValue call again * Make profile resolving more flexible for web API (graphhopper#2629) * ProfileResolver only resolves name of the profile (graphhopper#2629) * car: do not pass jersey_barrier https://www.openstreetmap.org/node/8857224952 * move cut string method to EdgeKVStorage * EdgeKVStorage: no need for cacheSize parameter anymore * Examples: remove incorrect comment * fix PathDetails e.g. -1 as default for DecimalDetails doesn't work as a value of the EV could be negative too * renamed DouglasPeucker to RamerDouglasPeucker * client-hc: add examples to get translated ("raw") turn instructions * HeightTile: minor correction, DecimalEncodedValueImpl: minor clarification * EdgeKVStorage: allow 32 bits (graphhopper#2632) * allow 32 bits instead of just 31 for EdgeKVStorage * remove incorrect exception * minor change to wayGeo limit check * Maps: Hide gpx export button when custom model box is open, fix graphhopper#2635 * Add hint about custom_model_file vs. custom_model to exception error message (graphhopper#2638) * Add comma in routing logs * Move code that creates EncodingManager from properties to EncodingManager * Return boolean result from BaseGraph#loadExisting * Move code that puts EncodingManager into properties to EncodingManager * add hgt provider * AbstractTiffElevationProvider: use correct long cast * pt: hint on how to use multiple files * Add BaseGraph#debugPrint * new edge smoothing: "ramer" (graphhopper#2634) * initial version of new edge smoothing * improve comments * let's switch the order: first do sampling, then smoothing * use moving_average as name and a few more comments * use same max_elevation like in example config * fix moving_average * again moving_average rename * New average_slope EV (graphhopper#2645) * initial version of new edge smoothing * improve comments * let's switch the order: first do sampling, then smoothing * encoded values for elevation-aware routing: average_slope and max_slope * for tunnels and bridges ignore elevation changes for pillar nodes * SlopeSetter -> SlopeCalculator * fix link for GTFS demo file for graphhopper#2639 * removed defaultIsInfinity and fix bug in DecimalEncodedValueImpl (graphhopper#2646) * removed defaultIsInfinity and fix bug in DecimalEncodedValueImpl * changelog: fix issue number * for useMaximumAsInfinity: also throw an exception if value is too big, but not for infinity * fix merge of master * Revert "for useMaximumAsInfinity: also throw an exception if value is too big, but not for infinity" This reverts commit e3d8826. * print warning if max_width, max_weight etc values are too large * fix link for GTFS demo file for graphhopper#2639 * Revert "fix link for GTFS demo file for graphhopper#2639" This reverts commit d9bb4b9. * NOTICE: updated dependencies and copyright * make ramer edge smoothing more robust, graphhopper#2634 * TurnCostParser: no need for method createTurnCostEncodedValues * improvements for bike (graphhopper#2631) * lower speed for bad smoothness and steps; avoid hazmat; faster if paving_stones * clean up of smoothness handling * revert to 4kmh pushing section speed and tweak speed for certain surfaces * mtb+racing: do not overwrite highway and surface speed if identical in subclass * consider multiple from members for no_entry (graphhopper#2648) * allow configuring turn costs and TransportationMode for RoadsTagParser, related to graphhopper#2460 * add hgv enum to make truck access configurable * add test for hgv encoded value * for now do not log as too many warnings, graphhopper#2646 * SlopeCalculator: skip calculation if PointList is empty or 2D only * Do not get elevations for nodes we don't need while parsing OSM * Custom weighting calcEdgeMillis truncate instead of round * just for consistency and easier migration with/from FastestWeighting * CustomWeighting: handle special case for barrier edges with distance==0 and average_speed>0 * Maps: Add slope detail to elevation diagram (graphhopper#2654) * Custom and fastest weighting calcEdgeMillis round instead of truncate * otherwise they are not always the same, because one multiplies by 3600 and the other by 3.6*1000 ... * Fix pt tests * Disable flaky test * custom and fastest calcEdgeMillis again: make them actually the same * Validate that osm ids are not negative (graphhopper#2652) * Add comment about negative osm ids, code formatting * OSMParsers: don't accept null TagParser * replace car4wd with roads and a custom_model (graphhopper#2651) * Revert "OSMParsers: don't accept null TagParser" This reverts commit 8f5c7b2. * Add urban density encoded value to identify built-up areas (graphhopper#2637) * Rename Development -> UrbanDensity (graphhopper#2637) * Support ";" access delimiter for car access. (graphhopper#2655) * Support ";" access delimiter for car access. One example is motor_vehicle = agricultural;forestry * Add support for ";" access delimiter for MotorcycleTagParser and road_access EV. * Move logic for access delimiter handling for ";" from RoadAccess into OSMRoadAccessParser * Fix for OSMRoadAccessParserTest * map match without graphhopper class (graphhopper#2657) * Solve Viterbi problem with Dijkstra to calculate fewer routes * Solve Viterbi problem with Dijkstra to calculate fewer routes * use 6.x/6.0 in readme * announcement * fix critical bug in client-hc for Matrix API * SBI Algo Co-authored-by: Peter <graphhopper@gmx.de> Co-authored-by: easbar <easbar.mail@posteo.net> Co-authored-by: otbutz <tbutz@optitool.de> Co-authored-by: Thomas Butz <thomas.butz@optitool.de> Co-authored-by: Michael Zilske <michael.zilske@tu-berlin.de> Co-authored-by: Robin <boldtrn@users.noreply.github.com> Co-authored-by: Andi <contactammmagamma@gmail.com> Co-authored-by: Rafael Sanches Telles <sanchesetelles@gmail.com> Co-authored-by: Rafael Telles <rafael@bzion.com.br> Co-authored-by: Alexey Abel <dev@abelonline.de> Co-authored-by: Lukas Weber <32765578+lukasalexanderweber@users.noreply.github.com> Co-authored-by: ratrun <ratrun@gmx.at>
@otbutz can you explain the main benefits for the country toll rules? Wouldn't it be reasonable to set toll=no everywhere the |
Germany was at least a prominent example in the past, but maybe things have improved? We (OPTITOOL GmbH) tried running GH without the fallback rules about two years ago and quickly reintroduced the rules when customers reported high deviations. |
Ok, so this is more about HGV toll than about missing |
Absolutely |
@otbutz Another question regarding the toll rules :) Do you think it is essential to keep them a country rule? Do you see any drawbacks of simply distinguishing by country right in OSMTollParser? |
With the switch to osm-legal-default-speeds, the country rules have more or less been reduced to toll rules anyway. I think it's reasonable to reduce their public exposure accordingly. |
@otbutz and another question: Currently there are empty rules for BIH, GBR, IRL, MDA, MKD, MNE, NOR, RUS which means Toll.MISSING is not set to Toll.NO, just like for all the non-European countries for which there is no country rule at all. Did you add these countries just for completeness? And can we set Toll.NO there instead? |
Yes.
If applicable, sure. |
I'm also a bit confused because in Albania we set Toll.NO instead of Toll.MISSING, but for example in France we set Toll.ALL for motorways, but keep Toll.MISSING for all the other roads. -> #3111 |
Added toll fallback rules for most European countries. I skipped countries like the UK or Ireland, which have toll roads but cannot be addressed by simple road type matching like e.g "toll on all motorways by default", because they only charge tolls on certain roads or even road sections.
Some of them also simply express that the country in question doesn't collect any toll like Finland or Iceland:
graphhopper/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java
Lines 26 to 35 in 2ec8e34
Those rules are still useful as we know that any untagged way can safely be assumed to be toll free in those countries.