diff --git a/indexer/geometry_coding.cpp b/indexer/geometry_coding.cpp index 74a83b0a11..cf0d36487e 100644 --- a/indexer/geometry_coding.cpp +++ b/indexer/geometry_coding.cpp @@ -1,8 +1,6 @@ #include "geometry_coding.hpp" #include "../coding/byte_stream.hpp" -#include "../coding/varint.hpp" #include "../base/assert.hpp" -#include "../base/bits.hpp" #include "../base/stl_add.hpp" #include "../std/complex.hpp" #include "../std/vector.hpp" @@ -10,20 +8,6 @@ namespace { -inline uint64_t EncodeDelta(m2::PointU const & actual, m2::PointU const & prediction) -{ - return bits::BitwiseMerge( - bits::ZigZagEncode(static_cast(actual.x) - static_cast(prediction.x)), - bits::ZigZagEncode(static_cast(actual.y) - static_cast(prediction.y))); -} - -inline m2::PointU DecodeDelta(uint64_t delta, m2::PointU const & prediction) -{ - uint32_t x, y; - bits::BitwiseSplit(delta, x, y); - return m2::PointU(prediction.x + bits::ZigZagDecode(x), prediction.y + bits::ZigZagDecode(y)); -} - inline void EncodeVarUints(vector const & varints, vector & serialOutput) { PushBackByteSink > sink(serialOutput); diff --git a/indexer/geometry_coding.hpp b/indexer/geometry_coding.hpp index 8de007c512..db81b460a7 100644 --- a/indexer/geometry_coding.hpp +++ b/indexer/geometry_coding.hpp @@ -1,10 +1,26 @@ #pragma once #include "../geometry/point2d.hpp" +#include "../coding/varint.hpp" #include "../base/base.hpp" +#include "../base/bits.hpp" #include "../std/vector.hpp" #include "../std/tuple.hpp" +inline uint64_t EncodeDelta(m2::PointU const & actual, m2::PointU const & prediction) +{ + return bits::BitwiseMerge( + bits::ZigZagEncode(static_cast(actual.x) - static_cast(prediction.x)), + bits::ZigZagEncode(static_cast(actual.y) - static_cast(prediction.y))); +} + +inline m2::PointU DecodeDelta(uint64_t delta, m2::PointU const & prediction) +{ + uint32_t x, y; + bits::BitwiseSplit(delta, x, y); + return m2::PointU(prediction.x + bits::ZigZagDecode(x), prediction.y + bits::ZigZagDecode(y)); +} + // Predict point p0 given previous (p1, p2). m2::PointU PredictPointInPolyline(m2::PointU const & maxPoint, m2::PointU const & p1, diff --git a/indexer/indexer_tests/geometry_coding_test.cpp b/indexer/indexer_tests/geometry_coding_test.cpp index e3f97e92ec..1131e2f96e 100644 --- a/indexer/indexer_tests/geometry_coding_test.cpp +++ b/indexer/indexer_tests/geometry_coding_test.cpp @@ -3,10 +3,32 @@ #include "../../geometry/geometry_tests/large_polygon.hpp" #include "../../geometry/distance.hpp" #include "../../geometry/simplification.hpp" +#include "../../coding/byte_stream.hpp" +#include "../../coding/varint.hpp" #include "../../base/logging.hpp" typedef m2::PointU PU; +UNIT_TEST(EncodeDelta) +{ + for (int x = -100; x <= 100; ++x) + { + for (int y = -100; y <= 100; ++y) + { + PU orig = PU(100 + x, 100 + y); + PU pred = PU(100, 100); + TEST_EQUAL(orig, DecodeDelta(EncodeDelta(orig, pred), pred), ()); + vector data; + PushBackByteSink > sink(data); + WriteVarUint(sink, EncodeDelta(orig, pred)); + size_t expectedSize = 1; + if (x >= 8 || x < -8 || y >= 4 || y < -4) expectedSize = 2; + if (x >= 64 || x < -64 || y >= 64 || y < -64) expectedSize = 3; + TEST_EQUAL(data.size(), expectedSize, (x, y)); + } + } +} + UNIT_TEST(PredictPointsInPolyline2) { TEST_EQUAL(PU(7, 6), PredictPointInPolyline(PU(8, 7), PU(4, 4), PU(1, 2)), ()); @@ -36,7 +58,6 @@ UNIT_TEST(PredictPointsInPolyline3_SquareClamp0) TEST_EQUAL(PU(4, 0), PredictPointInPolyline(PU(6, 6), PU(2, 0), PU(3, 2), PU(5, 1)), ()); } - UNIT_TEST(PredictPointsInPolyline3_90deg) { TEST_EQUAL(PU(3, 2), PredictPointInPolyline(PU(8, 8), PU(3, 6), PU(1, 6), PU(1, 5)), ()); @@ -45,7 +66,7 @@ UNIT_TEST(PredictPointsInPolyline3_90deg) namespace { -void TestPolylineEncode(char const * testName, +void TestPolylineEncode(string testName, vector const & points, m2::PointU const & maxPoint, void (* fnEncode)(vector const & points, @@ -78,11 +99,11 @@ vector SimplifyPoints(vector const & points, double eps) return simpPoints; } -void TestEncodePolyline(char const * name, m2::PointU maxPoint, vector const & points) +void TestEncodePolyline(string name, m2::PointU maxPoint, vector const & points) { - TestPolylineEncode(name, points, maxPoint, &EncodePolylinePrev1, &DecodePolylinePrev1); - TestPolylineEncode(name, points, maxPoint, &EncodePolylinePrev2, &DecodePolylinePrev2); - TestPolylineEncode(name, points, maxPoint, &EncodePolylinePrev3, &DecodePolylinePrev3); + TestPolylineEncode(name + "1", points, maxPoint, &EncodePolylinePrev1, &DecodePolylinePrev1); + TestPolylineEncode(name + "2", points, maxPoint, &EncodePolylinePrev2, &DecodePolylinePrev2); + TestPolylineEncode(name + "3", points, maxPoint, &EncodePolylinePrev3, &DecodePolylinePrev3); } }