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
|
#include "scales_processor.hpp"
#include "geometry/screenbase.hpp"
#include "indexer/mercator.hpp"
#include "indexer/scales.hpp"
/// Note! Default tile size value should be equal with
/// the default value in RenderPolicy::TileSize().
ScalesProcessor::ScalesProcessor()
: m_tileSize(256), m_visualScale(1.0)
{
}
ScalesProcessor::ScalesProcessor(int tileSize)
: m_tileSize(tileSize), m_visualScale(1.0)
{
}
void ScalesProcessor::SetParams(double visualScale, int tileSize)
{
m_tileSize = tileSize;
m_visualScale = visualScale;
}
m2::RectD const & ScalesProcessor::GetWorldRect()
{
static m2::RectD const worldRect = MercatorBounds::FullRect();
return worldRect;
}
int ScalesProcessor::GetTileScaleBase(ScreenBase const & s) const
{
ScreenBase tmpS = s;
tmpS.Rotate(-tmpS.GetAngle());
// slightly smaller than original to produce "antialiasing" effect using bilinear filtration.
int const halfSize = static_cast<int>(m_tileSize / 1.05 / 2.0);
m2::RectD glbRect;
m2::PointD const pxCenter = tmpS.PixelRect().Center();
tmpS.PtoG(m2::RectD(pxCenter - m2::PointD(halfSize, halfSize),
pxCenter + m2::PointD(halfSize, halfSize)),
glbRect);
return GetTileScaleBase(glbRect);
}
int ScalesProcessor::GetTileScaleBase(m2::RectD const & r) const
{
double const sz = max(r.SizeX(), r.SizeY());
return max(1, my::rounds(log((MercatorBounds::maxX - MercatorBounds::minX) / sz) / log(2.0)));
}
int ScalesProcessor::GetTileScaleIncrement() const
{
return log(m_tileSize / 256.0 / m_visualScale) / log(2.0);
}
int ScalesProcessor::CalculateTileSize(int screenWidth, int screenHeight)
{
int const maxSz = max(screenWidth, screenHeight);
// we're calculating the tileSize based on (maxSz > 1024 ? rounded : ceiled)
// to the nearest power of two value of the maxSz
int const ceiledSz = 1 << static_cast<int>(ceil(log(double(maxSz + 1)) / log(2.0)));
int res = 0;
if (maxSz < 1024)
res = ceiledSz;
else
{
int const flooredSz = ceiledSz / 2;
// rounding to the nearest power of two.
if (ceiledSz - maxSz < maxSz - flooredSz)
res = ceiledSz;
else
res = flooredSz;
}
return min(max(res / 2, 256), 1024);
}
m2::RectD ScalesProcessor::GetRectForDrawScale(int drawScale, m2::PointD const & center) const
{
// +1 - we will calculate half length for each side
double const factor = 1 << (max(1, drawScale - GetTileScaleIncrement()) + 1);
double const len = (MercatorBounds::maxX - MercatorBounds::minX) / factor;
return m2::RectD(MercatorBounds::ClampX(center.x - len),
MercatorBounds::ClampY(center.y - len),
MercatorBounds::ClampX(center.x + len),
MercatorBounds::ClampY(center.y + len));
}
double ScalesProcessor::GetClipRectInflation() const
{
/// @todo Why 24? Probably better to get some part of m_tileSize?
return 24 * m_visualScale;
}
|