Welcome to mirror list, hosted at ThFree Co, Russian Federation.

visual_params.cpp « drape_frontend - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7d1e97655797774c9e96221447730e2247d98efe (plain)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include "visual_params.hpp"

#include "../base/macros.hpp"
#include "../base/math.hpp"
#include "../base/assert.hpp"

#include "../indexer/mercator.hpp"

#include "../std/limits.hpp"
#include "../std/algorithm.hpp"

namespace df
{

uint32_t const YotaDevice = 0x1;

namespace
{

static VisualParams g_VizParams;

typedef pair<string, double> visual_scale_t;

struct VisualScaleFinder
{
  VisualScaleFinder(double vs)
    : m_vs(vs)
  {
  }

  bool operator()(visual_scale_t const & node)
  {
    return my::AlmostEqual(node.second, m_vs);
  }

  double m_vs;
};

} // namespace

#ifdef DEBUG
static bool g_isInited = false;
#define RISE_INITED g_isInited = true
#define ASSERT_INITED ASSERT(g_isInited, ())
#else
#define RISE_INITED
#define ASSERT_INITED
#endif


void VisualParams::Init(double vs, uint32_t tileSize, vector<uint32_t> const & additionalOptions)
{
  g_VizParams.m_tileSize = tileSize;
  g_VizParams.m_visualScale = vs;
  if (find(additionalOptions.begin(), additionalOptions.end(), YotaDevice) != additionalOptions.end())
    g_VizParams.m_isYotaDevice = true;
  RISE_INITED;
}

VisualParams & VisualParams::Instance()
{
  ASSERT_INITED;
  return g_VizParams;
}

string const & VisualParams::GetResourcePostfix() const
{
  static visual_scale_t postfixes[] =
  {
    make_pair("ldpi", 0.75),
    make_pair("mdpi", 1.0),
    make_pair("hdpi", 1.5),
    make_pair("xhdpi", 2.0),
    make_pair("xxhdpi",  3.0)
  };

  static string specifixPostfixes[] =
  {
    "yota"
  };

  if (m_isYotaDevice)
    return specifixPostfixes[0];

  visual_scale_t * finded = find_if(postfixes, postfixes + ARRAY_SIZE(postfixes), VisualScaleFinder(m_visualScale));
  ASSERT(finded < postfixes + ARRAY_SIZE(postfixes), ());
  return finded->first;
}

double VisualParams::GetVisualScale() const
{
  return m_visualScale;
}

uint32_t VisualParams::GetTileSize() const
{
  return m_tileSize;
}

VisualParams::VisualParams()
  : m_tileSize(0)
  , m_visualScale(0.0)
{
}

m2::RectD const & GetWorldRect()
{
  static m2::RectD const worldRect = MercatorBounds::FullRect();
  return worldRect;
}

int GetTileScaleBase(ScreenBase const & s)
{
  ScreenBase tmpS = s;
  tmpS.Rotate(-tmpS.GetAngle());

  // slightly smaller than original to produce "antialiasing" effect using bilinear filtration.
  int const halfSize = static_cast<int>(VisualParams::Instance().GetTileSize() / 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 GetTileScaleBase(m2::RectD const & r)
{
  double const sz = max(r.SizeX(), r.SizeY());
  return max(1, my::rounds(log((MercatorBounds::maxX - MercatorBounds::minX) / sz) / log(2.0)));
}

int GetTileScaleIncrement()
{
  VisualParams const & p = VisualParams::Instance();
  return log(p.GetTileSize() / 256.0 / p.GetVisualScale()) / log(2.0);
}

m2::RectD GetRectForDrawScale(int drawScale, m2::PointD const & center)
{
  // +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));
}

m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center)
{
  return GetRectForDrawScale(my::rounds(drawScale), center);
}

int 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;
  }

#ifndef OMIM_OS_DESKTOP
  return my::clamp(res / 2, 256, 1024);
#else
  return my::clamp(res / 2, 512, 1024);
#endif
}

int GetDrawTileScale(int baseScale)
{
  return max(1, baseScale + GetTileScaleIncrement());
}

int GetDrawTileScale(ScreenBase const & s)
{
  return GetDrawTileScale(GetTileScaleBase(s));
}

int GetDrawTileScale(m2::RectD const & r)
{
  return GetDrawTileScale(GetTileScaleBase(r));
}

} // namespace df