[coding] Add PointD <-> PointU encoding with limit rect.

This commit is contained in:
tatiana-yan 2019-09-25 12:23:24 +03:00 committed by mpimenov
parent c57e8235d2
commit 79a30871a5
3 changed files with 69 additions and 0 deletions

View file

@ -5,10 +5,14 @@
#include "coding/point_coding.hpp"
#include "geometry/mercator.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "base/logging.hpp"
#include "base/math.hpp"
#include <cmath>
#include <random>
using namespace std;
@ -72,6 +76,35 @@ UNIT_TEST(PointDToPointU_Epsilons)
}
}
UNIT_TEST(PointDToPointU_WithLimitRect)
{
mt19937 rng(0);
m2::PointD const limitRectOrigin[] = {{0.0, 0.0}, {10.0, 10.0}, {90.0, 90.0}, {160.0, 160.0}};
double const limitRectSize[] = {0.1, 1.0, 5.0, 10.0, 20.0};
size_t const pointsPerRect = 100;
for (auto const & origin : limitRectOrigin)
{
for (auto const size : limitRectSize)
{
m2::RectD const limitRect(origin.x, origin.y, origin.x + size, origin.y + size);
auto distX = uniform_real_distribution<double>(limitRect.minX(), limitRect.maxX());
auto distY = uniform_real_distribution<double>(limitRect.minY(), limitRect.maxY());
auto const coordBits = GetCoordBits(limitRect, kEps);
// All rects in this test are more than 2 times smaller than mercator range.
TEST_LESS(coordBits, kCoordBits, (limitRect));
for (size_t i = 0; i < pointsPerRect; ++i)
{
auto const pt = m2::PointD(distX(rng), distY(rng));
auto const pointU = PointDToPointU(pt, coordBits, limitRect);
auto const pointD = PointUToPointD(pointU, coordBits, limitRect);
TEST(base::AlmostEqualAbs(pt, pointD, kEps), (limitRect, pt, pointD, coordBits, kEps));
}
}
}
}
UNIT_TEST(PointToInt64Obsolete_Smoke)
{
m2::PointD const arr[] = {{1.25, 1.3}, {180, 90}, {-180, -90}, {0, 0}};

View file

@ -6,6 +6,8 @@
#include "base/bits.hpp"
#include "base/math.hpp"
#include <algorithm>
namespace
{
double CoordSize(uint8_t coordBits)
@ -51,6 +53,15 @@ m2::PointU PointDToPointU(m2::PointD const & pt, uint8_t coordBits)
return PointDToPointU(pt.x, pt.y, coordBits);
}
m2::PointU PointDToPointU(m2::PointD const & pt, uint8_t coordBits, m2::RectD const & limitRect)
{
ASSERT_GREATER_OR_EQUAL(coordBits, 1, ());
ASSERT_LESS_OR_EQUAL(coordBits, 32, ());
auto const x = DoubleToUint32(pt.x, limitRect.minX(), limitRect.maxX(), coordBits);
auto const y = DoubleToUint32(pt.y, limitRect.minY(), limitRect.maxY(), coordBits);
return m2::PointU(x, y);
}
m2::PointD PointUToPointD(m2::PointU const & pt, uint8_t coordBits)
{
return m2::PointD(static_cast<double>(pt.x) * MercatorBounds::kRangeX / CoordSize(coordBits) +
@ -59,6 +70,24 @@ m2::PointD PointUToPointD(m2::PointU const & pt, uint8_t coordBits)
MercatorBounds::kMinY);
}
m2::PointD PointUToPointD(m2::PointU const & pt, uint8_t coordBits, m2::RectD const & limitRect)
{
return m2::PointD(Uint32ToDouble(pt.x, limitRect.minX(), limitRect.maxX(), coordBits),
Uint32ToDouble(pt.y, limitRect.minY(), limitRect.maxY(), coordBits));
}
uint8_t GetCoordBits(m2::RectD const & limitRect, double accuracy)
{
auto const range = std::max(limitRect.SizeX(), limitRect.SizeY());
auto const valuesNumber = 1.0 + range / accuracy;
for (uint8_t coordBits = 1; coordBits <= 32; ++coordBits)
{
if (CoordSize(coordBits) >= valuesNumber)
return coordBits;
}
return 0;
}
// Obsolete functions ------------------------------------------------------------------------------
int64_t PointToInt64Obsolete(double x, double y, uint8_t coordBits)

View file

@ -44,8 +44,15 @@ m2::PointU PointDToPointU(double x, double y, uint8_t coordBits);
m2::PointU PointDToPointU(m2::PointD const & pt, uint8_t coordBits);
m2::PointU PointDToPointU(m2::PointD const & pt, uint8_t coordBits, m2::RectD const & limitRect);
m2::PointD PointUToPointD(m2::PointU const & p, uint8_t coordBits);
m2::PointD PointUToPointD(m2::PointU const & pt, uint8_t coordBits, m2::RectD const & limitRect);
// Returns coordBits needed to encode point from given rect with given accuracy.
uint8_t GetCoordBits(m2::RectD const & limitRect, double accuracy);
// All functions below are deprecated and are left
// only for backward compatibility.
//