Commit a681941a authored by dogmaphobic's avatar dogmaphobic
Browse files

Fixes to Offline Map Cache

parent 6920c117
......@@ -20,7 +20,8 @@ Rectangle
property bool checked: false
property bool complete: false
property alias text: nameLabel.text
property alias size: sizeLabel.text
property int tiles: 0
property string size: ""
signal clicked()
......@@ -40,6 +41,7 @@ Rectangle
horizontalAlignment: Text.AlignRight
anchors.verticalCenter: parent.verticalCenter
color: __showHighlight ? __qgcPal.buttonHighlightText : __qgcPal.buttonText
text: __mapButton.size + (tiles > 0 ? " (" + tiles + " tiles)" : "")
}
Item {
width: ScreenTools.defaultFontPixelWidth * 2
......
......@@ -32,7 +32,7 @@ Q_DECLARE_METATYPE(QList<QGCTile*>)
static const char* kDbFileName = "qgcMapCache.db";
static QLocale kLocale;
#define CACHE_PATH_VERSION "100"
#define CACHE_PATH_VERSION "300"
struct stQGeoTileCacheQGCMapTypes {
const char* name;
......@@ -144,15 +144,29 @@ QGCMapEngine::~QGCMapEngine()
//-----------------------------------------------------------------------------
void
QGCMapEngine::init()
QGCMapEngine::_wipeOldCaches()
{
//-- Delete old style cache (if present)
QString oldCacheDir;
#ifdef __mobile__
oldCacheDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1String("/QGCMapCache55");
#else
oldCacheDir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/QGCMapCache55");
#endif
_wipeDirectory(oldCacheDir);
#ifdef __mobile__
QString oldCacheDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1String("/QGCMapCache55");
oldCacheDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1String("/QGCMapCache100");
#else
QString oldCacheDir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/QGCMapCache55");
oldCacheDir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/QGCMapCache100");
#endif
_wipeDirectory(oldCacheDir);
}
//-----------------------------------------------------------------------------
void
QGCMapEngine::init()
{
//-- Delete old style caches (if present)
_wipeOldCaches();
//-- Figure out cache path
#ifdef __mobile__
QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1String("/QGCMapCache" CACHE_PATH_VERSION);
......@@ -398,7 +412,7 @@ QGCMapEngine::bigSizeToString(quint64 size)
//-----------------------------------------------------------------------------
QString
QGCMapEngine::numberToString(quint32 number)
QGCMapEngine::numberToString(quint64 number)
{
return kLocale.toString(number);
}
......@@ -408,7 +422,7 @@ void
QGCMapEngine::_updateTotals(quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize)
{
emit updateTotals(totaltiles, totalsize, defaulttiles, defaultsize);
quint64 maxSize = getMaxDiskCache() * 1024 * 1024;
quint64 maxSize = (quint64)getMaxDiskCache() * 1024L * 1024L;
if(!_prunning && defaultsize > maxSize) {
//-- Prune Disk Cache
_prunning = true;
......
......@@ -96,7 +96,7 @@ public:
static QString getTileHash (UrlFactory::MapType type, int x, int y, int z);
static UrlFactory::MapType getTypeFromName (const QString &name);
static QString bigSizeToString (quint64 size);
static QString numberToString (quint32 number);
static QString numberToString (quint64 number);
static int concurrentDownloads (UrlFactory::MapType type);
private slots:
......@@ -107,7 +107,8 @@ signals:
void updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize);
private:
bool _wipeDirectory(const QString& dirPath);
void _wipeOldCaches ();
bool _wipeDirectory (const QString& dirPath);
private:
QGCCacheWorker _worker;
......
......@@ -28,17 +28,18 @@ QGC_LOGGING_CATEGORY(QGCCachedTileSetLog, "QGCCachedTileSetLog")
#define TILE_BATCH_SIZE 256
//-----------------------------------------------------------------------------
QGCCachedTileSet::QGCCachedTileSet(const QString& name, const QString& description)
QGCCachedTileSet::QGCCachedTileSet(const QString& name)
: _name(name)
, _description(description)
, _topleftLat(0.0)
, _topleftLon(0.0)
, _bottomRightLat(0.0)
, _bottomRightLon(0.0)
, _numTiles(0)
, _tilesSize(0)
, _savedTiles(0)
, _savedSize(0)
, _totalTileCount(0)
, _totalTileSize(0)
, _uniqueTileCount(0)
, _uniqueTileSize(0)
, _savedTileCount(0)
, _savedTileSize(0)
, _minZoom(3)
, _maxZoom(3)
, _defaultSet(false)
......@@ -72,30 +73,44 @@ QGCCachedTileSet::errorCountStr()
//-----------------------------------------------------------------------------
QString
QGCCachedTileSet::numTilesStr()
QGCCachedTileSet::totalTileCountStr()
{
return QGCMapEngine::numberToString(_numTiles);
return QGCMapEngine::numberToString(_totalTileCount);
}
//-----------------------------------------------------------------------------
QString
QGCCachedTileSet::tilesSizeStr()
QGCCachedTileSet::totalTilesSizeStr()
{
return QGCMapEngine::bigSizeToString(_tilesSize);
return QGCMapEngine::bigSizeToString(_totalTileSize);
}
//-----------------------------------------------------------------------------
QString
QGCCachedTileSet::savedTilesStr()
QGCCachedTileSet::uniqueTileSizeStr()
{
return QGCMapEngine::numberToString(_savedTiles);
return QGCMapEngine::bigSizeToString(_uniqueTileSize);
}
//-----------------------------------------------------------------------------
QString
QGCCachedTileSet::savedSizeStr()
QGCCachedTileSet::uniqueTileCountStr()
{
return QGCMapEngine::bigSizeToString(_savedSize);
return QGCMapEngine::numberToString(_uniqueTileCount);
}
//-----------------------------------------------------------------------------
QString
QGCCachedTileSet::savedTileCountStr()
{
return QGCMapEngine::numberToString(_savedTileCount);
}
//-----------------------------------------------------------------------------
QString
QGCCachedTileSet::savedTileSizeStr()
{
return QGCMapEngine::bigSizeToString(_savedTileSize);
}
//-----------------------------------------------------------------------------
......@@ -103,12 +118,12 @@ QString
QGCCachedTileSet::downloadStatus()
{
if(_defaultSet) {
return tilesSizeStr();
return totalTilesSizeStr();
}
if(_numTiles == _savedTiles) {
return savedSizeStr();
if(_totalTileCount <= _savedTileCount) {
return savedTileSizeStr();
} else {
return savedSizeStr() + " / " + tilesSizeStr();
return savedTileSizeStr() + " / " + totalTilesSizeStr();
}
}
......@@ -128,8 +143,8 @@ QGCCachedTileSet::createDownloadTask()
if(_manager)
connect(task, &QGCMapTask::error, _manager, &QGCMapEngineManager::taskError);
getQGCMapEngine()->addTask(task);
emit numTilesChanged();
emit tilesSizeChanged();
emit totalTileCountChanged();
emit totalTilesSizeChanged();
_batchRequested = true;
}
......@@ -164,6 +179,7 @@ QGCCachedTileSet::_tileListFetched(QList<QGCTile *> tiles)
_noMoreTiles = true;
}
if(!tiles.size()) {
_doneWithDownload();
return;
}
//-- If this is the first time, create Network Manager
......@@ -176,23 +192,33 @@ QGCCachedTileSet::_tileListFetched(QList<QGCTile *> tiles)
_prepareDownload();
}
//-----------------------------------------------------------------------------
void QGCCachedTileSet::_doneWithDownload()
{
if(!_errorCount) {
_totalTileCount = _savedTileCount;
_totalTileSize = _savedTileSize;
//-- Too expensive to compute the real size now. Estimate it for the time being.
quint32 avg = _savedTileSize / _savedTileCount;
_uniqueTileSize = _uniqueTileCount * avg;
}
emit totalTileCountChanged();
emit totalTilesSizeChanged();
emit savedTileSizeChanged();
emit savedTileCountChanged();
emit uniqueTileSizeChanged();
_downloading = false;
emit downloadingChanged();
emit completeChanged();
}
//-----------------------------------------------------------------------------
void QGCCachedTileSet::_prepareDownload()
{
if(!_tilesToDownload.count()) {
//-- Are we done?
if(_noMoreTiles) {
if(!_errorCount) {
_numTiles = _savedTiles;
_tilesSize = _savedSize;
}
emit numTilesChanged();
emit tilesSizeChanged();
emit savedSizeChanged();
emit savedTilesChanged();
_downloading = false;
emit downloadingChanged();
emit completeChanged();
_doneWithDownload();
} else {
if(!_batchRequested)
createDownloadTask();
......@@ -253,15 +279,17 @@ QGCCachedTileSet::_networkReplyFinished()
QGCUpdateTileDownloadStateTask* task = new QGCUpdateTileDownloadStateTask(_id, QGCTile::StateComplete, hash);
getQGCMapEngine()->addTask(task);
//-- Updated cached (downloaded) data
_savedSize += image.size();
_savedTiles++;
emit savedSizeChanged();
emit savedTilesChanged();
_savedTileSize += image.size();
_savedTileCount++;
emit savedTileSizeChanged();
emit savedTileCountChanged();
//-- Update estimate
if(_savedTiles % 10 == 0) {
quint32 avg = _savedSize / _savedTiles;
_tilesSize = avg * _numTiles;
emit tilesSizeChanged();
if(_savedTileCount % 10 == 0) {
quint32 avg = _savedTileSize / _savedTileCount;
_totalTileSize = avg * _totalTileCount;
_uniqueTileSize = avg * _uniqueTileCount;
emit totalTilesSizeChanged();
emit uniqueTileSizeChanged();
}
}
//-- Setup a new download
......
......@@ -39,36 +39,38 @@ class QGCCachedTileSet : public QObject
{
Q_OBJECT
public:
QGCCachedTileSet (const QString& name, const QString& description);
QGCCachedTileSet (const QString& name);
~QGCCachedTileSet ();
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT)
Q_PROPERTY(QString mapTypeStr READ mapTypeStr CONSTANT)
Q_PROPERTY(double topleftLon READ topleftLon CONSTANT)
Q_PROPERTY(double topleftLat READ topleftLat CONSTANT)
Q_PROPERTY(double bottomRightLon READ bottomRightLon CONSTANT)
Q_PROPERTY(double bottomRightLat READ bottomRightLat CONSTANT)
Q_PROPERTY(int minZoom READ minZoom CONSTANT)
Q_PROPERTY(int maxZoom READ maxZoom CONSTANT)
Q_PROPERTY(quint32 numTiles READ numTiles NOTIFY numTilesChanged)
Q_PROPERTY(QString numTilesStr READ numTilesStr NOTIFY numTilesChanged)
Q_PROPERTY(quint64 tilesSize READ tilesSize NOTIFY tilesSizeChanged)
Q_PROPERTY(QString tilesSizeStr READ tilesSizeStr NOTIFY tilesSizeChanged)
Q_PROPERTY(quint32 savedTiles READ savedTiles NOTIFY savedTilesChanged)
Q_PROPERTY(QString savedTilesStr READ savedTilesStr NOTIFY savedTilesChanged)
Q_PROPERTY(quint64 savedSize READ savedSize NOTIFY savedSizeChanged)
Q_PROPERTY(QString savedSizeStr READ savedSizeStr NOTIFY savedSizeChanged)
Q_PROPERTY(QString downloadStatus READ downloadStatus NOTIFY savedSizeChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate CONSTANT)
Q_PROPERTY(bool complete READ complete NOTIFY completeChanged)
Q_PROPERTY(bool defaultSet READ defaultSet CONSTANT)
Q_PROPERTY(quint64 setID READ setID CONSTANT)
Q_PROPERTY(bool deleting READ deleting NOTIFY deletingChanged)
Q_PROPERTY(bool downloading READ downloading NOTIFY downloadingChanged)
Q_PROPERTY(quint32 errorCount READ errorCount NOTIFY errorCountChanged)
Q_PROPERTY(QString errorCountStr READ errorCountStr NOTIFY errorCountChanged)
Q_PROPERTY(QImage thumbNail READ thumbNail CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString mapTypeStr READ mapTypeStr CONSTANT)
Q_PROPERTY(double topleftLon READ topleftLon CONSTANT)
Q_PROPERTY(double topleftLat READ topleftLat CONSTANT)
Q_PROPERTY(double bottomRightLon READ bottomRightLon CONSTANT)
Q_PROPERTY(double bottomRightLat READ bottomRightLat CONSTANT)
Q_PROPERTY(int minZoom READ minZoom CONSTANT)
Q_PROPERTY(int maxZoom READ maxZoom CONSTANT)
Q_PROPERTY(quint32 totalTileCount READ totalTileCount NOTIFY totalTileCountChanged)
Q_PROPERTY(QString totalTileCountStr READ totalTileCountStr NOTIFY totalTileCountChanged)
Q_PROPERTY(quint64 totalTilesSize READ totalTilesSize NOTIFY totalTilesSizeChanged)
Q_PROPERTY(QString totalTilesSizeStr READ totalTilesSizeStr NOTIFY totalTilesSizeChanged)
Q_PROPERTY(quint32 uniqueTileCount READ uniqueTileCount NOTIFY uniqueTileCountChanged)
Q_PROPERTY(QString uniqueTileCountStr READ uniqueTileCountStr NOTIFY uniqueTileCountChanged)
Q_PROPERTY(quint64 uniqueTileSize READ uniqueTileSize NOTIFY uniqueTileSizeChanged)
Q_PROPERTY(QString uniqueTileSizeStr READ uniqueTileSizeStr NOTIFY uniqueTileSizeChanged)
Q_PROPERTY(quint32 savedTileCount READ savedTileCount NOTIFY savedTileCountChanged)
Q_PROPERTY(QString savedTileCountStr READ savedTileCountStr NOTIFY savedTileCountChanged)
Q_PROPERTY(quint64 savedTileSize READ savedTileSize NOTIFY savedTileSizeChanged)
Q_PROPERTY(QString savedTileSizeStr READ savedTileSizeStr NOTIFY savedTileSizeChanged)
Q_PROPERTY(QString downloadStatus READ downloadStatus NOTIFY savedTileSizeChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate CONSTANT)
Q_PROPERTY(bool complete READ complete NOTIFY completeChanged)
Q_PROPERTY(bool defaultSet READ defaultSet CONSTANT)
Q_PROPERTY(quint64 setID READ setID CONSTANT)
Q_PROPERTY(bool deleting READ deleting NOTIFY deletingChanged)
Q_PROPERTY(bool downloading READ downloading NOTIFY downloadingChanged)
Q_PROPERTY(quint32 errorCount READ errorCount NOTIFY errorCountChanged)
Q_PROPERTY(QString errorCountStr READ errorCountStr NOTIFY errorCountChanged)
Q_INVOKABLE void createDownloadTask ();
Q_INVOKABLE void resumeDownloadTask ();
......@@ -77,46 +79,49 @@ public:
void setManager (QGCMapEngineManager* mgr);
QString name () { return _name; }
QString description () { return _description; }
QString mapTypeStr () { return _mapTypeStr; }
double topleftLat () { return _topleftLat; }
double topleftLon () { return _topleftLon; }
double bottomRightLat () { return _bottomRightLat; }
double bottomRightLon () { return _bottomRightLon; }
quint32 numTiles () { return (quint32)_numTiles; }
QString numTilesStr ();
quint64 tilesSize () { return (quint64)_tilesSize; }
QString tilesSizeStr ();
quint32 savedTiles () { return (quint32)_savedTiles; }
QString savedTilesStr ();
quint64 savedSize () { return (quint64)_savedSize; }
QString savedSizeStr ();
quint32 totalTileCount () { return (quint32)_totalTileCount; }
QString totalTileCountStr ();
quint64 totalTilesSize () { return (quint64)_totalTileSize; }
QString totalTilesSizeStr ();
quint32 uniqueTileCount () { return _uniqueTileCount; }
QString uniqueTileCountStr ();
quint64 uniqueTileSize () { return _uniqueTileSize; }
QString uniqueTileSizeStr ();
quint32 savedTileCount () { return (quint32)_savedTileCount; }
QString savedTileCountStr ();
quint64 savedTileSize () { return (quint64)_savedTileSize; }
QString savedTileSizeStr ();
QString downloadStatus ();
int minZoom () { return _minZoom; }
int maxZoom () { return _maxZoom; }
QDateTime creationDate () { return _creationDate; }
quint64 id () { return _id; }
UrlFactory::MapType type () { return _type; }
bool complete () { return _defaultSet || (_numTiles == _savedTiles); }
bool complete () { return _defaultSet || (_totalTileCount <= _savedTileCount); }
bool defaultSet () { return _defaultSet; }
quint64 setID () { return _id; }
bool deleting () { return _deleting; }
bool downloading () { return _downloading; }
quint32 errorCount () { return _errorCount; }
QString errorCountStr ();
QImage thumbNail () { return _thumbNail; }
void setName (QString name) { _name = name; }
void setDescription (QString desc) { _description = desc; }
void setMapTypeStr (QString typeStr) { _mapTypeStr = typeStr; }
void setTopleftLat (double lat) { _topleftLat = lat; }
void setTopleftLon (double lon) { _topleftLon = lon; }
void setBottomRightLat (double lat) { _bottomRightLat = lat; }
void setBottomRightLon (double lon) { _bottomRightLon = lon; }
void setNumTiles (quint32 num) { _numTiles = num; }
void setTilesSize (quint64 size) { _tilesSize = size; }
void setSavedTiles (quint32 num) { _savedTiles = num; emit savedTilesChanged(); }
void setSavedSize (quint64 size) { _savedSize = size; emit savedSizeChanged(); }
void setTotalTileCount (quint32 num) { _totalTileCount = num; emit totalTileCountChanged(); }
void setUniqueTileCount (quint32 num) { _uniqueTileCount = num; }
void setUniqueTileSize (quint64 size) { _uniqueTileSize = size; }
void setTotalTileSize (quint64 size) { _totalTileSize = size; emit totalTilesSizeChanged(); }
void setSavedTileCount (quint32 num) { _savedTileCount = num; emit savedTileCountChanged(); }
void setSavedTileSize (quint64 size) { _savedTileSize = size; emit savedTileSizeChanged(); }
void setMinZoom (int zoom) { _minZoom = zoom; }
void setMaxZoom (int zoom) { _maxZoom = zoom; }
void setCreationDate (QDateTime date) { _creationDate = date; }
......@@ -125,15 +130,16 @@ public:
void setDefaultSet (bool def) { _defaultSet = def; }
void setDeleting (bool del) { _deleting = del; emit deletingChanged(); }
void setDownloading (bool down) { _downloading = down; }
void setThumbNail (const QImage& thumb) { _thumbNail = thumb; }
signals:
void deletingChanged ();
void downloadingChanged ();
void numTilesChanged ();
void tilesSizeChanged ();
void savedTilesChanged ();
void savedSizeChanged ();
void totalTileCountChanged ();
void uniqueTileCountChanged ();
void uniqueTileSizeChanged ();
void totalTilesSizeChanged ();
void savedTileCountChanged ();
void savedTileSizeChanged ();
void completeChanged ();
void errorCountChanged ();
......@@ -144,19 +150,21 @@ private slots:
private:
void _prepareDownload ();
void _doneWithDownload ();
private:
QString _name;
QString _description;
QString _mapTypeStr;
double _topleftLat;
double _topleftLon;
double _bottomRightLat;
double _bottomRightLon;
quint32 _numTiles;
quint64 _tilesSize;
quint32 _savedTiles;
quint64 _savedSize;
quint32 _totalTileCount;
quint64 _totalTileSize;
quint32 _uniqueTileCount;
quint64 _uniqueTileSize;
quint32 _savedTileCount;
quint64 _savedTileSize;
int _minZoom;
int _maxZoom;
bool _defaultSet;
......@@ -173,7 +181,6 @@ private:
bool _noMoreTiles;
bool _batchRequested;
QGCMapEngineManager* _manager;
QImage _thumbNail;
};
#endif // QGC_MAP_TILE_SET_H
......
......@@ -168,7 +168,9 @@ QGCCacheWorker::run()
_updateTimeout = SHORT_TIMEOUT;
}
if(!count || (time(0) - _lastUpdate > _updateTimeout)) {
_updateTotals();
if(_valid) {
_updateTotals();
}
}
} else {
//-- Wait a bit before shutting things down
......@@ -298,14 +300,11 @@ QGCCacheWorker::_getTileSets(QGCMapTask* mtask)
QGCFetchTileSetTask* task = static_cast<QGCFetchTileSetTask*>(mtask);
QSqlQuery query(*_db);
QString s = QString("SELECT * FROM TileSets ORDER BY defaultSet DESC, name ASC");
qCDebug(QGCTileCacheLog) << "_getTileSets(): " << s;
if(query.exec(s)) {
while(query.next()) {
QString name = query.value("name").toString();
QString desc = query.value("description").toString();
//-- Original database had description as NOT NULL
if(desc.isEmpty())
desc = " ";
QGCCachedTileSet* set = new QGCCachedTileSet(name, desc);
QGCCachedTileSet* set = new QGCCachedTileSet(name);
set->setId(query.value("setID").toULongLong());
set->setMapTypeStr(query.value("typeStr").toString());
set->setTopleftLat(query.value("topleftLat").toDouble());
......@@ -315,19 +314,9 @@ QGCCacheWorker::_getTileSets(QGCMapTask* mtask)
set->setMinZoom(query.value("minZoom").toInt());
set->setMaxZoom(query.value("maxZoom").toInt());
set->setType((UrlFactory::MapType)query.value("type").toInt());
set->setNumTiles(query.value("numTiles").toUInt());
set->setTilesSize(query.value("tilesSize").toULongLong());
set->setTotalTileCount(query.value("numTiles").toUInt());
set->setDefaultSet(query.value("defaultSet").toInt() != 0);
set->setCreationDate(QDateTime::fromTime_t(query.value("date").toUInt()));
//-- Load thumbnail (if not default set)
if(!set->defaultSet()) {
int w = query.value("thumbW").toInt();
int h = query.value("thumbH").toInt();
if(w && h) {
QByteArray ba = query.value("thumbNail").toByteArray();
set->setThumbNail(QImage((uchar*)(void*)ba.data(), w, h, QImage::Format_RGB32));
}
}
_updateSetTotals(set);
//-- Object created here must be moved to app thread to be used there
set->moveToThread(QApplication::instance()->thread());
......@@ -344,23 +333,52 @@ QGCCacheWorker::_updateSetTotals(QGCCachedTileSet* set)
{
if(set->defaultSet()) {
_updateTotals();
set->setSavedTiles(_totalCount);
set->setSavedSize(_totalSize);
set->setNumTiles(_defaultCount);
set->setTilesSize(_defaultSize);
set->setSavedTileCount(_totalCount);
set->setSavedTileSize(_totalSize);
set->setTotalTileCount(_defaultCount);
set->setTotalTileSize(_defaultSize);
return;
}
QSqlQuery subquery(*_db);
QString sq = QString("SELECT COUNT(size), SUM(size) FROM Tiles A INNER JOIN SetTiles B on A.tileID = B.tileID WHERE B.setID = %1").arg(set->id());
qCDebug(QGCTileCacheLog) << "_updateSetTotals(): " << sq;
if(subquery.exec(sq)) {
if(subquery.next()) {
set->setSavedTiles(subquery.value(0).toUInt());
set->setSavedSize(subquery.value(1).toULongLong());
//-- Update estimated size
if(set->savedTiles() > 10 && set->savedSize()) {
quint32 avg = set->savedSize() / set->savedTiles();
set->setTilesSize(avg * set->numTiles());
set->setSavedTileCount(subquery.value(0).toUInt());
set->setSavedTileSize(subquery.value(1).toULongLong());
qCDebug(QGCTileCacheLog) << "Set" << set->id() << "Totals:" << set->savedTileCount() << " " << set->savedTileSize() << "Expected: " << set->totalTileCount() << " " << set->totalTilesSize();
//-- Update (estimated) size
quint64 avg = UrlFactory::averageSizeForType(set->type());
if(set->totalTileCount() <= set->savedTileCount()) {
//-- We're done so the saved size is the total size
set->setTotalTileSize(set->savedTileSize());
} else {
//-- Otherwise we need to estimate it.
if(set->savedTileCount() > 10 && set->savedTileSize()) {
avg = set->savedTileSize() / set->savedTileCount();
}
set->setTotalTileSize(avg * set->totalTileCount());
}
//-- Now figure out the count for tiles unique to this set
quint32 ucount = 0;
quint64 usize = 0;
sq = QString("SELECT COUNT(size), SUM(size) FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A join SetTiles B on A.tileID = B.tileID WHERE B.setID = %1 GROUP by A.tileID HAVING COUNT(A.tileID) = 1)").arg(set->id());
if(subquery.exec(sq)) {
if(subquery.next()) {
//-- This is only accurate when all tiles are downloaded
ucount = subquery.value(0).toUInt();
usize = subquery.value(1).toULongLong();
}
}
//-- If we haven't downloaded it all, estimate size of unique tiles
quint32 expectedUcount = set->totalTileCount() - set->savedTileCount();
if(!ucount) {
usize = expectedUcount * avg;
} else {
expectedUcount = ucount;
}
set->setUniqueTileCount(expectedUcount);
set->setUniqueTileSize(usize);
}
}
}
......@@ -372,13 +390,15 @@ QGCCacheWorker::_updateTotals()
QSqlQuery query(*_db);
QString s;
s = QString("SELECT COUNT(size), SUM(size) FROM Tiles");
qCDebug(QGCTileCacheLog) << "_updateTotals(): " << s;
if(query.exec(s)) {
if(query.next()) {
_totalCount = query.value(0).toUInt();
_totalSize = query.value(1).toULongLong();
}
}
s = QString("SELECT COUNT(size), SUM(size) FROM Tiles A INNER JOIN SetTiles B on A.tileID = B.tileID WHERE B.setID = %1").arg(_getDefaultTileSet());
s = QString("SELECT COUNT(size), SUM(size) FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A join SetTiles B on A.tileID = B.tileID WHERE B.setID = %1 GROUP by A.tileID HAVING COUNT(A.tileID) = 1)").arg(_getDefaultTileSet());
qCDebug(QGCTileCacheLog) << "_updateTotals(): " << s;
if(query.exec(s)) {
if(query.next()) {
_defaultCount = query.value(0).toUInt();
......@@ -390,17 +410,17 @@ QGCCacheWorker::_updateTotals()
}
//-----------------------------------------------------------------------------
bool
QGCCacheWorker::_findTile(const QString hash)
quint64 QGCCacheWorker::_findTile(const QString hash)
{
quint64 tileID = 0;
QSqlQuery query(*_db);
QString s = QString("SELECT type FROM Tiles WHERE hash = \"%1\"").arg(hash);
QString s = QString("SELECT tileID FROM Tiles WHERE hash = \"%1\"").arg(hash);
if(query.exec(s)) {
if(query.next()) {
return true;
tileID = query.value(0).toULongLong();
}
}
return false;
return tileID;
}
//-----------------------------------------------------------------------------
......@@ -412,15 +432,10 @@ QGCCacheWorker::_createTileSet(QGCMapTask *mtask)
quint32 actual_count = 0;
QGCCreateTileSetTask* task = static_cast<QGCCreateTileSetTask*>(mtask);
QSqlQuery query(*_db);
QString desc = task->tileSet()->description();
//-- Original database had description as NOT NULL
if(desc.isEmpty())
desc = " ";
query.prepare("INSERT INTO TileSets("
"name, description, typeStr, topleftLat, topleftLon, bottomRightLat, bottomRightLon, minZoom, maxZoom, type, numTiles, tilesSize, thumbNail, thumbW, thumbH, date"
") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
"name, typeStr, topleftLat, topleftLon, bottomRightLat, bottomRightLon, minZoom, maxZoom, type, numTiles, date"
") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
query.addBindValue(task->tileSet()->name());
query.addBindValue(desc);
query.addBindValue(task->tileSet()->mapTypeStr());
query.addBindValue(task->tileSet()->topleftLat());
query.addBindValue(task->tileSet()->topleftLon());
......@@ -429,35 +444,28 @@ QGCCacheWorker::_createTileSet(QGCMapTask *mtask)
query.addBindValue(task->tileSet()->minZoom());
query.addBindValue(task->tileSet()->maxZoom());
query.addBindValue(task->tileSet()->type());
query.addBindValue(task->tileSet()->numTiles());
query.addBindValue(task->tileSet()->tilesSize());
if(task->tileSet()->thumbNail().isNull()) {
query.addBindValue(QByteArray(1,'\0'));
query.addBindValue(0);
query.addBindValue(0);
} else {
query.addBindValue(QByteArray((const char *)(void*)task->tileSet()->thumbNail().convertToFormat(QImage::Format_RGB32).bits(), task->tileSet()->thumbNail().byteCount()));
query.addBindValue(task->tileSet()->thumbNail().width());
query.addBindValue(task->tileSet()->thumbNail().height());
}
query.addBindValue(task->tileSet()->totalTileCount());
query.addBindValue(QDateTime::currentDateTime().toTime_t());
if(!query.exec()) {
qWarning() << "Map Cache SQL error (add tileSet into TileSets):" << query.lastError().text();
} else {
//-- Get just creted (auto-incremented) setID
//-- Get just created (auto-incremented) setID
quint64 setID = query.lastInsertId().toULongLong();
task->tileSet()->setId(setID);
//-- Prepare Download List
quint64 tileCount = 0;
for(int z = task->tileSet()->minZoom(); z <= task->tileSet()->maxZoom(); z++) {
QGCTileSet set = QGCMapEngine::getTileCount(z,
task->tileSet()->topleftLon(), task->tileSet()->topleftLat(),
task->tileSet()->bottomRightLon(), task->tileSet()->bottomRightLat(), task->tileSet()->type());
tileCount += set.tileCount;
UrlFactory::MapType type = task->tileSet()->type();
for(int x = set.tileX0; x <= set.tileX1; x++) {
for(int y = set.tileY0; y <= set.tileY1; y++) {
//-- See if tile is already downloaded
QString hash = QGCMapEngine::getTileHash(type, x, y, z);
if(!_findTile(hash)) {
quint64 tileID = _findTile(hash);
if(!tileID) {
//-- Set to download
query.prepare("INSERT OR IGNORE INTO TilesDownload(setID, hash, type, x, y, z, state) VALUES(?, ?, ?, ?, ? ,? ,?)");
query.addBindValue(setID);
......@@ -473,16 +481,18 @@ QGCCacheWorker::_createTileSet(QGCMapTask *mtask)
return;
} else
actual_count++;
} else {
//-- Tile already in the database. No need to dowload.
QString s = QString("INSERT OR IGNORE INTO SetTiles(tileID, setID) VALUES(%1, %2)").arg(tileID).arg(setID);
query.prepare(s);
if(!query.exec()) {
qWarning() << "Map Cache SQL error (add tile into SetTiles):" << query.lastError().text();
}
qCDebug(QGCTileCacheLog) << "_createTileSet() Already Cached HASH:" << hash;
}
}
}
}
//-- Now update how many tiles we actually have to download
quint64 actual_size = actual_count * UrlFactory::averageSizeForType(task->tileSet()->type());
QString s = QString("UPDATE TileSets SET numTiles = %1, tilesSize = %2 WHERE setID = %3").arg(actual_count).arg(actual_size).arg(task->tileSet()->setID());
if(!query.exec(s)) {
qWarning() << "Map Cache SQL error (set TilesDownload state):" << query.lastError().text();
}
//-- Done
_updateSetTotals(task->tileSet());
task->setTileSetSaved();
......@@ -560,7 +570,8 @@ QGCCacheWorker::_pruneCache(QGCMapTask* mtask)
QGCPruneCacheTask* task = static_cast<QGCPruneCacheTask*>(mtask);
QSqlQuery query(*_db);
QString s;
s = QString("SELECT tileID, size, hash FROM Tiles WHERE tileID IN (SELECT tileID FROM SetTiles WHERE setID = %1) ORDER BY DATE ASC LIMIT 128").arg(_getDefaultTileSet());
//-- Select tiles in default set only, sorted by oldest.
s = QString("SELECT tileID, size, hash FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A join SetTiles B on A.tileID = B.tileID WHERE B.setID = %1 GROUP by A.tileID HAVING COUNT(A.tileID) = 1) ORDER BY DATE ASC LIMIT 128").arg(_getDefaultTileSet());
qint64 amount = (qint64)task->amount();
QList<quint64> tlist;
if(query.exec(s)) {
......@@ -590,7 +601,8 @@ QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask)
QGCDeleteTileSetTask* task = static_cast<QGCDeleteTileSetTask*>(mtask);
QSqlQuery query(*_db);
QString s;
s = QString("DELETE FROM Tiles WHERE tileID IN (SELECT tileID FROM SetTiles WHERE setID = %1)").arg(task->setID());
//-- Only delete tiles unique to this set
s = QString("DELETE FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A JOIN SetTiles B ON A.tileID = B.tileID WHERE B.setID = %1 GROUP BY A.tileID HAVING COUNT(A.tileID) = 1)").arg(task->setID());
query.exec(s);
s = QString("DELETE FROM TilesDownload WHERE setID = %1").arg(task->setID());
query.exec(s);
......@@ -672,7 +684,6 @@ QGCCacheWorker::_createDB()
"CREATE TABLE IF NOT EXISTS TileSets ("
"setID INTEGER PRIMARY KEY NOT NULL, "
"name TEXT NOT NULL UNIQUE, "
"description TEXT, "
"typeStr TEXT, "
"topleftLat REAL DEFAULT 0.0, "
"topleftLon REAL DEFAULT 0.0, "
......@@ -682,11 +693,7 @@ QGCCacheWorker::_createDB()
"maxZoom INTEGER DEFAULT 3, "
"type INTEGER DEFAULT -1, "
"numTiles INTEGER DEFAULT 0, "
"tilesSize INTEGER DEFAULT 0, "
"defaultSet INTEGER DEFAULT 0, "
"thumbNail BLOB NULL, "
"thumbW INTEGER DEFAULT 0, "
"thumbH INTEGER DEFAULT 0, "
"date INTEGER DEFAULT 0)"))
{
qWarning() << "Map Cache SQL error (create TileSets db):" << query.lastError().text();
......@@ -721,9 +728,8 @@ QGCCacheWorker::_createDB()
QString s = QString("SELECT name FROM TileSets WHERE name = \"%1\"").arg(kDefaultSet);
if(query.exec(s)) {
if(!query.next()) {
query.prepare("INSERT INTO TileSets(name, description, defaultSet, date) VALUES(?, ?, ?, ?)");
query.prepare("INSERT INTO TileSets(name, defaultSet, date) VALUES(?, ?, ?)");
query.addBindValue(kDefaultSet);
query.addBindValue("System wide tile cache");
query.addBindValue(1);
query.addBindValue(QDateTime::currentDateTime().toTime_t());
if(!query.exec()) {
......
......@@ -60,7 +60,7 @@ private:
void _resetCacheDatabase (QGCMapTask* mtask);
void _pruneCache (QGCMapTask* mtask);
bool _findTile (const QString hash);
quint64 _findTile (const QString hash);
bool _findTileSetID (const QString name, quint64& setID);
void _updateSetTotals (QGCCachedTileSet* set);
bool _init ();
......
......@@ -127,10 +127,10 @@ QGCMapEngineManager::_tileSetFetched(QGCCachedTileSet* tileSet)
//-----------------------------------------------------------------------------
void
QGCMapEngineManager::startDownload(const QString& name, const QString& description, const QString& mapType, const QImage& image)
QGCMapEngineManager::startDownload(const QString& name, const QString& mapType)
{
if(_totalSet.tileSize) {
QGCCachedTileSet* set = new QGCCachedTileSet(name, description);
QGCCachedTileSet* set = new QGCCachedTileSet(name);
set->setMapTypeStr(mapType);
set->setTopleftLat(_topleftLat);
set->setTopleftLon(_topleftLon);
......@@ -138,11 +138,9 @@ QGCMapEngineManager::startDownload(const QString& name, const QString& descripti
set->setBottomRightLon(_bottomRightLon);
set->setMinZoom(_minZoom);
set->setMaxZoom(_maxZoom);
set->setTilesSize(_totalSet.tileSize);
set->setNumTiles(_totalSet.tileCount);
set->setTotalTileSize(_totalSet.tileSize);
set->setTotalTileCount(_totalSet.tileCount);
set->setType(QGCMapEngine::getTypeFromName(mapType));
if(!image.isNull())
set->setThumbNail(image);
QGCCreateTileSetTask* task = new QGCCreateTileSetTask(set);
//-- Create Tile Set (it will also create a list of tiles to download)
connect(task, &QGCCreateTileSetTask::tileSetSaved, this, &QGCMapEngineManager::_tileSetSaved);
......@@ -329,10 +327,10 @@ QGCMapEngineManager::_updateTotals(quint32 totaltiles, quint64 totalsize, quint3
QGCCachedTileSet* set = qobject_cast<QGCCachedTileSet*>(_tileSets.get(i));
Q_ASSERT(set);
if (set->defaultSet()) {
set->setSavedSize(totalsize);
set->setSavedTiles(totaltiles);
set->setNumTiles(defaulttiles);
set->setTilesSize(defaultsize);
set->setSavedTileSize(totalsize);
set->setSavedTileCount(totaltiles);
set->setTotalTileCount(defaulttiles);
set->setTotalTileSize(defaultsize);
return;
}
}
......
......@@ -49,7 +49,7 @@ public:
Q_INVOKABLE void loadTileSets ();
Q_INVOKABLE void updateForCurrentView (double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString& mapName);
Q_INVOKABLE void startDownload (const QString& name, const QString& description, const QString& mapType, const QImage& image = QImage());
Q_INVOKABLE void startDownload (const QString& name, const QString& mapType);
Q_INVOKABLE void saveSetting (const QString& key, const QString& value);
Q_INVOKABLE QString loadSetting (const QString& key, const QString& defaultValue);
Q_INVOKABLE void deleteTileSet (QGCCachedTileSet* tileSet);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment