Fix key/val offset bug.

This commit is contained in:
Daniel Patterson 2016-11-08 02:47:19 -08:00
parent 481b03baeb
commit cef53c4b56
2 changed files with 330 additions and 5 deletions

View File

@ -621,6 +621,22 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<datafacade::BaseDataFacad
line_layer_writer.add_uint32(util::vector_tile::EXTENT_TAG,
util::vector_tile::EXTENT); // extent
// Because we need to know the indexes into the vector tile lookup table,
// we need to do an initial pass over the data and create the complete
// index of used values.
for (const auto &edge : edges)
{
const auto forward_weight_vector =
facade->GetUncompressedForwardWeights(edge.packed_geometry_id);
const auto reverse_weight_vector =
facade->GetUncompressedReverseWeights(edge.packed_geometry_id);
const auto forward_weight = forward_weight_vector[edge.fwd_segment_position];
const auto reverse_weight = reverse_weight_vector[reverse_weight_vector.size() -
edge.fwd_segment_position - 1];
use_line_value(reverse_weight);
use_line_value(forward_weight);
}
// Begin the layer features block
{
// Each feature gets a unique id, starting at 1
@ -652,21 +668,18 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<datafacade::BaseDataFacad
reverse_datasource_vector[reverse_datasource_vector.size() -
edge.fwd_segment_position - 1];
use_line_value(reverse_weight);
use_line_value(forward_weight);
std::string name = facade->GetNameForID(edge.name_id);
const auto name_offset = [&name, &names, &name_offsets]() {
auto iter = name_offsets.find(name);
if (iter == name_offsets.end())
{
auto offset = names.size() - 1;
auto offset = names.size();
name_offsets[name] = offset;
names.push_back(std::move(name));
return offset;
}
return iter->second;
}();
names.push_back(std::move(name));
const auto encode_tile_line = [&line_layer_writer,
&edge,

View File

@ -208,4 +208,316 @@ BOOST_AUTO_TEST_CASE(test_tile)
BOOST_CHECK_EQUAL(number_of_turns_found, 732);
}
BOOST_AUTO_TEST_CASE(test_tile_turns)
{
const auto args = get_args();
auto osrm = getOSRM(args.at(0));
using namespace osrm;
// Small tile where we can test all the values
TileParameters params{272953, 191177, 19};
std::string result;
const auto rc = osrm.Tile(params, result);
BOOST_CHECK(rc == Status::Ok);
BOOST_CHECK_GT(result.size(), 128);
protozero::pbf_reader tile_message(result);
tile_message.next();
BOOST_CHECK_EQUAL(tile_message.tag(), util::vector_tile::LAYER_TAG); // must be a layer
// Skip the segments layer
tile_message.skip();
tile_message.next();
auto layer_message = tile_message.get_message();
std::vector<int> found_bearing_in_indexes;
std::vector<int> found_turn_angles_indexes;
std::vector<int> found_penalties_indexes;
const auto check_turn_feature = [&](protozero::pbf_reader feature_message) {
feature_message.next(); // advance parser to first entry
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG);
BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_POINT);
feature_message.next(); // advance to next entry
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG);
feature_message.get_uint64(); // id
feature_message.next(); // advance to next entry
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG);
// properties
auto feature_iter_pair = feature_message.get_packed_uint32();
BOOST_CHECK_EQUAL(std::distance(feature_iter_pair.begin(), feature_iter_pair.end()), 6);
auto iter = feature_iter_pair.begin();
BOOST_CHECK_EQUAL(*iter++, 0); // bearing_in key
found_bearing_in_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 1); // turn_angle key
found_turn_angles_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 2); // cost key
found_penalties_indexes.push_back(*iter++); // skip value check, can be valud uint32
BOOST_CHECK(iter == feature_iter_pair.end());
// geometry
feature_message.next();
auto geometry_iter_pair = feature_message.get_packed_uint32();
BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1);
};
std::unordered_map<int, float> float_vals;
std::unordered_map<int, std::int64_t> sint64_vals;
int kv_index = 0;
const auto check_value = [&](protozero::pbf_reader value) {
while (value.next())
{
switch (value.tag())
{
case util::vector_tile::VARIANT_TYPE_FLOAT:
float_vals[kv_index] = value.get_float();
break;
case util::vector_tile::VARIANT_TYPE_SINT64:
sint64_vals[kv_index] = value.get_sint64();
break;
default:
BOOST_CHECK(false);
}
kv_index++;
}
};
auto number_of_turn_keys = 0u;
auto number_of_turns_found = 0u;
while (layer_message.next())
{
switch (layer_message.tag())
{
case util::vector_tile::VERSION_TAG:
BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2);
break;
case util::vector_tile::NAME_TAG:
BOOST_CHECK_EQUAL(layer_message.get_string(), "turns");
break;
case util::vector_tile::EXTENT_TAG:
BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT);
break;
case util::vector_tile::FEATURE_TAG:
check_turn_feature(layer_message.get_message());
number_of_turns_found++;
break;
case util::vector_tile::KEY_TAG:
layer_message.get_string();
number_of_turn_keys++;
break;
case util::vector_tile::VARIANT_TAG:
check_value(layer_message.get_message());
break;
default:
BOOST_CHECK(false); // invalid tag
break;
}
}
// Verify that we got the expected turn penalties
std::vector<float> actual_turn_penalties;
for (const auto &i : found_penalties_indexes)
{
BOOST_CHECK(float_vals.count(i) == 1);
actual_turn_penalties.push_back(float_vals[i]);
}
std::sort(actual_turn_penalties.begin(), actual_turn_penalties.end());
const std::vector<float> expected_turn_penalties = {
0, 0, 0, 0, 0, 0, 0.1, 0.1, 0.3, 0.4, 1.3, 1.8, 5.4, 5.5, 5.8, 7.1, 7.2, 7.2};
BOOST_CHECK(actual_turn_penalties == expected_turn_penalties);
// Verify the expected turn angles
std::vector<std::int64_t> actual_turn_angles;
for (const auto &i : found_turn_angles_indexes)
{
BOOST_CHECK(sint64_vals.count(i) == 1);
actual_turn_angles.push_back(sint64_vals[i]);
}
std::sort(actual_turn_angles.begin(), actual_turn_angles.end());
const std::vector<std::int64_t> expected_turn_angles = {
-123, -120, -118, -64, -57, -29, -28, -3, -2, 2, 3, 28, 29, 57, 64, 118, 120, 123};
BOOST_CHECK(actual_turn_angles == expected_turn_angles);
// Verify the expected bearings
std::vector<std::int64_t> actual_turn_bearings;
for (const auto &i : found_bearing_in_indexes)
{
BOOST_CHECK(sint64_vals.count(i) == 1);
actual_turn_bearings.push_back(sint64_vals[i]);
}
std::sort(actual_turn_bearings.begin(), actual_turn_bearings.end());
const std::vector<std::int64_t> expected_turn_bearings = {
49, 49, 106, 106, 169, 169, 171, 171, 229, 229, 258, 258, 287, 287, 349, 349, 352, 352};
BOOST_CHECK(actual_turn_bearings == expected_turn_bearings);
}
BOOST_AUTO_TEST_CASE(test_tile_speeds)
{
const auto args = get_args();
auto osrm = getOSRM(args.at(0));
using namespace osrm;
// Small tile so we can test all the values
// TileParameters params{272953, 191177, 19};
TileParameters params{136477, 95580, 18};
std::string result;
const auto rc = osrm.Tile(params, result);
BOOST_CHECK(rc == Status::Ok);
BOOST_CHECK_GT(result.size(), 128);
protozero::pbf_reader tile_message(result);
tile_message.next();
BOOST_CHECK_EQUAL(tile_message.tag(), util::vector_tile::LAYER_TAG); // must be a layer
protozero::pbf_reader layer_message = tile_message.get_message();
std::vector<int> found_speed_indexes;
std::vector<int> found_component_indexes;
std::vector<int> found_datasource_indexes;
std::vector<int> found_duration_indexes;
std::vector<int> found_name_indexes;
const auto check_feature = [&](protozero::pbf_reader feature_message) {
feature_message.next(); // advance parser to first entry
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG);
BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_LINE);
feature_message.next(); // advance to next entry
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG);
feature_message.get_uint64(); // id
feature_message.next(); // advance to next entry
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG);
// properties
auto property_iter_pair = feature_message.get_packed_uint32();
auto value_begin = property_iter_pair.begin();
auto value_end = property_iter_pair.end();
BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 10);
auto iter = value_begin;
BOOST_CHECK_EQUAL(*iter++, 0); // speed key
found_speed_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 1); // component key
// component value
found_component_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 2); // data source key
found_datasource_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 3); // duration key
found_duration_indexes.push_back(*iter++);
// name
BOOST_CHECK_EQUAL(*iter++, 4);
found_name_indexes.push_back(*iter++);
BOOST_CHECK(iter == value_end);
// geometry
feature_message.next();
auto geometry_iter_pair = feature_message.get_packed_uint32();
BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1);
};
std::unordered_map<int, std::string> string_vals;
std::unordered_map<int, bool> bool_vals;
std::unordered_map<int, std::uint64_t> uint64_vals;
std::unordered_map<int, double> double_vals;
int kv_index = 0;
const auto check_value = [&](protozero::pbf_reader value) {
while (value.next())
{
switch (value.tag())
{
case util::vector_tile::VARIANT_TYPE_BOOL:
bool_vals[kv_index] = value.get_bool();
break;
case util::vector_tile::VARIANT_TYPE_DOUBLE:
double_vals[kv_index] = value.get_double();
break;
case util::vector_tile::VARIANT_TYPE_FLOAT:
value.get_float();
break;
case util::vector_tile::VARIANT_TYPE_STRING:
string_vals[kv_index] = value.get_string();
break;
case util::vector_tile::VARIANT_TYPE_UINT64:
uint64_vals[kv_index] = value.get_uint64();
break;
case util::vector_tile::VARIANT_TYPE_SINT64:
value.get_sint64();
break;
}
kv_index++;
}
};
auto number_of_speed_keys = 0u;
auto number_of_speed_values = 0u;
while (layer_message.next())
{
switch (layer_message.tag())
{
case util::vector_tile::VERSION_TAG:
BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2);
break;
case util::vector_tile::NAME_TAG:
BOOST_CHECK_EQUAL(layer_message.get_string(), "speeds");
break;
case util::vector_tile::EXTENT_TAG:
BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT);
break;
case util::vector_tile::FEATURE_TAG:
check_feature(layer_message.get_message());
break;
case util::vector_tile::KEY_TAG:
layer_message.get_string();
number_of_speed_keys++;
break;
case util::vector_tile::VARIANT_TAG:
check_value(layer_message.get_message());
number_of_speed_values++;
break;
default:
BOOST_CHECK(false); // invalid tag
break;
}
}
std::vector<std::string> actual_names;
for (const auto &i : found_name_indexes)
{
BOOST_CHECK(string_vals.count(i) == 1);
actual_names.push_back(string_vals[i]);
}
std::sort(actual_names.begin(), actual_names.end());
const std::vector<std::string> expected_names = {"Avenue du Carnier",
"Avenue du Carnier",
"Avenue du Carnier",
"Avenue du Carnier",
"Avenue du Carnier",
"Avenue du Maréchal Foch",
"Avenue du Maréchal Foch",
"Avenue du Maréchal Foch",
"Avenue du Maréchal Foch",
"Avenue du Maréchal Foch",
"Avenue du Maréchal Foch",
"Avenue du Professeur Langevin",
"Avenue du Professeur Langevin",
"Avenue du Professeur Langevin",
"Montée de la Crémaillère",
"Montée de la Crémaillère",
"Rue Jules Ferry",
"Rue Jules Ferry",
"Rue Professeur Calmette",
"Rue Professeur Calmette"};
BOOST_CHECK(actual_names == expected_names);
}
BOOST_AUTO_TEST_SUITE_END()