Optimise encodePolyline function

This commit is contained in:
Siarhei Fedartsou 2024-06-10 19:46:26 +02:00
parent e8da3d9231
commit 727b031d45
2 changed files with 29 additions and 47 deletions

View File

@ -12,7 +12,7 @@ namespace osrm::engine
{ {
namespace detail namespace detail
{ {
std::string encode(std::vector<int> &numbers); void encode(int number_to_encode, std::string &output);
std::int32_t decode_polyline_integer(std::string::const_iterator &first, std::int32_t decode_polyline_integer(std::string::const_iterator &first,
std::string::const_iterator last); std::string::const_iterator last);
} // namespace detail } // namespace detail
@ -30,27 +30,24 @@ std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter
return {}; return {};
} }
std::vector<int> delta_numbers; std::string output;
BOOST_ASSERT(size > 0); // just a guess that we will need ~4 bytes per coordinate to avoid reallocations
delta_numbers.reserve((size - 1) * 2); output.reserve(size * 4);
int current_lat = 0; int current_lat = 0;
int current_lon = 0; int current_lon = 0;
std::for_each( for (auto it = begin; it != end; ++it)
begin,
end,
[&delta_numbers, &current_lat, &current_lon, coordinate_to_polyline](
const util::Coordinate loc)
{ {
const int lat_diff = const int lat_diff =
std::round(static_cast<int>(loc.lat) * coordinate_to_polyline) - current_lat; std::round(static_cast<int>(it->lat) * coordinate_to_polyline) - current_lat;
const int lon_diff = const int lon_diff =
std::round(static_cast<int>(loc.lon) * coordinate_to_polyline) - current_lon; std::round(static_cast<int>(it->lon) * coordinate_to_polyline) - current_lon;
delta_numbers.emplace_back(lat_diff); detail::encode(lat_diff, output);
delta_numbers.emplace_back(lon_diff); detail::encode(lon_diff, output);
current_lat += lat_diff; current_lat += lat_diff;
current_lon += lon_diff; current_lon += lon_diff;
}); }
return detail::encode(delta_numbers); return output;
} }
// Decodes geometry from polyline format // Decodes geometry from polyline format

View File

@ -10,9 +10,19 @@
namespace osrm::engine::detail // anonymous to keep TU local namespace osrm::engine::detail // anonymous to keep TU local
{ {
std::string encode(int number_to_encode) void encode(int number_to_encode, std::string &output)
{ {
std::string output; if (number_to_encode < 0)
{
const unsigned binary = std::llabs(number_to_encode);
const unsigned twos = (~binary) + 1u;
const unsigned shl = twos << 1u;
number_to_encode = static_cast<int>(~shl);
}
else
{
number_to_encode <<= 1u;
}
while (number_to_encode >= 0x20) while (number_to_encode >= 0x20)
{ {
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63; const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
@ -22,31 +32,6 @@ std::string encode(int number_to_encode)
number_to_encode += 63; number_to_encode += 63;
output += static_cast<char>(number_to_encode); output += static_cast<char>(number_to_encode);
return output;
}
std::string encode(std::vector<int> &numbers)
{
std::string output;
for (auto &number : numbers)
{
if (number < 0)
{
const unsigned binary = std::llabs(number);
const unsigned twos = (~binary) + 1u;
const unsigned shl = twos << 1u;
number = static_cast<int>(~shl);
}
else
{
number <<= 1u;
}
}
for (const int number : numbers)
{
output += encode(number);
}
return output;
} }
// https://developers.google.com/maps/documentation/utilities/polylinealgorithm // https://developers.google.com/maps/documentation/utilities/polylinealgorithm