提交 6c0b6ac0 编写于 作者: 丁劲犇's avatar 丁劲犇 😸

1. add a tile expire days prop. old tiles will be refreshed as needed.

2. add OCX interface to set local cache path and tile expire value.
Signed-off-by: 丁劲犇's avatargoldenhawking <goldenhawking@163.com>
上级 e6f1a8b9
......@@ -2,6 +2,7 @@
#include <QCoreApplication>
#include <QPainter>
#include <QSettings>
#include <QFileInfo>
#include "layer_tiles.h"
#include "tilesviewer.h"
namespace QTVOSM{
......@@ -12,7 +13,8 @@ namespace QTVOSM{
\param parent parent objects
*/
layer_tiles::layer_tiles(QObject *parent) :
QObject(parent)
QObject(parent),
m_nCacheExpireDays(30)
{
m_bActive = false;
m_bVisible = false;
......@@ -46,6 +48,12 @@ namespace QTVOSM{
settings.setValue(QString("settings/LocalCache_%1").arg(get_name()), m_strLocalCache);
emit cacheChanged(cache);
}
void layer_tiles::setCacheExpireDays(int nCacheExpireDays)
{
m_nCacheExpireDays = nCacheExpireDays;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
settings.setValue(QString("settings/CacheExpireDays_%1").arg(get_name()), m_nCacheExpireDays);
}
/*!
\brief When the tileviewer enter its paint_event function, this callback will be called.
......@@ -75,13 +83,10 @@ namespace QTVOSM{
int nCurrRightX = ceil((nCenter_X+m_pViewer->width()/2)/256.0);
int nCurrBottomY = ceil((nCenter_Y+m_pViewer->height()/2)/256.0);
//!2.4 draw images
bool needreg = false;
int reg_left = sz_whole_idx,reg_right = -1,reg_bottom = -1,reg_top = sz_whole_idx;
//!2.5 a repeat from tileindx left to right.
//!2.4 a repeat from tileindx left to right.
for (int col = nCurrLeftX;col<=nCurrRightX;col++)
{
//!2.5.1 a repeat from tileindx top to bottom.
//!2.4.1 a repeat from tileindx top to bottom.
for (int row = nCurrTopY;row<=nCurrBottomY;row++)
{
QImage image_source;
......@@ -92,16 +97,8 @@ namespace QTVOSM{
req_col = col % sz_whole_idx;
if (col<0)
req_col = (col + (1-col/sz_whole_idx)*sz_whole_idx) % sz_whole_idx;
//!2.5.2 call getTileImage to query the image .
if (false==this->getTileImage(m_pViewer->level(),req_col,req_row,image_source))
{
needreg = true;
if (reg_left>=req_col) reg_left = req_col;
if (reg_right<=req_col) reg_right = req_col;
if (reg_top>=req_row) reg_top = req_row;
if (reg_bottom<=req_row) reg_bottom = req_row;
}
else
//!2.4.2 call getTileImage to query the image .
if (true==this->getTileImage(m_pViewer->level(),req_col,req_row,image_source))
{
//bitblt
int nTileOffX = (col-nCenX)*256;
......@@ -117,9 +114,6 @@ namespace QTVOSM{
}
}
}
//!2.6 if some image is not exists in local cache, tried to download
if (needreg==true)
RegImages(reg_left,reg_right,reg_top,reg_bottom,m_pViewer->level());
}
}
......@@ -210,13 +204,17 @@ namespace QTVOSM{
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
m_strServerURL = settings.value(QString("settings/ServerURL_%1").arg(m_name),"http://c.tile.openstreetmap.org/%1/%2/%3.png").toString();
m_strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(m_name), QCoreApplication::applicationDirPath() +"/OSMCache").toString();
m_nCacheExpireDays = settings.value(QString("settings/CacheExpireDays_%1").arg(m_name), 30).toInt();
return this;
}
QWidget * layer_tiles::load_prop_window()
{
if (!m_propPage)
{
m_propPage = new layer_tiles_page(this,0);
connect (m_downloader,&urlDownloader::evt_message,m_propPage,&layer_tiles_page::slot_message,Qt::QueuedConnection);
}
return m_propPage;
}
......@@ -250,22 +248,27 @@ namespace QTVOSM{
strVal += ".png";
bool res = true;
bool needReg = false;
if (res)
{
QByteArray array_out;
QFile file(strVal);
QFileInfo info(strVal);
if (file.open(QIODevice::ReadOnly)==true)
{
array_out = file.readAll();
image = QImage::fromData(array_out);
if (image.isNull()==true)
res = false;
res = false, needReg = true;
else if (m_nCacheExpireDays > 0 && info.lastModified().secsTo(QDateTime::currentDateTime()) > this->m_nCacheExpireDays * 3600 * 24 )
needReg = true;
}
else
res = false;
res = false, needReg = true;
}
if (needReg)
RegImages(nX,nY,nLevel);
return res;
}
void layer_tiles::UpdateLayer()
......@@ -306,46 +309,32 @@ namespace QTVOSM{
\brief RegImages will download images from tile address.
\fn layer_tiles::RegImages
\param nLeft Left col (x) tile id og this level nLevel
\param nRight Right col (x) tile id og this level nLevel
\param nTop Top row (y) tile id og this level nLevel
\param nBottom Bottom row (y) tile id og this level nLevel
\param nX col (x) tile id og this level nLevel
\param nY row (y) tile id og this level nLevel
\param nLevel current level. In osm, nlevel often take 0~18
\return bool succeeded.
*/
bool layer_tiles::RegImages(int nLeft,int nRight,int nTop,int nBottom,int nLevel)
bool layer_tiles::RegImages(int nX, int nY,int nLevel)
{
if (!m_pViewer || m_bVisible==false) return true;
if (m_bconnected==false)
return true;
for (int nX = nLeft; nX <=nRight ; ++nX)
{
for (int nY = nTop; nY <= nBottom ; ++nY)
{
QString LFix;
QString strSourceUrl, strDestinDir, strFileName;
LFix += '/';
LFix += QString::number(nLevel,10);
LFix += '/';
LFix += QString::number(nX,10);
strDestinDir = m_strLocalCache + "/" + m_name + "/" + LFix;
LFix += '/';
LFix += QString::number(nY,10);
LFix += ".png";
strFileName = QString::number(nY,10);
strFileName += ".png";
strSourceUrl = m_strServerURL.arg(nLevel).arg(nX).arg(nY);
QString LFix;
QString strSourceUrl, strDestinDir, strFileName;
LFix += '/';
LFix += QString::number(nLevel,10);
LFix += '/';
LFix += QString::number(nX,10);
strDestinDir = m_strLocalCache + "/" + m_name + "/" + LFix;
LFix += '/';
LFix += QString::number(nY,10);
LFix += ".png";
strFileName = QString::number(nY,10);
strFileName += ".png";
strSourceUrl = m_strServerURL.arg(nLevel).arg(nX).arg(nY);
this->m_downloader->addDownloadUrl(strSourceUrl,strDestinDir,strFileName);
}
}
this->m_downloader->addDownloadUrl(strSourceUrl,strDestinDir,strFileName);
return true;
}
QVector< tag_download_tasks > layer_tiles::current_tasks()
{
if (m_downloader)
return m_downloader->current_tasks();
else
return QVector< tag_download_tasks >();
}
}
......@@ -26,12 +26,11 @@ namespace QTVOSM{
QString serverUrl() {return m_strServerURL; }
QString localCache() {return m_strLocalCache; }
int cacheExpireDays() {return m_nCacheExpireDays; }
bool isConnected(){return m_bconnected;}
void connectToTilesServer(bool bconnected);
void UpdateLayer();
//!Get downloadTask
QVector< tag_download_tasks > current_tasks();
public:
virtual layer_interface * load_initial_plugin(QString strSLibPath,viewer_interface * viewer);
virtual QWidget * load_prop_window();
......@@ -63,6 +62,7 @@ namespace QTVOSM{
QString m_name;
private:
bool m_bconnected;
int m_nCacheExpireDays;
QString m_strLocalCache;
QString m_strServerURL;
//The download tools
......@@ -75,10 +75,11 @@ namespace QTVOSM{
//! get single tile from web service
bool getTileImage(int nLevel,int nX,int nY,QImage & image);
//! regisit images to web service
bool RegImages(int nLeft,int nRight,int nTop,int nBottom,int nLevel);
bool RegImages(int nX, int nY,int nLevel);
public slots:
void setServerUrl(QString url);
void setLocalCache(QString cache);
void setCacheExpireDays(int nCacheExpireDays);
signals:
void connected(bool);
void svrurlChanged(QString);
......
......@@ -10,23 +10,21 @@ namespace QTVOSM{
layer_tiles_page::layer_tiles_page(layer_tiles * layer,QWidget *parent) :
QWidget(parent),
m_pLayer(layer),
ui(new Ui::layer_tiles_page),
m_nTimerID(startTimer(1000))
ui(new Ui::layer_tiles_page)
{
ui->setupUi(this);
//Get Cache Address
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
QString strServerURL = settings.value(QString("settings/ServerURL_%1").arg(layer->get_name()),"http://c.tile.openstreetmap.org/%1/%2/%3.png").toString();
QString strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(layer->get_name()), QCoreApplication::applicationDirPath() +"/OSMCache").toString();
int nCacheExpireDays = settings.value(QString("settings/CacheExpireDays_%1").arg(layer->get_name()), 30).toInt();
ui->lineEdit->setText(strLocalCache);
ui->lineEdit_addressUrl->setText(strServerURL);
ui->spinBox_cacheExpireDays->setValue(nCacheExpireDays);
this->setWindowTitle(layer->get_name());
//the pending tasks model
m_pPendingTasksModel = new QStandardItemModel(0,3,this);
m_pPendingTasksModel->setHeaderData(0,Qt::Horizontal,tr("url"));
m_pPendingTasksModel->setHeaderData(1,Qt::Horizontal,tr("destin dir"));
m_pPendingTasksModel->setHeaderData(2,Qt::Horizontal,tr("filename"));
ui->tableView_pendingTasks->setModel(m_pPendingTasksModel);
m_pPendingTasksModel = new QStandardItemModel(this);
ui->listView_messages->setModel(m_pPendingTasksModel);
connect (layer, &layer_tiles::connected ,this->ui->checkBox_connect, &QCheckBox::setChecked);
connect (layer, &layer_tiles::svrurlChanged ,this->ui->lineEdit_addressUrl, &QLineEdit::setText);
......@@ -54,31 +52,19 @@ namespace QTVOSM{
{
m_pLayer->setLocalCache(ui->lineEdit->text());
m_pLayer->setServerUrl(ui->lineEdit_addressUrl->text());
m_pLayer->setCacheExpireDays(ui->spinBox_cacheExpireDays->value());
m_pLayer->UpdateLayer();
}
void layer_tiles_page::timerEvent(QTimerEvent * e)
{
if (e->timerId()==m_nTimerID)
{
killTimer(m_nTimerID);
QVector<tag_download_tasks> vec_tk = m_pLayer->current_tasks();
//qDebug()<<vec_tk.size();
foreach (const tag_download_tasks & t, vec_tk)
{
QList<QStandardItem *> row;
row<<new QStandardItem(t.str_url);
row<<new QStandardItem(t.str_destinDir);
row<<new QStandardItem(t.str_destinFile);
m_pPendingTasksModel->appendRow(row);
}//end for each task
if (m_pPendingTasksModel->rowCount()>256)
m_pPendingTasksModel->removeRows(0,128);
m_nTimerID = startTimer(1000);
}//end if timer
}
void layer_tiles_page::on_checkBox_connect_clicked(bool ps)
{
m_pLayer->connectToTilesServer(ps);
}
void layer_tiles_page::slot_message(QString message)
{
m_pPendingTasksModel->appendRow(new QStandardItem(message));
if (m_pPendingTasksModel->rowCount()>256)
m_pPendingTasksModel->removeRows(0,m_pPendingTasksModel->rowCount()-256);
}
}
......@@ -23,15 +23,13 @@ namespace QTVOSM{
~layer_tiles_page();
//re-translat
void reTransUI();
protected:
void timerEvent(QTimerEvent * e);
private:
int m_nTimerID;
Ui::layer_tiles_page *ui ;
layer_tiles * m_pLayer ;
QStandardItemModel * m_pPendingTasksModel;
public slots:
void slot_message(QString);
protected slots:
void on_toolButton_browser_clicked();
void on_pushButton_apply_clicked();
void on_checkBox_connect_clicked(bool);
......
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>332</width>
<height>305</height>
<height>334</height>
</rect>
</property>
<property name="windowTitle">
......@@ -21,19 +21,12 @@
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Pending tasks</string>
<string>messages</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableView_pendingTasks">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QListView" name="listView_messages"/>
</item>
<item>
<widget class="QLabel" name="label">
......@@ -65,6 +58,34 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Cahce Expire</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_cacheExpireDays">
<property name="maximum">
<number>365</number>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Days</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
......@@ -101,6 +122,7 @@
</widget>
<resources>
<include location="../resource/resource.qrc"/>
<include location="../resource/resource.qrc"/>
</resources>
<connections/>
</ui>
......@@ -24,6 +24,8 @@ namespace QTVOSM{
bool allFinished = false;
bool succeeded = false;
m_mutex_protect.lock();
QString errMsg;
QString sourceUrl;
if (m_map_pendingTasks.contains(rply)==true)
{
const tag_download_tasks & tk = m_map_pendingTasks[rply];
......@@ -41,11 +43,12 @@ namespace QTVOSM{
file.write(rply->readAll());
file.close();
succeeded = true;
sourceUrl = m_map_pendingTasks[rply].str_url;
}
}
else
{
qCritical()<<rply->errorString();
qCritical()<<(errMsg = rply->errorString());
}
QString uniqueKey = tk.str_url + ":" + tk.str_destinDir +":" + tk.str_destinFile;
m_set_tileAddress.remove(uniqueKey);
......@@ -63,6 +66,18 @@ namespace QTVOSM{
emit evt_doNextJob();
if (allFinished == true && succeeded)
emit evt_all_taskFinished();
if (succeeded)
{
QString strMsg = tr("task succeeded: %1").arg(sourceUrl);
emit evt_message(strMsg);
}
else
{
QString strMsg = tr("task failed: %1,msg %2").arg(sourceUrl).arg(errMsg);
emit evt_message(strMsg);
}
}
void urlDownloader::newTaskAdded()
......@@ -108,14 +123,7 @@ namespace QTVOSM{
m_mutex_protect.unlock();
if (bNeedEmit)
emit evt_doNextJob();
}
QVector<tag_download_tasks> urlDownloader::current_tasks()
{
QVector<tag_download_tasks> ret;
m_mutex_protect.lock();
foreach (tag_download_tasks t, m_listTask)
ret.push_back(t);
m_mutex_protect.unlock();
return ret;
QString strMsg = tr("Add task %1").arg(sourceUrl);
emit evt_message(strMsg);
}
}
......@@ -32,8 +32,6 @@ namespace QTVOSM{
urlDownloader(QObject * pParent, int nMaxAsynThread = 5);
~urlDownloader();
void addDownloadUrl(const QString &sourceUrl,const QString & DestinDir, const QString & filename,bool newerFirst = true);
//view CurrentTasks
QVector<tag_download_tasks> current_tasks();
protected:
//the QSet to avoid repeatedly download same tile.
QSet<QString> m_set_tileAddress;
......@@ -48,6 +46,7 @@ namespace QTVOSM{
signals:
void evt_all_taskFinished();
void evt_doNextJob();
void evt_message(QString);
};
}
#endif // URLDOWNLOADER_H
......@@ -85,6 +85,60 @@ QString qtaxviewer_planetosm::osm_get_remote_address(QString layerName) const
return res;
}
QString qtaxviewer_planetosm::osm_get_local_cache(QString layerName) const
{
QString res = "./OSMCache";
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer(layerName);
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
res = lt->localCache();
}
return res;
}
void qtaxviewer_planetosm::osm_set_local_cache (QString layerName, QString addr)
{
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer(layerName);
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
lt->setLocalCache(addr);
}
}
int qtaxviewer_planetosm::osm_get_cache_expire_days(QString layerName)
{
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer(layerName);
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
return lt->cacheExpireDays();
}
return 0;
}
int qtaxviewer_planetosm::osm_set_cache_expire_days(QString layerName,int days)
{
int res = 0;
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer(layerName);
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
{
lt->setCacheExpireDays(days);
res = days;
}
}
return res;
}
/*!
\brief This function is equal to check the "auto download" checkbox in UI
when the tile is not exist in local cache, layer will start a
......
......@@ -36,6 +36,10 @@ public:
public slots:
QString osm_get_remote_address(QString layerName) const;
void osm_set_remote_address (QString layerName, QString addr);
QString osm_get_local_cache(QString layerName) const;
void osm_set_local_cache (QString layerName, QString addr);
int osm_get_cache_expire_days(QString layerName);
int osm_set_cache_expire_days(QString layerName,int days);
void osm_set_auto_download (QString layerName, int flag);
int osm_get_auto_download(QString layerName);
//Navigate
......
......@@ -397,3 +397,14 @@ void testcontainer::on_pushButton_test_request_clicked()
res.replace("=","\t=");
QMessageBox::information(this,"geomarker1::props",res);
}
void testcontainer::on_pushButton_test_cache_clicked()
{
QString res = ui->axWidget_map1->dynamicCall("osm_get_local_cache(QString)","OSM").toString();
QMessageBox::information(this,"geomarker1::osm_get_local_cache",res);
res = ui->axWidget_map1->dynamicCall("osm_set_local_cache(QString, QString)","OSM","/OSMCache").toString();
QMessageBox::information(this,"geomarker1::osm_set_local_cache",res);
res = ui->axWidget_map1->dynamicCall("osm_get_cache_expire_days(QString)","OSM").toString();
QMessageBox::information(this,"geomarker1::osm_get_cache_expire_days",res);
res = ui->axWidget_map1->dynamicCall("osm_set_cache_expire_days(QString,int)","OSM",res.toInt()+1).toString();
QMessageBox::information(this,"geomarker1::osm_get_cache_expire_days",res);
}
......@@ -26,6 +26,7 @@ private:
protected slots:
void slot_message(QString);
void on_pushButton_test_adds_clicked();
void on_pushButton_test_cache_clicked();
void on_pushButton_test_autodl_clicked();
void on_pushButton_test_navigate_clicked();
void on_pushButton_test_layers_clicked();
......
......@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>811</width>
<width>892</width>
<height>600</height>
</rect>
</property>
......@@ -80,6 +80,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_test_cache">
<property name="text">
<string>test_cache</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_test_autodl">
<property name="text">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册