-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Location-dependent left hand driving flag #4415
Conversation
do i understand it correctly, that this adds a general ability to use location-based data when preprocessing osm data, not just data about left/right side driving? can the features in the geojson file overlap? |
cdcc6a5
to
de0a73d
Compare
@emiltin yes, it is not limited to left-hand driving tags and GeoJSON can have any data that will be forwarded into Polygons with non-intersecting tags sets can overlap. If some overlapping polygons have the same tag then
|
ok, thanks for clarifying. this seems very useful. it will cover a different set of use-cases related to location data than the raster-based approach already available. |
de0a73d
to
1030510
Compare
You mean stored like that on disk? As far as I remember there were some issues around using out default memory-dump based serialization. If you see a fix for that, go for it. 👍
This is mainly an issue while crossing country polygon borders?
Do you think it would be possible to specify this from within the profile? Do we want to allow for multiple of those sources? This could work similar to how we use raster-data, in this case it would just be polygon based data. |
@TheMarex i added a vector serializer
yes, maybe for driving side flag this would make no sense (an edge case https://www.openstreetmap.org/export#map=17/22.52030/114.07047), but in many cases ways can cross polygons with the same tags, but different values.
yes, it is possible to specify in profiles, but data must loaded before creating contexts, otherwise many copies of rtrees will be multiplied for every thread-local context. Multiple of sources are also possible, in principle we can index data in a single rtree, but it will bring the merging question to discussion, i would go first towards a single GeoJSON file with MultiPolygon support and |
We could call the initialization in the |
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.
Reading the code, I think it might make sense to have a CLI parameter for the location data after all, since it is optional. I will leave this up to you to decide.
What is the plan with relation to the node-location? Do we want to wait for that PR or should be tell users to use the osmium re-writer?
Thanks for pushing this forward. 👍
CHANGELOG.md
Outdated
@@ -18,6 +19,10 @@ | |||
- Fix a pre-processing bug where incorrect directions could be issued when two turns would have similar instructions and we tried to give them distinct values (https://github.com/Project-OSRM/osrm-backend/pull/4375) | |||
- The entry bearing for correct the cardinality of a direction value (https://github.com/Project-OSRM/osrm-backend/pull/4353 | |||
- Change timezones in West Africa to the WAT zone so they're recognized on the Windows platform | |||
- Profiles |
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.
Changelog entries need to be moved to 5.12
CHANGELOG.md
Outdated
@@ -6,6 +6,7 @@ | |||
- BREAKING: Traffic signals will no longer be represented as turns internally. This requires re-processing of data but enables via-way turn restrictions across highway=traffic_signals | |||
- Additional checks for empty segments when loading traffic data files | |||
- Tunes the constants for turns in sharp curves just a tiny bit to circumvent a mix-up in fork directions at a specific intersection (https://github.com/Project-OSRM/osrm-backend/issues/4331) | |||
- BREAKING: added `is_left_hand_driving` vector to `.ebg_nodes` file |
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 might want to just say something like File format for .ebg_nodes not compatible with 5.11
.
""" | ||
And the ways with locations | ||
| nodes | driving_side | | ||
| ab | right | |
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 tests the driving_side
tag on ways in additional to the tag coming from outside data? Do you think in the future we might want to parse this data automatically from the OSM relations?
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 some residential roads, service roads, private ways or u-turns. Yes, we can add in future such handling, atm tags on ways have higher priority than default values.
@@ -114,6 +115,7 @@ struct ExtractionWay | |||
bool is_startpoint : 1; | |||
bool forward_restricted : 1; | |||
bool backward_restricted : 1; | |||
bool is_left_hand_driving : 1; |
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.
Just a thought: Maybe we should add some bool unused : 2
to make it explicit how many bits are still free.
Unrelated to your change but looking at this again, didn't VSC have problem with packing bools? We might want to change this to std::uint8_t
.
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.
VCS have other rules for padding, but here it should be similar to gcc packing
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.
after some hours of debugging i think i will keep bool type here, because of some strange gcc behavior here: with std::uint8_t
setting is_startpoint
also sets forward_restricted
and backward_restricted
. it can be either ub or gcc optimization issue
@@ -103,7 +103,7 @@ struct ProfileProperties | |||
bool continue_straight_at_waypoint; | |||
//! flag used for restriction parser (e.g. used for the walk profile) | |||
bool use_turn_restrictions; | |||
bool left_hand_driving; | |||
bool left_hand_driving; // DEPRECATED: property value is local to edges from API version 2 |
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.
What will happen if a user sets this value? Will it be used as the default for per-edge values?
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.
removed
include/storage/serialization.hpp
Outdated
@@ -114,44 +114,64 @@ template <typename T> void write(io::FileWriter &writer, const util::vector_view | |||
writer.WriteFrom(data.data(), count); | |||
} | |||
|
|||
template <typename T> inline unsigned char packBits(T &data, std::size_t index, std::size_t count) |
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.
data
can be a const-ref.
}; | ||
} | ||
|
||
sol::table LocationDependentData::operator()(sol::state &state, const osmium::Way &way) const |
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.
Would it be possible to return a non-sol object, so we can keep this interface lua-agnostic? I think sol should be able to wrap an unordered_map
automatically.
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 would like to keep it as a shortcut to avoid creating unordered_map
. It can be easily adjusted when it will be clear how conflicting tags must be merged
@@ -224,7 +225,7 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) | |||
"interpolate", | |||
&RasterContainer::GetRasterInterpolateFromSource); | |||
|
|||
context.state.new_usertype<ProfileProperties>( | |||
auto registration_ProfileProperties = context.state.new_usertype<ProfileProperties>( |
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.
Why do we need to save the return type of new_usertype
here?
@@ -0,0 +1,38 @@ | |||
#include "storage/serialization.hpp" |
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.
Good idea. We should add tests for the other serialization methods too at some point.
d4f5c92
to
be68c57
Compare
@TheMarex please can you check the last changes? I have tried to use real data with OSM administrative boundaries and results are very disappointing: EDIT: Before using location-dependent data, i think we need benchmarks of desired features and make an optimization of |
5550b63
to
57e7819
Compare
@TheMarex i have ported point-in-polygon check from osmium and added some unit tests to check correctness. The performance results are better than using There are still some space for improvement because "bands" solution is a naive implementation of an interval tree with fixed-size bands. For OSM Germany border with latitudes from 47.2701 to 55.0992 with a band width 0.00056389 degrees the histogram of segments is so the check performance will depend on node locations and at the southern border it will be 1000 times slower than at the northern one. I think it is ok to merge under assumption of simple polygons for the left-hand side driving checks, and performance can be improved later by using similar check with an interval tree. Another huge performance improvement is to avoid using
But i don't know atm the best way how to deal with the issue: may be create Lua tables in every context in advance, don't merge tables in c++ and provide an optional table of tags tables (it is possible to add also relation tags or any other "extension" tags into that table). So it is mainly a Lua interface question. |
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'm unclear on how the multi-file handling works, otherwise the code looks good.
However there is a big speedup potential for the point-in-polygon checks using quad-tree approximation (actually just removing most of the point-in-polygon checks).
} | ||
|
||
// Create R-tree for bounding boxes of collected polygons | ||
rtree = rtree_t(bounding_boxes); |
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.
Hrm I don't quite understand how this works with multiple input files: It seems to me on every call of this functions the rtree gets overwritten and all previous data is lost?
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.
🤦♂️ will be fixed
} | ||
else | ||
{ | ||
way_function(profile_table, way, result, toLua(state, location_dependent_data(way))); |
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.
Does this add any overhead when not giving any location dependent data as input (e.g. no geojson file)?
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.
empty data should handled in then
branch when rtree is empty, and no optional arguments will be passed to the lua function
}; | ||
|
||
// Search the R-tree and collect a Lua table of tags that correspond to the location | ||
rtree.query(boost::geometry::index::intersects(point) && |
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.
Instead of saving each polygon in one bounding box you could try a quad tree approximation:
- Divide the bounding box into 4 equal parts
- For every new box check if its fully container, fully outside or intersects the boundary
- If a box intersects the boundary: Continue dividing that box.
- Stop when all boxes are either fully in or fully out, or you reached a minimum box size (like 10x10m)
Now your query can terminate immediately when it hits a fully in/fully out bounding box. You only need to do the expensive point-in-polygon check on the points that hit the boundary boxes.
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 just stumbled upon some guidance profile decisions which depend on driving side here. I think it is missing from this changeset.
4dad3c3
to
480bc4a
Compare
For some reason envelop = make_inverse<box_t>(); boost::geometry::expand(envelop, next); normalizes longitude to [-180,180]
e407aa3
to
e59f95d
Compare
e59f95d
to
d644586
Compare
@TheMarex just checked the mean difference is 0.3 seconds or 5%
|
Issue
PR adds location-dependent tags and adds parsing
driving_side
tag.Location-dependent data is taken from a GeoJSON file (file name is an argument of a new extractor option
--location-dependent-data
) and provided as an optional argumentlocation_data
offunction process_way(profile, way, result, location_data)
. At the moment to use location-dependent data OSM files must be preprocessed withosmium add-locations-to-ways
.Left-hand driving flag is added to node-based-graph edges, edge-based-graph nodes and used in guidance pre-processing and in geospatial queries.
Some points to be discussed:
MultiPolygon
support?add-locations-to-ways
before parsing ways Country-aware way function #4167is_left_hand_driving
flag is indexed by EBG node ids, but it can be indexed by geometry ids. This will require an additional file that is indexed by geometry ids, but contains geometry non-segments data.vector<bool>
is stored as 8-bit per 1-bit value, is it a new issue?Tasklist
Requirements / Relations
Partially supersedes #4167