diff --git a/indexer/cell_id.hpp b/indexer/cell_id.hpp index b43e744d46..d0ee6641b6 100644 --- a/indexer/cell_id.hpp +++ b/indexer/cell_id.hpp @@ -1,26 +1,9 @@ #pragma once #include "mercator.hpp" +#include "point_to_int64.hpp" -#include "../geometry/cellid.hpp" -#include "../geometry/rect2d.hpp" - -#include "../base/base.hpp" #include "../base/assert.hpp" -#include "../std/utility.hpp" -#include "../std/string.hpp" - -typedef double CoordT; -typedef pair CoordPointT; - -typedef m2::CellId<19> RectId; - -int64_t PointToInt64(CoordT x, CoordT y); -inline int64_t PointToInt64(CoordPointT const & pt) { return PointToInt64(pt.first, pt.second); } -CoordPointT Int64ToPoint(int64_t v); - -pair RectToInt64(m2::RectD const & r); -m2::RectD Int64ToRect(pair const & p); template struct Bounds @@ -40,7 +23,6 @@ template class CellIdConverter { public: - static CoordT XToCellIdX(CoordT x) { return (x - BoundsT::minX) / StepX(); @@ -50,6 +32,15 @@ public: return (y - BoundsT::minY) / StepY(); } + static CoordT CellIdXToX(CoordT x) + { + return (x*StepX() + BoundsT::minX); + } + static CoordT CellIdYToY(CoordT y) + { + return (y*StepY() + BoundsT::minY); + } + static CellIdT ToCellId(CoordT x, CoordT y) { uint32_t const ix = static_cast(XToCellIdX(x)); @@ -90,7 +81,7 @@ public: static CoordPointT FromCellId(CellIdT id) { pair const xy = id.XY(); - return CoordPointT(xy.first * StepX() + BoundsT::minX, xy.second * StepY() + BoundsT::minY); + return CoordPointT(CellIdXToX(xy.first), CellIdYToY(xy.second)); } static void GetCellBounds(CellIdT id, CoordT & minX, CoordT & minY, CoordT & maxX, CoordT & maxY) diff --git a/indexer/point_to_int64.cpp b/indexer/point_to_int64.cpp index 152ba44e93..93c990d81b 100644 --- a/indexer/point_to_int64.cpp +++ b/indexer/point_to_int64.cpp @@ -11,36 +11,48 @@ #define POINT_COORD_BITS 30 -int64_t PointToInt64(CoordT x, CoordT y) + +m2::PointU PointD2PointU(CoordT x, CoordT y) { if (x < MercatorBounds::minX) x = MercatorBounds::minX; if (y < MercatorBounds::minY) y = MercatorBounds::minY; if (x > MercatorBounds::maxX) x = MercatorBounds::maxX; if (y > MercatorBounds::maxY) y = MercatorBounds::maxY; + uint32_t const ix = static_cast(0.5 + (x - MercatorBounds::minX) - / (MercatorBounds::maxX - MercatorBounds::minX) * (1 << POINT_COORD_BITS)); + / (MercatorBounds::maxX - MercatorBounds::minX) * (1 << POINT_COORD_BITS)); uint32_t const iy = static_cast(0.5 + (y - MercatorBounds::minY) - / (MercatorBounds::maxY - MercatorBounds::minY) * (1 << POINT_COORD_BITS)); - int64_t res = static_cast(m2::PointUToUint64(m2::PointU(ix, iy))); + / (MercatorBounds::maxY - MercatorBounds::minY) * (1 << POINT_COORD_BITS)); + ASSERT_LESS_OR_EQUAL(ix, 1 << POINT_COORD_BITS, ()); ASSERT_LESS_OR_EQUAL(iy, 1 << POINT_COORD_BITS, ()); + + return m2::PointU(ix, iy); +} + +int64_t PointToInt64(CoordT x, CoordT y) +{ + int64_t const res = static_cast(m2::PointUToUint64(PointD2PointU(x, y))); + ASSERT_LESS_OR_EQUAL(res, 3ULL << 2 * POINT_COORD_BITS, ()); ASSERT_GREATER_OR_EQUAL(res, 0, ("Highest bits of (ix, iy) are not used, so res should be > 0.")); return res; } +CoordPointT PointU2PointD(m2::PointU const & pt) +{ + return CoordPointT( + static_cast(pt.x) * (MercatorBounds::maxX - MercatorBounds::minX) + / (1 << POINT_COORD_BITS) + MercatorBounds::minX, + static_cast(pt.y) * (MercatorBounds::maxY - MercatorBounds::minY) + / (1 << POINT_COORD_BITS) + MercatorBounds::minY); +} + CoordPointT Int64ToPoint(int64_t v) { ASSERT_LESS_OR_EQUAL(v, 3ULL << 2 * POINT_COORD_BITS, ()); - m2::PointU const pt = m2::Uint64ToPointU(static_cast(v)); - CoordT const fx = static_cast(pt.x); - CoordT const fy = static_cast(pt.y); - return CoordPointT( - fx * (MercatorBounds::maxX - MercatorBounds::minX) - / (1 << POINT_COORD_BITS) + MercatorBounds::minX, - fy * (MercatorBounds::maxY - MercatorBounds::minY) - / (1 << POINT_COORD_BITS) + MercatorBounds::minY); + return PointU2PointD(m2::Uint64ToPointU(static_cast(v))); } pair RectToInt64(m2::RectD const & r) diff --git a/indexer/point_to_int64.hpp b/indexer/point_to_int64.hpp new file mode 100644 index 0000000000..3bb7325c40 --- /dev/null +++ b/indexer/point_to_int64.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "../geometry/cellid.hpp" +#include "../geometry/rect2d.hpp" + +#include "../std/utility.hpp" + + +typedef double CoordT; +typedef pair CoordPointT; + +typedef m2::CellId<19> RectId; + +m2::PointU PointD2PointU(CoordT x, CoordT y); +CoordPointT PointU2PointD(m2::PointU const & p); + +int64_t PointToInt64(CoordT x, CoordT y); +inline int64_t PointToInt64(CoordPointT const & pt) { return PointToInt64(pt.first, pt.second); } +CoordPointT Int64ToPoint(int64_t v); + +pair RectToInt64(m2::RectD const & r); +m2::RectD Int64ToRect(pair const & p);