Skip to content

Commit e327632

Browse files
authored
Include 'rate' property (reciprocal of weight) on debug tile edges. (#4162)
Include 'rate' property (reciprocal of weight) on debug tile edges and add turn weight data to debug tiles.
1 parent f80e5db commit e327632

File tree

4 files changed

+131
-58
lines changed

4 files changed

+131
-58
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
- #4075 Changed counting of exits on service roundabouts
2121
- Debug Tiles
2222
- added support for visualising turn penalties to the MLD plugin
23+
- added support for showing the rate (reciprocal of weight) on each edge when used
24+
- added support for turn weights in addition to turn durations in debug tiles
2325
- Bugfixes
2426
- Fixed a copy/paste issue assigning wrong directions in similar turns (left over right)
2527
- #4074: fixed a bug that would announce entering highway ramps as u-turns

docs/http.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,10 @@ Vector tiles contain two layers:
419419
| `speed` | `integer` | the speed on that road segment, in km/h |
420420
| `is_small` | `boolean` | whether this segment belongs to a small (< 1000 node) [strongly connected component](https://en.wikipedia.org/wiki/Strongly_connected_component) |
421421
| `datasource` | `string` | the source for the speed value (normally `lua profile` unless you're using the [traffic update feature](https://github.com/Project-OSRM/osrm-backend/wiki/Traffic), in which case it contains the stem of the filename that supplied the speed value for this segment |
422-
| `duration` | `float` | how long this segment takes to traverse, in seconds |
422+
| `duration` | `float` | how long this segment takes to traverse, in seconds. This value is to calculate the total route ETA. |
423+
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
423424
| `name` | `string` | the name of the road this segment belongs to |
425+
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
424426

425427
`turns` layer:
426428

@@ -429,6 +431,7 @@ Vector tiles contain two layers:
429431
| `bearing_in` | `integer` | the absolute bearing that approaches the intersection. -180 to +180, 0 = North, 90 = East |
430432
| `turn_angle` | `integer` | the angle of the turn, relative to the `bearing_in`. -180 to +180, 0 = straight ahead, 90 = 90-degrees to the right |
431433
| `cost` | `float` | the time we think it takes to make that turn, in seconds. May be negative, depending on how the data model is constructed (some turns get a "bonus"). |
434+
| `weight` | `float` | the weight we think it takes to make that turn. May be negative, depending on how the data model is constructed (some turns get a "bonus"). ACTUAL ROUTING USES THIS VALUE |
432435

433436

434437
## Result objects

src/engine/plugins/tile.cpp

Lines changed: 84 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,12 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
428428
const auto &edge = edges[edge_index];
429429
const auto geometry_id = get_geometry_id(edge);
430430

431+
// Get coordinates for start/end nodes of segment (NodeIDs u and v)
432+
const auto a = facade.GetCoordinateOfNode(edge.u);
433+
const auto b = facade.GetCoordinateOfNode(edge.v);
434+
// Calculate the length in meters
435+
const double length = osrm::util::coordinate_calculation::haversineDistance(a, b);
436+
431437
// Weight values
432438
const auto forward_weight_vector =
433439
facade.GetUncompressedForwardWeights(geometry_id);
@@ -439,6 +445,14 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
439445
use_line_value(forward_weight);
440446
use_line_value(reverse_weight);
441447

448+
std::uint32_t forward_rate =
449+
static_cast<std::uint32_t>(round(length / forward_weight * 10.));
450+
std::uint32_t reverse_rate =
451+
static_cast<std::uint32_t>(round(length / reverse_weight * 10.));
452+
453+
use_line_value(forward_rate);
454+
use_line_value(reverse_rate);
455+
442456
// Duration values
443457
const auto forward_duration_vector =
444458
facade.GetUncompressedForwardDurations(geometry_id);
@@ -489,9 +503,9 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
489503
const auto reverse_duration =
490504
reverse_duration_vector[reverse_duration_vector.size() -
491505
edge.fwd_segment_position - 1];
492-
const auto forward_datasource =
506+
const auto forward_datasource_idx =
493507
forward_datasource_vector[edge.fwd_segment_position];
494-
const auto reverse_datasource =
508+
const auto reverse_datasource_idx =
495509
reverse_datasource_vector[reverse_datasource_vector.size() -
496510
edge.fwd_segment_position - 1];
497511

@@ -516,14 +530,16 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
516530
&component_id,
517531
&id,
518532
&max_datasource_id,
519-
&used_line_ints](const FixedLine &tile_line,
520-
const std::uint32_t speed_kmh,
521-
const std::size_t weight,
522-
const std::size_t duration,
523-
const DatasourceID datasource,
524-
const std::size_t name_idx,
525-
std::int32_t &start_x,
526-
std::int32_t &start_y) {
533+
&used_line_ints](
534+
const FixedLine &tile_line,
535+
const std::uint32_t speed_kmh_idx,
536+
const std::uint32_t rate_idx,
537+
const std::size_t weight_idx,
538+
const std::size_t duration_idx,
539+
const DatasourceID datasource_idx,
540+
const std::size_t name_idx,
541+
std::int32_t &start_x,
542+
std::int32_t &start_y) {
527543
// Here, we save the two attributes for our feature: the speed and
528544
// the is_small boolean. We only serve up speeds from 0-139, so all we
529545
// do is save the first
@@ -547,23 +563,27 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
547563
feature_writer, util::vector_tile::FEATURE_ATTRIBUTES_TAG);
548564

549565
field.add_element(0); // "speed" tag key offset
566+
field.add_element(std::min(
567+
speed_kmh_idx, 127u)); // save the speed value, capped at 127
568+
field.add_element(1); // "is_small" tag key offset
550569
field.add_element(
551-
std::min(speed_kmh, 127u)); // save the speed value, capped at 127
552-
field.add_element(1); // "is_small" tag key offset
553-
field.add_element(128 +
554-
(component_id.is_tiny ? 0 : 1)); // is_small feature
555-
field.add_element(2); // "datasource" tag key offset
556-
field.add_element(130 + datasource); // datasource value offset
557-
field.add_element(3); // "weight" tag key offset
570+
128 + (component_id.is_tiny ? 0 : 1)); // is_small feature offset
571+
field.add_element(2); // "datasource" tag key offset
572+
field.add_element(130 + datasource_idx); // datasource value offset
573+
field.add_element(3); // "weight" tag key offset
558574
field.add_element(130 + max_datasource_id + 1 +
559-
weight); // weight value offset
560-
field.add_element(4); // "duration" tag key offset
575+
weight_idx); // weight value offset
576+
field.add_element(4); // "duration" tag key offset
561577
field.add_element(130 + max_datasource_id + 1 +
562-
duration); // duration value offset
563-
field.add_element(5); // "name" tag key offset
578+
duration_idx); // duration value offset
579+
field.add_element(5); // "name" tag key offset
564580

565581
field.add_element(130 + max_datasource_id + 1 + used_line_ints.size() +
566582
name_idx); // name value offset
583+
584+
field.add_element(6); // rate tag key offset
585+
field.add_element(130 + max_datasource_id + 1 +
586+
rate_idx); // rate goes in used_line_ints
567587
}
568588
{
569589

@@ -581,17 +601,26 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
581601
std::int32_t start_y = 0;
582602

583603
// Calculate the speed for this line
584-
std::uint32_t speed_kmh =
604+
// Speeds are looked up in a simple 1:1 table, so the speed value == lookup
605+
// table index
606+
std::uint32_t speed_kmh_idx =
585607
static_cast<std::uint32_t>(round(length / forward_duration * 10 * 3.6));
586608

609+
// Rate values are in meters per weight-unit - and similar to speeds, we
610+
// present 1 decimal place of precision (these values are added as
611+
// double/10) lower down
612+
std::uint32_t forward_rate =
613+
static_cast<std::uint32_t>(round(length / forward_weight * 10.));
614+
587615
auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
588616
if (!tile_line.empty())
589617
{
590618
encode_tile_line(tile_line,
591-
speed_kmh,
619+
speed_kmh_idx,
620+
line_int_offsets[forward_rate],
592621
line_int_offsets[forward_weight],
593622
line_int_offsets[forward_duration],
594-
forward_datasource,
623+
forward_datasource_idx,
595624
name_offset,
596625
start_x,
597626
start_y);
@@ -606,17 +635,26 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
606635
std::int32_t start_y = 0;
607636

608637
// Calculate the speed for this line
609-
std::uint32_t speed_kmh =
638+
// Speeds are looked up in a simple 1:1 table, so the speed value == lookup
639+
// table index
640+
std::uint32_t speed_kmh_idx =
610641
static_cast<std::uint32_t>(round(length / reverse_duration * 10 * 3.6));
611642

643+
// Rate values are in meters per weight-unit - and similar to speeds, we
644+
// present 1 decimal place of precision (these values are added as
645+
// double/10) lower down
646+
std::uint32_t reverse_rate =
647+
static_cast<std::uint32_t>(round(length / reverse_weight * 10.));
648+
612649
auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
613650
if (!tile_line.empty())
614651
{
615652
encode_tile_line(tile_line,
616-
speed_kmh,
653+
speed_kmh_idx,
654+
line_int_offsets[reverse_rate],
617655
line_int_offsets[reverse_weight],
618656
line_int_offsets[reverse_duration],
619-
reverse_datasource,
657+
reverse_datasource_idx,
620658
name_offset,
621659
start_x,
622660
start_y);
@@ -634,6 +672,7 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
634672
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "weight");
635673
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "duration");
636674
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "name");
675+
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "rate");
637676

638677
// Now, we write out the possible speed value arrays and possible is_tiny
639678
// values. Field type 4 is the "values" field. It's a variable type field,
@@ -695,19 +734,21 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
695734
{
696735
// we need to pre-encode all values here because we need the full offsets later
697736
// for encoding the actual features.
698-
std::vector<std::tuple<util::Coordinate, unsigned, unsigned, unsigned>>
737+
std::vector<std::tuple<util::Coordinate, unsigned, unsigned, unsigned, unsigned>>
699738
encoded_turn_data(all_turn_data.size());
700-
std::transform(
701-
all_turn_data.begin(),
702-
all_turn_data.end(),
703-
encoded_turn_data.begin(),
704-
[&](const routing_algorithms::TurnData &t) {
705-
auto angle_idx = use_point_int_value(t.in_angle);
706-
auto turn_idx = use_point_int_value(t.turn_angle);
707-
auto duration_idx =
708-
use_point_float_value(t.duration / 10.0); // Note conversion to float here
709-
return std::make_tuple(t.coordinate, angle_idx, turn_idx, duration_idx);
710-
});
739+
std::transform(all_turn_data.begin(),
740+
all_turn_data.end(),
741+
encoded_turn_data.begin(),
742+
[&](const routing_algorithms::TurnData &t) {
743+
auto angle_idx = use_point_int_value(t.in_angle);
744+
auto turn_idx = use_point_int_value(t.turn_angle);
745+
auto duration_idx = use_point_float_value(
746+
t.duration / 10.0); // Note conversion to float here
747+
auto weight_idx = use_point_float_value(
748+
t.weight / 10.0); // Note conversion to float here
749+
return std::make_tuple(
750+
t.coordinate, angle_idx, turn_idx, duration_idx, weight_idx);
751+
});
711752

712753
// Now write the points layer for turn penalty data:
713754
// Add a layer object to the PBF stream. 3=='layer' from the vector tile spec
@@ -734,7 +775,7 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
734775
util::vector_tile::GEOMETRY_TYPE_POINT); // geometry type
735776
feature_writer.add_uint64(util::vector_tile::ID_TAG, id++); // id
736777
{
737-
// Write out the 3 properties we want on the feature. These
778+
// Write out the 4 properties we want on the feature. These
738779
// refer to indexes in the properties lookup table, which we
739780
// add to the tile after we add all features.
740781
protozero::packed_field_uint32 field(
@@ -745,6 +786,8 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
745786
field.add_element(std::get<2>(point_turn_data));
746787
field.add_element(2); // "cost" tag key offset
747788
field.add_element(used_point_ints.size() + std::get<3>(point_turn_data));
789+
field.add_element(3); // "weight" tag key offset
790+
field.add_element(used_point_ints.size() + std::get<4>(point_turn_data));
748791
}
749792
{
750793
// Add the geometry as the last field in this feature
@@ -772,6 +815,7 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
772815
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "bearing_in");
773816
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "turn_angle");
774817
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "cost");
818+
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "weight");
775819

776820
// Now, save the lists of integers and floats that our features refer to.
777821
for (const auto &value : used_point_ints)

0 commit comments

Comments
 (0)