forked from organicmaps/organicmaps-tmp
[coding] Add PointD <-> PointU encoding with limit rect.
This commit is contained in:
parent
c57e8235d2
commit
79a30871a5
3 changed files with 69 additions and 0 deletions
|
@ -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}};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
Loading…
Add table
Reference in a new issue