forked from organicmaps/organicmaps
pyramidal tiles pre-caching.
This commit is contained in:
parent
d18fe08ce5
commit
db6b2b07de
6 changed files with 157 additions and 150 deletions
|
@ -17,42 +17,51 @@ public:
|
|||
|
||||
double const log2 = log(2.0);
|
||||
|
||||
// LOG(LINFO, ("width:", screenWidth, ", height:", screenHeight));
|
||||
|
||||
size_t ceiledScreenWidth = static_cast<int>(pow(2.0, ceil(log(double(screenWidth)) / log2)));
|
||||
size_t ceiledScreenHeight = static_cast<int>(pow(2.0, ceil(log(double(screenHeight)) / log2)));
|
||||
|
||||
size_t ceiledScreenSize = max(ceiledScreenWidth, ceiledScreenHeight);
|
||||
|
||||
// LOG(LINFO, ("ceiledScreenSize=", ceiledScreenSize));
|
||||
|
||||
m_tileSize = min(max(ceiledScreenSize / 2, (size_t)128), (size_t)512);
|
||||
|
||||
int k = static_cast<int>((256.0 / m_tileSize) * (256.0 / m_tileSize));
|
||||
double k = (256.0 / m_tileSize) * (256.0 / m_tileSize);
|
||||
|
||||
LOG(LINFO, ("tileSize=", m_tileSize));
|
||||
|
||||
/// calculating how much tiles we need for the screen of such size
|
||||
|
||||
m_maxTilesCount = 0;
|
||||
|
||||
m_preCachingDepth = 3;
|
||||
m_preCachingDepth = 6;
|
||||
|
||||
/// calculating for non-rotated screen
|
||||
|
||||
for (unsigned i = 0; i < m_preCachingDepth; ++i)
|
||||
{
|
||||
// LOG(LINFO, ("calculating", i, "level"));
|
||||
/// minimum size of tile on the screen
|
||||
int minTileSize = floor((m_tileSize << i) / 1.05 / 2.0) - 1;
|
||||
float minTileSize = floor((m_tileSize << i) / 1.05 / 2.0) - 1;
|
||||
// LOG(LINFO, ("minTileSize:", minTileSize));
|
||||
int tilesOnXSide = ceil(screenWidth / minTileSize) + 1;
|
||||
// LOG(LINFO, ("tilesOnXSide:", tilesOnXSide));
|
||||
int tilesOnYSide = ceil(screenHeight / minTileSize) + 1;
|
||||
// LOG(LINFO, ("tilesOnYSide:", tilesOnYSide));
|
||||
/// tiles in the single screen
|
||||
int singleScreenTilesCount = tilesOnXSide * tilesOnYSide;
|
||||
|
||||
int curLevelTilesCount = singleScreenTilesCount * 2;
|
||||
|
||||
// LOG(LINFO, ("singleScreenTilesCount:", singleScreenTilesCount));
|
||||
int curLevelTilesCount = singleScreenTilesCount * 3;
|
||||
// LOG(LINFO, ("curLevelTilesCount:", curLevelTilesCount));
|
||||
m_maxTilesCount += curLevelTilesCount;
|
||||
|
||||
LOG(LINFO, ("on", i, "depth we need", curLevelTilesCount, "tiles"));
|
||||
// LOG(LINFO, ("on", i, "depth we need", curLevelTilesCount, "tiles"));
|
||||
}
|
||||
|
||||
LOG(LINFO, ("minimum amount of tiles needed is", m_maxTilesCount));
|
||||
|
||||
m_maxTilesCount = max(120 * k, m_maxTilesCount);
|
||||
m_maxTilesCount = max(static_cast<int>(120 * k), m_maxTilesCount);
|
||||
|
||||
switch (densityDpi)
|
||||
{
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
ScreenCoverage::ScreenCoverage()
|
||||
: m_tiler(0, 0),
|
||||
m_infoLayer(new yg::InfoLayer()),
|
||||
m_drawScale(0),
|
||||
m_isEmptyDrawingCoverage(false),
|
||||
m_leavesCount(0),
|
||||
m_stylesCache(0)
|
||||
{
|
||||
m_infoLayer->setCouldOverlap(false);
|
||||
|
@ -31,8 +31,8 @@ ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer,
|
|||
: m_tileRenderer(tileRenderer),
|
||||
m_tiler(tileSize, scaleEtalonSize),
|
||||
m_infoLayer(new yg::InfoLayer()),
|
||||
m_drawScale(0),
|
||||
m_isEmptyDrawingCoverage(false),
|
||||
m_leavesCount(0),
|
||||
m_coverageGenerator(coverageGenerator),
|
||||
m_stylesCache(0)
|
||||
{
|
||||
|
@ -49,8 +49,9 @@ ScreenCoverage * ScreenCoverage::Clone()
|
|||
res->m_coverageGenerator = m_coverageGenerator;
|
||||
res->m_tileRects = m_tileRects;
|
||||
res->m_newTileRects = m_newTileRects;
|
||||
res->m_drawScale = m_drawScale;
|
||||
res->m_newLeafTileRects = m_newLeafTileRects;
|
||||
res->m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage;
|
||||
res->m_leavesCount = m_leavesCount;
|
||||
|
||||
TileCache * tileCache = &m_tileRenderer->GetTileCache();
|
||||
|
||||
|
@ -119,8 +120,13 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
|||
m_tiles.insert(tile);
|
||||
m_tileRects.erase(ri);
|
||||
m_newTileRects.erase(ri);
|
||||
m_newLeafTileRects.erase(ri);
|
||||
|
||||
m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing;
|
||||
if (m_tiler.isLeaf(ri))
|
||||
{
|
||||
m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing;
|
||||
m_leavesCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,12 +134,14 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
|||
|
||||
if (addTile)
|
||||
{
|
||||
yg::InfoLayer * tileInfoLayerCopy = tile->m_infoLayer->clone();
|
||||
if (m_tiler.isLeaf(ri))
|
||||
{
|
||||
yg::InfoLayer * tileInfoLayerCopy = tile->m_infoLayer->clone();
|
||||
m_infoLayer->merge(*tileInfoLayerCopy,
|
||||
tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
|
||||
|
||||
m_infoLayer->merge(*tileInfoLayerCopy,
|
||||
tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
|
||||
|
||||
delete tileInfoLayerCopy;
|
||||
delete tileInfoLayerCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,41 +175,45 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
m_screen = screen;
|
||||
|
||||
m_newTileRects.clear();
|
||||
|
||||
m_tiler.seed(m_screen, m_screen.GlobalRect().GlobalCenter());
|
||||
|
||||
vector<Tiler::RectInfo> allRects;
|
||||
vector<Tiler::RectInfo> allPrevRects;
|
||||
vector<Tiler::RectInfo> newRects;
|
||||
TileSet tiles;
|
||||
TileSet prevTiles;
|
||||
|
||||
m_tiler.currentLevelTiles(allRects);
|
||||
m_tiler.prevLevelTiles(allPrevRects, GetPlatform().PreCachingDepth());
|
||||
m_tiler.tiles(allRects, GetPlatform().PreCachingDepth());
|
||||
|
||||
TileCache * tileCache = &m_tileRenderer->GetTileCache();
|
||||
|
||||
tileCache->writeLock();
|
||||
|
||||
m_drawScale = m_tiler.drawScale();
|
||||
|
||||
m_isEmptyDrawingCoverage = true;
|
||||
m_leavesCount = 0;
|
||||
|
||||
for (unsigned i = 0; i < allRects.size(); ++i)
|
||||
{
|
||||
m_tileRects.insert(allRects[i]);
|
||||
Tiler::RectInfo ri = allRects[i];
|
||||
|
||||
if (tileCache->hasTile(ri))
|
||||
{
|
||||
tileCache->touchTile(ri);
|
||||
Tile const * tile = &tileCache->getTile(ri);
|
||||
ASSERT(tiles.find(tile) == tiles.end(), ());
|
||||
|
||||
m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing;
|
||||
if (m_tiler.isLeaf(allRects[i]))
|
||||
m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing;
|
||||
|
||||
tiles.insert(tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
newRects.push_back(ri);
|
||||
if (m_tiler.isLeaf(ri))
|
||||
++m_leavesCount;
|
||||
}
|
||||
}
|
||||
|
||||
for (TileSet::const_iterator it = m_prevTiles.begin(); it != m_prevTiles.end(); ++it)
|
||||
|
@ -260,12 +272,58 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
|
||||
for (TileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
|
||||
{
|
||||
yg::InfoLayer * tileInfoLayerCopy = (*it)->m_infoLayer->clone();
|
||||
m_infoLayer->merge(*tileInfoLayerCopy, (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix());
|
||||
delete tileInfoLayerCopy;
|
||||
Tiler::RectInfo ri = (*it)->m_rectInfo;
|
||||
if (m_tiler.isLeaf(ri))
|
||||
{
|
||||
yg::InfoLayer * tileInfoLayerCopy = (*it)->m_infoLayer->clone();
|
||||
m_infoLayer->merge(*tileInfoLayerCopy, (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix());
|
||||
delete tileInfoLayerCopy;
|
||||
}
|
||||
}
|
||||
|
||||
m_newLeafTileRects.clear();
|
||||
|
||||
for (unsigned i = 0; i < newRects.size(); ++i)
|
||||
if (m_tiler.isLeaf(newRects[i]))
|
||||
m_newLeafTileRects.insert(newRects[i]);
|
||||
|
||||
copy(newRects.begin(), newRects.end(), inserter(m_newTileRects, m_newTileRects.end()));
|
||||
|
||||
set<Tiler::RectInfo> drawnTiles;
|
||||
|
||||
for (TileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
|
||||
{
|
||||
Tiler::RectInfo ri = (*it)->m_rectInfo;
|
||||
drawnTiles.insert(Tiler::RectInfo(0, ri.m_tileScale, ri.m_x, ri.m_y));
|
||||
}
|
||||
|
||||
vector<Tiler::RectInfo> firstClassTiles;
|
||||
vector<Tiler::RectInfo> secondClassTiles;
|
||||
|
||||
for (unsigned i = 0; i < newRects.size(); ++i)
|
||||
{
|
||||
Tiler::RectInfo nr = newRects[i];
|
||||
|
||||
Tiler::RectInfo cr[4] =
|
||||
{
|
||||
Tiler::RectInfo(0, nr.m_tileScale + 1, nr.m_x * 2, nr.m_y * 2),
|
||||
Tiler::RectInfo(0, nr.m_tileScale + 1, nr.m_x * 2 + 1, nr.m_y * 2),
|
||||
Tiler::RectInfo(0, nr.m_tileScale + 1, nr.m_x * 2 + 1, nr.m_y * 2 + 1),
|
||||
Tiler::RectInfo(0, nr.m_tileScale + 1, nr.m_x * 2, nr.m_y * 2 + 1)
|
||||
};
|
||||
|
||||
int childTilesToDraw = 4;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
if (drawnTiles.count(cr[i]) || !m_screen.GlobalRect().IsIntersect(m2::AnyRectD(cr[i].m_rect)))
|
||||
--childTilesToDraw;
|
||||
|
||||
if (childTilesToDraw > 1)
|
||||
firstClassTiles.push_back(nr);
|
||||
else
|
||||
secondClassTiles.push_back(nr);
|
||||
}
|
||||
|
||||
/// clearing all old commands
|
||||
m_tileRenderer->ClearCommands();
|
||||
/// setting new sequenceID
|
||||
|
@ -273,11 +331,16 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
|
||||
m_tileRenderer->CancelCommands();
|
||||
|
||||
/// adding commands for tiles which aren't in cache
|
||||
for (size_t i = 0; i < newRects.size(); ++i)
|
||||
m_tileRenderer->AddCommand(newRects[i], m_tiler.sequenceID(),
|
||||
bind(&CoverageGenerator::AddMergeTileTask, m_coverageGenerator, newRects[i]));
|
||||
// filtering out rects that are fully covered by its descedants
|
||||
|
||||
// adding commands for tiles which aren't in cache
|
||||
for (size_t i = 0; i < firstClassTiles.size(); ++i)
|
||||
m_tileRenderer->AddCommand(firstClassTiles[i], m_tiler.sequenceID(),
|
||||
bind(&CoverageGenerator::AddMergeTileTask, m_coverageGenerator,
|
||||
firstClassTiles[i]));
|
||||
|
||||
for (size_t i = 0; i < secondClassTiles.size(); ++i)
|
||||
m_tileRenderer->AddCommand(secondClassTiles[i], m_tiler.sequenceID());
|
||||
}
|
||||
|
||||
ScreenCoverage::~ScreenCoverage()
|
||||
|
@ -308,23 +371,7 @@ void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen)
|
|||
{
|
||||
vector<yg::gl::BlitInfo> infos;
|
||||
|
||||
for (TileSet::const_iterator it = m_prevTiles.begin(); it != m_prevTiles.end(); ++it)
|
||||
{
|
||||
Tile const * tile = *it;
|
||||
|
||||
size_t tileWidth = tile->m_renderTarget->width();
|
||||
size_t tileHeight = tile->m_renderTarget->height();
|
||||
|
||||
yg::gl::BlitInfo bi;
|
||||
|
||||
bi.m_matrix = tile->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix();
|
||||
|
||||
bi.m_srcRect = m2::RectI(0, 0, tileWidth - 2, tileHeight - 2);
|
||||
bi.m_texRect = m2::RectU(1, 1, tileWidth - 1, tileHeight - 1);
|
||||
bi.m_srcSurface = tile->m_renderTarget;
|
||||
|
||||
infos.push_back(bi);
|
||||
}
|
||||
// LOG(LINFO, ("drawing", m_tiles.size(), "tiles"));
|
||||
|
||||
for (TileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
|
||||
{
|
||||
|
@ -369,12 +416,12 @@ void ScreenCoverage::EndFrame(yg::gl::Screen *s)
|
|||
|
||||
int ScreenCoverage::GetDrawScale() const
|
||||
{
|
||||
return m_drawScale;
|
||||
return m_tiler.drawScale();
|
||||
}
|
||||
|
||||
bool ScreenCoverage::IsEmptyDrawingCoverage() const
|
||||
{
|
||||
return m_isEmptyDrawingCoverage;
|
||||
return (m_leavesCount <= 0) && m_isEmptyDrawingCoverage;
|
||||
}
|
||||
|
||||
bool ScreenCoverage::IsPartialCoverage() const
|
||||
|
|
|
@ -44,20 +44,19 @@ private:
|
|||
TileRectSet m_tileRects;
|
||||
/// Only rects, that should be drawn
|
||||
TileRectSet m_newTileRects;
|
||||
/// Only leaf rects, that should be drawn
|
||||
TileRectSet m_newLeafTileRects;
|
||||
/// Typedef for a set of tiles, that are visible for the m_screen
|
||||
typedef set<Tile const *, LessRectInfo> TileSet;
|
||||
TileSet m_tiles;
|
||||
TileSet m_prevTiles;
|
||||
/// InfoLayer composed of infoLayers for visible tiles
|
||||
scoped_ptr<yg::InfoLayer> m_infoLayer;
|
||||
/// Primary scale, which is used to draw tiles in m_screen.
|
||||
/// Not all tiles could correspond to this value, as there could be tiles from
|
||||
/// lower and higher level in the coverage to provide a smooth
|
||||
/// scale transition experience
|
||||
int m_drawScale;
|
||||
|
||||
bool m_isEmptyDrawingCoverage;
|
||||
|
||||
int m_leavesCount;
|
||||
|
||||
CoverageGenerator * m_coverageGenerator;
|
||||
yg::StylesCache * m_stylesCache;
|
||||
|
||||
|
@ -96,5 +95,8 @@ public:
|
|||
/// perform end frame
|
||||
void EndFrame(yg::gl::Screen * s);
|
||||
/// get draw scale for the tiles in the current coverage
|
||||
/// Not all tiles in coverage could correspond to this value,
|
||||
/// as there could be tiles from lower and higher level in the
|
||||
/// coverage to provide a smooth scale transition experience
|
||||
int GetDrawScale() const;
|
||||
};
|
||||
|
|
126
map/tiler.cpp
126
map/tiler.cpp
|
@ -28,26 +28,31 @@ void Tiler::RectInfo::initRect()
|
|||
m_rect.setMaxY((m_y + 1) * rectSizeY);
|
||||
}
|
||||
|
||||
LessByDistance::LessByDistance(m2::PointD const & pt)
|
||||
LessByScaleAndDistance::LessByScaleAndDistance(m2::PointD const & pt)
|
||||
: m_pt(pt)
|
||||
{
|
||||
}
|
||||
|
||||
bool LessByDistance::operator()(Tiler::RectInfo const & l, Tiler::RectInfo const & r)
|
||||
bool LessByScaleAndDistance::operator()(Tiler::RectInfo const & l, Tiler::RectInfo const & r)
|
||||
{
|
||||
if (l.m_drawScale != r.m_drawScale)
|
||||
return l.m_drawScale < r.m_drawScale;
|
||||
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_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;
|
||||
if (l.m_drawScale != r.m_drawScale)
|
||||
return l.m_drawScale < r.m_drawScale;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -112,63 +117,7 @@ void Tiler::seed(ScreenBase const & screen, m2::PointD const & centerPt)
|
|||
m_tileScale = getTileScale(screen, m_tileSize);
|
||||
}
|
||||
|
||||
void Tiler::currentLevelTiles(vector<RectInfo> & tiles)
|
||||
{
|
||||
int tileSize = m_tileSize;
|
||||
|
||||
int drawScale = getDrawScale(m_screen, tileSize, 1);
|
||||
int tileScale = getTileScale(m_screen, tileSize);
|
||||
|
||||
double rectSizeX = (MercatorBounds::maxX - MercatorBounds::minX) / (1 << tileScale);
|
||||
double rectSizeY = (MercatorBounds::maxY - MercatorBounds::minY) / (1 << tileScale);
|
||||
|
||||
/// calculating coverage on the global rect, which corresponds to the
|
||||
/// pixel rect, which in ceiled to tileSize and enlarged by 1 tile on each side
|
||||
/// to produce an effect of simple precaching.
|
||||
|
||||
m2::RectD pxRect = m_screen.PixelRect();
|
||||
|
||||
int pxWidthInTiles = (pxRect.SizeX() + tileSize - 1) / tileSize;
|
||||
int pxHeightInTiles = (pxRect.SizeY() + tileSize - 1) / tileSize;
|
||||
|
||||
m2::PointD pxCenter = pxRect.Center();
|
||||
|
||||
double glbHalfSizeX = m_screen.PtoG(pxCenter - m2::PointD(pxWidthInTiles * tileSize / 2, 0)).Length(m_screen.PtoG(pxCenter));
|
||||
double glbHalfSizeY = m_screen.PtoG(pxCenter - m2::PointD(0, pxHeightInTiles * tileSize / 2)).Length(m_screen.PtoG(pxCenter));
|
||||
|
||||
m2::AnyRectD globalRect(m_screen.PtoG(pxCenter),
|
||||
m_screen.GlobalRect().angle(),
|
||||
m2::RectD(-glbHalfSizeX, -glbHalfSizeY, glbHalfSizeX, glbHalfSizeY));
|
||||
|
||||
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));
|
||||
|
||||
/// clearing previous coverage
|
||||
tiles.clear();
|
||||
|
||||
/// 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(drawScale, tileScale, tileX, tileY));
|
||||
}
|
||||
|
||||
/// sorting coverage elements
|
||||
sort(tiles.begin(), tiles.end(), LessByDistance(m_centerPt));
|
||||
}
|
||||
|
||||
void Tiler::prevLevelTiles(vector<RectInfo> & tiles, int depth)
|
||||
void Tiler::tiles(vector<RectInfo> & tiles, int depth)
|
||||
{
|
||||
if (m_tileScale == 0)
|
||||
return;
|
||||
|
@ -176,14 +125,14 @@ void Tiler::prevLevelTiles(vector<RectInfo> & tiles, int depth)
|
|||
/// clearing previous coverage
|
||||
tiles.clear();
|
||||
|
||||
int lowerBound = m_tileScale > depth ? m_tileScale - depth : 0;
|
||||
int higherBound = m_tileScale;
|
||||
if (m_tileScale - depth < 0)
|
||||
depth = m_tileScale;
|
||||
|
||||
for (unsigned i = lowerBound; i < higherBound; ++i)
|
||||
for (unsigned i = 0; i < depth; ++i)
|
||||
{
|
||||
int pow = m_tileScale - i - 1;
|
||||
int pow = depth - 1 - i;
|
||||
|
||||
int scale = 2 << pow;
|
||||
int scale = 1 << pow;
|
||||
|
||||
int tileSize = m_tileSize * scale;
|
||||
|
||||
|
@ -194,24 +143,10 @@ void Tiler::prevLevelTiles(vector<RectInfo> & tiles, int depth)
|
|||
double rectSizeY = (MercatorBounds::maxY - MercatorBounds::minY) / (1 << tileScale);
|
||||
|
||||
/// calculating coverage on the global rect, which corresponds to the
|
||||
/// pixel rect, which in ceiled to tileSize and enlarged by 1 tile on each side
|
||||
/// to produce an effect of simple precaching.
|
||||
/// pixel rect, which in ceiled to tileSize
|
||||
|
||||
m2::RectD pxRect = m_screen.PixelRect();
|
||||
|
||||
int pxWidthInTiles = (pxRect.SizeX() + tileSize - 1) / tileSize;
|
||||
int pxHeightInTiles = (pxRect.SizeY() + tileSize - 1) / tileSize;
|
||||
|
||||
m2::PointD pxCenter = pxRect.Center();
|
||||
|
||||
double glbHalfSizeX = m_screen.PtoG(pxCenter - m2::PointD(pxWidthInTiles * tileSize / 2, 0)).Length(m_screen.PtoG(pxCenter));
|
||||
double glbHalfSizeY = m_screen.PtoG(pxCenter - m2::PointD(0, pxHeightInTiles * tileSize / 2)).Length(m_screen.PtoG(pxCenter));
|
||||
|
||||
m2::AnyRectD globalRect(m_screen.PtoG(pxCenter),
|
||||
m_screen.GlobalRect().angle(),
|
||||
m2::RectD(-glbHalfSizeX, -glbHalfSizeY, glbHalfSizeX, glbHalfSizeY));
|
||||
|
||||
m2::RectD const clipRect = globalRect.GetGlobalRect();
|
||||
m2::AnyRectD const & globalRect = m_screen.GlobalRect();
|
||||
m2::RectD const clipRect = m_screen.GlobalRect().GetGlobalRect();
|
||||
|
||||
int minTileX = static_cast<int>(floor(clipRect.minX() / rectSizeX));
|
||||
int maxTileX = static_cast<int>(ceil(clipRect.maxX() / rectSizeX));
|
||||
|
@ -234,12 +169,15 @@ void Tiler::prevLevelTiles(vector<RectInfo> & tiles, int depth)
|
|||
}
|
||||
|
||||
/// sorting coverage elements
|
||||
sort(tiles.begin(), tiles.end(), LessByDistance(m_centerPt));
|
||||
sort(tiles.begin(), tiles.end(), LessByScaleAndDistance(m_centerPt));
|
||||
}
|
||||
|
||||
|
||||
Tiler::Tiler(size_t tileSize, size_t scaleEtalonSize)
|
||||
: m_sequenceID(0), m_tileSize(tileSize), m_scaleEtalonSize(scaleEtalonSize)
|
||||
: m_drawScale(0),
|
||||
m_tileScale(0),
|
||||
m_sequenceID(0),
|
||||
m_tileSize(tileSize),
|
||||
m_scaleEtalonSize(scaleEtalonSize)
|
||||
{}
|
||||
|
||||
size_t Tiler::sequenceID() const
|
||||
|
@ -247,7 +185,17 @@ size_t Tiler::sequenceID() const
|
|||
return m_sequenceID;
|
||||
}
|
||||
|
||||
double Tiler::drawScale() const
|
||||
int Tiler::drawScale() const
|
||||
{
|
||||
return m_drawScale;
|
||||
}
|
||||
|
||||
int Tiler::tileScale() const
|
||||
{
|
||||
return m_tileScale;
|
||||
}
|
||||
|
||||
bool Tiler::isLeaf(RectInfo const & ri) const
|
||||
{
|
||||
return (ri.m_drawScale == m_drawScale) && (ri.m_tileScale == m_tileScale);
|
||||
}
|
||||
|
|
|
@ -46,18 +46,19 @@ public:
|
|||
/// seed tiler with new screenBase.
|
||||
void seed(ScreenBase const & screenBase, m2::PointD const & centerPt);
|
||||
|
||||
void currentLevelTiles(vector<RectInfo> & tiles);
|
||||
void prevLevelTiles(vector<RectInfo> & tiles, int depth);
|
||||
void tiles(vector<RectInfo> & tiles, int depth);
|
||||
bool isLeaf(RectInfo const & ri) const;
|
||||
|
||||
size_t sequenceID() const;
|
||||
|
||||
double drawScale() const;
|
||||
int drawScale() const;
|
||||
int tileScale() const;
|
||||
};
|
||||
|
||||
struct LessByDistance
|
||||
struct LessByScaleAndDistance
|
||||
{
|
||||
m2::PointD m_pt;
|
||||
LessByDistance(m2::PointD const & pt);
|
||||
LessByScaleAndDistance(m2::PointD const & pt);
|
||||
bool operator()(Tiler::RectInfo const & l, Tiler::RectInfo const & r);
|
||||
};
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ int Platform::MaxTilesCount() const
|
|||
|
||||
int Platform::PreCachingDepth() const
|
||||
{
|
||||
return 3;
|
||||
return 5;
|
||||
}
|
||||
|
||||
int Platform::TileSize() const
|
||||
|
|
Loading…
Add table
Reference in a new issue