Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)

To expand with full Organic Maps and Maps.ME commits history run:
  git remote add om-historic [om-historic.git repo url]
  git fetch --tags om-historic
  git replace squashed-history historic-commits
This commit is contained in:
Konstantin Pastbin
2025-04-13 16:37:30 +07:00
commit e3e4a1985a
12931 changed files with 13195100 additions and 0 deletions

148
coding/point_coding.cpp Normal file
View File

@@ -0,0 +1,148 @@
#include "coding/point_coding.hpp"
#include "geometry/mercator.hpp"
#include "base/assert.hpp"
#include "base/bits.hpp"
#include <algorithm>
namespace
{
double CoordSize(uint8_t coordBits)
{
ASSERT(coordBits >= 1 && coordBits <= 32, (coordBits));
return static_cast<double>((uint64_t{1} << coordBits) - 1);
}
} // namespace
uint32_t DoubleToUint32(double x, double min, double max, uint8_t coordBits)
{
ASSERT_LESS_OR_EQUAL(min, max, ());
double const coordSize = CoordSize(coordBits);
// Expand checks to avoid NANs when min == max.
double d;
if (x <= min)
d = 0;
else if (x >= max)
d = coordSize;
else
d = (x - min) / (max - min) * coordSize;
// Check in case of NANs.
ASSERT(d >= 0 && d <= coordSize, (d, x, min, max, coordBits));
return static_cast<uint32_t>(0.5 + d);
}
double Uint32ToDouble(uint32_t x, double min, double max, uint8_t coordBits)
{
ASSERT_LESS_OR_EQUAL(min, max, ());
double const coordSize = CoordSize(coordBits);
auto const d = min + static_cast<double>(x) * (max - min) / coordSize;
// It doesn't work now because of fancy serialization of m2::DiamondBox.
/// @todo Check PathsThroughLayers search test. Refactor CitiesBoundariesSerDes.
//ASSERT_LESS_OR_EQUAL(x, coordSize, (d, min, max, coordBits));
// It doesn't work because of possible floating errors.
//ASSERT(d >= min && d <= max, (d, x, min, max, coordBits));
return base::Clamp(d, min, max);
}
m2::PointU PointDToPointU(double x, double y, uint8_t coordBits)
{
using mercator::Bounds;
return { DoubleToUint32(x, Bounds::kMinX, Bounds::kMaxX, coordBits),
DoubleToUint32(y, Bounds::kMinY, Bounds::kMaxY, coordBits) };
}
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)
{
return { DoubleToUint32(pt.x, limitRect.minX(), limitRect.maxX(), coordBits),
DoubleToUint32(pt.y, limitRect.minY(), limitRect.maxY(), coordBits) };
}
m2::PointD PointUToPointD(m2::PointU const & pt, uint8_t coordBits)
{
using mercator::Bounds;
return { Uint32ToDouble(pt.x, Bounds::kMinX, Bounds::kMaxX, coordBits),
Uint32ToDouble(pt.y, Bounds::kMinY, Bounds::kMaxY, coordBits) };
}
m2::PointD PointUToPointD(m2::PointU const & pt, uint8_t coordBits, m2::RectD const & limitRect)
{
return { 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)
{
int64_t const res = static_cast<int64_t>(PointUToUint64Obsolete(PointDToPointU(x, y, coordBits)));
ASSERT_GREATER_OR_EQUAL(res, 0, ("Highest bits of (ix, iy) are not used, so res should be > 0."));
ASSERT_LESS_OR_EQUAL(static_cast<uint64_t>(res), uint64_t{3} << 2 * kPointCoordBits, ());
return res;
}
int64_t PointToInt64Obsolete(m2::PointD const & pt, uint8_t coordBits)
{
return PointToInt64Obsolete(pt.x, pt.y, coordBits);
}
m2::PointD Int64ToPointObsolete(int64_t v, uint8_t coordBits)
{
ASSERT_GREATER_OR_EQUAL(v, 0, ("Highest bits of (ix, iy) are not used, so res should be > 0."));
ASSERT_LESS_OR_EQUAL(static_cast<uint64_t>(v), uint64_t{3} << 2 * kPointCoordBits, ());
return PointUToPointD(Uint64ToPointUObsolete(static_cast<uint64_t>(v)), coordBits);
}
std::pair<int64_t, int64_t> RectToInt64Obsolete(m2::RectD const & r, uint8_t coordBits)
{
int64_t const p1 = PointToInt64Obsolete(r.minX(), r.minY(), coordBits);
int64_t const p2 = PointToInt64Obsolete(r.maxX(), r.maxY(), coordBits);
return std::make_pair(p1, p2);
}
m2::RectD Int64ToRectObsolete(std::pair<int64_t, int64_t> const & p, uint8_t coordBits)
{
m2::PointD const pt1 = Int64ToPointObsolete(p.first, coordBits);
m2::PointD const pt2 = Int64ToPointObsolete(p.second, coordBits);
return m2::RectD(pt1, pt2);
}
uint64_t PointUToUint64Obsolete(m2::PointU const & pt)
{
uint64_t const res = bits::BitwiseMerge(pt.x, pt.y);
ASSERT_EQUAL(pt, Uint64ToPointUObsolete(res), ());
return res;
}
m2::PointU Uint64ToPointUObsolete(int64_t v)
{
m2::PointU res;
bits::BitwiseSplit(v, res.x, res.y);
return res;
}