#ifndef POLYLINECOMPRESSOR_H_ #define POLYLINECOMPRESSOR_H_ #include "util/coordinate.hpp" #include #include #include #include namespace osrm { namespace engine { namespace detail { constexpr double POLYLINE_DECODING_PRECISION = 1e5; constexpr double POLYLINE_TO_COORDINATE = COORDINATE_PRECISION / POLYLINE_DECODING_PRECISION; std::string encode(std::vector &numbers); } using CoordVectorForwardIter = std::vector::const_iterator; // Encodes geometry into polyline format. // See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm template std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter end) { double coordinate_to_polyline = POLYLINE_PRECISION / COORDINATE_PRECISION; auto size = std::distance(begin, end); if (size == 0) { return {}; } std::vector delta_numbers; BOOST_ASSERT(size > 0); delta_numbers.reserve((size - 1) * 2); int current_lat = 0; int current_lon = 0; std::for_each( begin, end, [&delta_numbers, ¤t_lat, ¤t_lon, coordinate_to_polyline]( const util::Coordinate loc) { const int lat_diff = std::round(static_cast(loc.lat) * coordinate_to_polyline) - current_lat; const int lon_diff = std::round(static_cast(loc.lon) * coordinate_to_polyline) - current_lon; delta_numbers.emplace_back(lat_diff); delta_numbers.emplace_back(lon_diff); current_lat += lat_diff; current_lon += lon_diff; }); return detail::encode(delta_numbers); } // Decodes geometry from polyline format // See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm std::vector decodePolyline(const std::string &polyline); } } #endif /* POLYLINECOMPRESSOR_H_ */