1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#include "tiler.hpp"
#include "scales_processor.hpp"
#include "indexer/mercator.hpp"
#include "base/logging.hpp"
Tiler::RectInfo::RectInfo()
: m_tileScale(0), m_x(0), m_y(0)
{}
Tiler::RectInfo::RectInfo(int tileScale, int x, int y)
: m_tileScale(tileScale), m_x(x), m_y(y)
{
initRect();
}
void Tiler::RectInfo::initRect()
{
int k = 1 << m_tileScale;
double rectSizeX = (MercatorBounds::maxX - MercatorBounds::minX) / k;
double rectSizeY = (MercatorBounds::maxY - MercatorBounds::minY) / k;
m_rect.setMinX(m_x * rectSizeX);
m_rect.setMaxX((m_x + 1) * rectSizeX);
m_rect.setMinY(m_y * rectSizeY);
m_rect.setMaxY((m_y + 1) * rectSizeY);
}
LessByScaleAndDistance::LessByScaleAndDistance(m2::PointD const & pt)
: m_pt(pt)
{
}
bool LessByScaleAndDistance::operator()(Tiler::RectInfo const & l, Tiler::RectInfo const & r)
{
if (l.m_tileScale != r.m_tileScale)
return l.m_tileScale < r.m_tileScale;
return l.m_rect.Center().Length(m_pt) < r.m_rect.Center().Length(m_pt);
}
bool operator<(Tiler::RectInfo const & l, Tiler::RectInfo const & r)
{
if (l.m_tileScale != r.m_tileScale)
return l.m_tileScale < r.m_tileScale;
if (l.m_y != r.m_y)
return l.m_y < r.m_y;
if (l.m_x != r.m_x)
return l.m_x < r.m_x;
return false;
}
bool operator==(Tiler::RectInfo const & l, Tiler::RectInfo const & r)
{
return (l.m_y == r.m_y)
&& (l.m_x == r.m_x)
&& (l.m_tileScale == r.m_tileScale);
}
int Tiler::getTileScale(ScreenBase const & s, int ts) const
{
return ScalesProcessor(ts).GetTileScaleBase(s);
}
void Tiler::seed(ScreenBase const & screen, m2::PointD const & centerPt, size_t tileSize)
{
m_screen = screen;
m_centerPt = centerPt;
m_tileSize = tileSize;
m_tileScale = getTileScale(screen, tileSize);
}
void Tiler::tiles(vector<RectInfo> & tiles, int depth)
{
if (m_tileScale == 0)
return;
tiles.clear();
if (m_tileScale - depth < 0)
depth = m_tileScale;
for (unsigned i = 0; i < depth; ++i)
{
int const pow = depth - 1 - i;
int const scale = 1 << pow;
int const tileSize = m_tileSize * scale;
int const tileScale = getTileScale(m_screen, tileSize);
double const rectSizeX = (MercatorBounds::maxX - MercatorBounds::minX) / (1 << tileScale);
double const rectSizeY = (MercatorBounds::maxY - MercatorBounds::minY) / (1 << tileScale);
// calculating coverage on the global rect, which corresponds to the
// pixel rect, which in ceiled to tileSize
m2::AnyRectD const & globalRect = m_screen.GlobalRect();
m2::RectD const clipRect = globalRect.GetGlobalRect();
int minTileX = static_cast<int>(floor(clipRect.minX() / rectSizeX));
int maxTileX = static_cast<int>(ceil(clipRect.maxX() / rectSizeX));
int minTileY = static_cast<int>(floor(clipRect.minY() / rectSizeY));
int maxTileY = static_cast<int>(ceil(clipRect.maxY() / rectSizeY));
// generating new coverage
for (int tileY = minTileY; tileY < maxTileY; ++tileY)
for (int tileX = minTileX; tileX < maxTileX; ++tileX)
{
m2::RectD tileRect(tileX * rectSizeX,
tileY * rectSizeY,
(tileX + 1) * rectSizeX,
(tileY + 1) * rectSizeY);
if (globalRect.IsIntersect(m2::AnyRectD(tileRect)))
tiles.push_back(RectInfo(tileScale, tileX, tileY));
}
}
// sorting coverage elements
sort(tiles.begin(), tiles.end(), LessByScaleAndDistance(m_centerPt));
}
Tiler::Tiler() : m_tileScale(0)
{}
int Tiler::tileScale() const
{
return m_tileScale;
}
bool Tiler::isLeaf(RectInfo const & ri) const
{
return (ri.m_tileScale == m_tileScale);
}
|