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

We improved the plugin mechanism , enable active-x bindings in windows.

上级 5a3ad8d6
TEMPLATE = subdirs
SUBDIRS += qtviewer_planetosm \
qtvplugin_grid
TEMPLATE = subdirs
SUBDIRS += \
qtviewer_planetosm \
qtvplugin_grid \
qtvplugin_geomarker
win32:{
SUBDIRS +=\
qtaxviewer_planetosm\
test_container
qtaxviewer_planetosm.file = qtviewer_planetosm/qtaxviewer_planetosm.pro
}
#include "osm_frame_widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
osm_frame_widget w;
w.show();
return a.exec();
}
#include "osm_frame_widget.h"
#include <QApplication>
#include <QLibraryInfo>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);
QTranslator appTranslator;
QString strTransLocalFile =
QCoreApplication::applicationDirPath()+"/" +
QCoreApplication::applicationName()+"_"+
QLocale::system().name()+".qm";
appTranslator.load(strTransLocalFile );
app.installTranslator(&appTranslator);
osm_frame_widget w;
w.show();
return app.exec();
}
#include "osm_frame_widget.h"
#include "ui_osm_frame_widget.h"
#include <QDir>
#include <QtPlugin>
#include "osmtiles/layer_tiles.h"
#include "osmtiles/layer_browser.h"
#include <QModelIndexList>
#include <QModelIndex>
#include <QPluginLoader>
osm_frame_widget::osm_frame_widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::osm_frame_widget)
{
ui->setupUi(this);
m_pLayerDispMod = new QStandardItemModel(this);
m_pLayerDispMod->setColumnCount(3);
m_pLayerDispMod->setHeaderData(0,Qt::Horizontal,QString(tr("name")));
m_pLayerDispMod->setHeaderData(1,Qt::Horizontal,QString(tr("active")));
m_pLayerDispMod->setHeaderData(2,Qt::Horizontal,QString(tr("visible")));
ui->tableView_layers->setModel(m_pLayerDispMod);
connect(ui->widget_mainMap,&tilesviewer::evt_level_changed,ui->dial_zoom,&QDial::setValue);
connect(ui->dial_zoom,&QDial::valueChanged,ui->widget_mainMap,&tilesviewer::setLevel);
//add an osm layer
layer_tiles * pOSMTile = new layer_tiles(ui->widget_mainMap);
pOSMTile->cb_setName("BackgroundOSM");
pOSMTile->cb_setActive(true);
pOSMTile->cb_setVisible(true);
pOSMTile->connectToTilesServer(true);
AppendLayer(pOSMTile);
//add an sat layer
layer_tiles * pSatTile = new layer_tiles(ui->widget_mainMap);
pSatTile->cb_setName("BackgroundSAT");
pSatTile->connectToTilesServer(true);
AppendLayer(pSatTile);
//add single layer to browser
layer_browser * pOSMTileBr = new layer_browser(ui->browserView);
pOSMTileBr->cb_setName("BackgroundOSM");
ui->browserView->addLayer(pOSMTileBr);
//connect center change event
connect (ui->widget_mainMap,&tilesviewer::evt_center_changed,ui->browserView,&tilesviewer::setBrCenterLLA);
connect (ui->browserView,&tilesviewer::evt_center_changed,ui->widget_mainMap,&tilesviewer::setCenterLLA);
connect (ui->widget_mainMap,&tilesviewer::evt_level_changed,ui->browserView,&tilesviewer::setBrLevel);
EnumPlugins();
UpdateLayerTable();
}
void osm_frame_widget::UpdateLayerTable()
{
QVector<QString> names = ui->widget_mainMap->layerNames();
QVector<bool> activities = ui->widget_mainMap->layerActivities();
QVector<bool> visibles = ui->widget_mainMap->layerVisibilities();
int nItems = names.size();
if (m_pLayerDispMod->rowCount()>0)
m_pLayerDispMod->removeRows(0,m_pLayerDispMod->rowCount());
for (int i=0;i<nItems;++i)
{
m_pLayerDispMod->appendRow(new QStandardItem(names[nItems-1-i]));
m_pLayerDispMod->setData(m_pLayerDispMod->index(i,1),activities[nItems-1-i]);
m_pLayerDispMod->setData(m_pLayerDispMod->index(i,2),visibles[nItems-1-i]);
}
}
void osm_frame_widget::AppendLayer(layer_interface * interface)
{
if (false==ui->widget_mainMap->addLayer(interface))
return;
QWidget * wig = interface->cb_create_propWindow();
if (wig)
{
m_layerPropPages[interface] = wig;
ui->tabWidget_main->addTab(wig,interface->cb_name());
}
}
osm_frame_widget::~osm_frame_widget()
{
delete ui;
}
void osm_frame_widget::EnumPlugins()
{
QDir pluginsDir(QApplication::applicationDirPath());
QStringList filters;
filters << "*.dll";
pluginsDir.setNameFilters(filters);
//查找文件
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();//尝试调入Plugin
if (plugin) {
layer_interface * pPlugin= qobject_cast<layer_interface *>(plugin);//动态类型转换
if (pPlugin)//具有这个接口
{
//加入图层
AppendLayer(pPlugin);
}
}
}
return ;
}
void osm_frame_widget::on_pushButton_visible_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
int nItems = layers.size();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
layers[nItems - 1 -row]->cb_setVisible(true);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_hide_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
layers[nItems - 1 -row]->cb_setVisible(false);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveDown_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerUp(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveBtm_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerTop(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveUp_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerDown(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveTop_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerBottom(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_active_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
for (int i=0;i<layers.size();++i)
layers[i]->cb_setActive((i==(nItems - 1 -row))?true:false);
UpdateLayerTable();
}
}
}
#include "osm_frame_widget.h"
#include "ui_osm_frame_widget.h"
#include <QDir>
#include <QtPlugin>
#include "osmtiles/layer_tiles.h"
#include "osmtiles/layer_browser.h"
#include <QModelIndexList>
#include <QModelIndex>
#include <QPluginLoader>
#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>
#include "osmtiles/viewer_interface.h"
QMutex osm_frame_widget::m_mutex_proteced;
/*!
\brief osm_frame_widget is the main widget of this control.
in this constructor, 2 OUTER message will be fired.
\fn osm_frame_widget::osm_frame_widget
\param parent
*/
osm_frame_widget::osm_frame_widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::osm_frame_widget)
{
m_mutex_proteced.lock();
QTVOSM_DEBUG("The osm_frame_widget class constructing...");
ui->setupUi(this);
m_pLayerDispMod = new QStandardItemModel(this);
m_pLayerDispMod->setColumnCount(3);
m_pLayerDispMod->setHeaderData(0,Qt::Horizontal,QString(tr("name")));
m_pLayerDispMod->setHeaderData(1,Qt::Horizontal,QString(tr("active")));
m_pLayerDispMod->setHeaderData(2,Qt::Horizontal,QString(tr("visible")));
ui->tableView_layers->setModel(m_pLayerDispMod);
connect(ui->widget_mainMap,&tilesviewer::evt_level_changed,ui->dial_zoom,&QDial::setValue);
connect(ui->dial_zoom,&QDial::valueChanged,ui->widget_mainMap,&tilesviewer::setLevel);
//add an osm layer
layer_tiles * pOSMTile = new layer_tiles(ui->widget_mainMap);
pOSMTile->set_name("OSM");
pOSMTile->set_active(true);
pOSMTile->set_visible(true);
//pOSMTile->connectToTilesServer(true);
AppendLayer(QCoreApplication::applicationFilePath(),pOSMTile);
/*
//add an sat layer
layer_tiles * pSatTile = new layer_tiles(ui->widget_mainMap);
pSatTile->set_name("SAT");
//pSatTile->connectToTilesServer(true);
AppendLayer(QCoreApplication::applicationFilePath(),pSatTile);
*/
//add single layer to browser
layer_browser * pOSMTileBr = new layer_browser(ui->browserView);
pOSMTileBr->set_name("OSM");
pOSMTileBr->load_initial_plugin(QCoreApplication::applicationFilePath(),ui->browserView);
ui->browserView->addLayer(pOSMTileBr);
//connect center change event
connect (ui->widget_mainMap,&tilesviewer::evt_center_changed,ui->browserView,&tilesviewer::setBrCenterLLA);
connect (ui->browserView,&tilesviewer::evt_center_changed,ui->widget_mainMap,&tilesviewer::setCenterLLA);
connect (ui->widget_mainMap,&tilesviewer::evt_level_changed,ui->browserView,&tilesviewer::setBrLevel);
connect (ui->widget_mainMap,&tilesviewer::cmd_update_layer_box,this,&osm_frame_widget::delacmd_refresh_layer_view,Qt::QueuedConnection);
//send messages
//! 1. source=MAIN_MAP, destin = ALL, msg = WINDOW_CREATE
if (this->isEnabled())
{
QMap<QString, QVariant> map_evt;
map_evt["source"] = "MAIN_MAP";
map_evt["destin"] = "ALL";
map_evt["name"] = "WINDOW_CREATE";
double tlat, tlon;
ui->widget_mainMap->centerLLA(&tlat,&tlon);
map_evt["main_lat"] = tlat;
map_evt["main_lon"] = tlon;
map_evt["nLevel"] = ui->widget_mainMap->level();
ui->widget_mainMap->post_event(map_evt);
}
ui->tab_map->installEventFilter(this);
//adjust layers, make exclusive layrs being de-activated.
ui->widget_mainMap->adjust_layers(pOSMTile);
//! 2. source=MAIN_MAP, destin = ALL, msg = MAP_INITED
if ( this->isEnabled())
{
QMap<QString, QVariant> map_evt;
map_evt["source"] = "MAIN_MAP";
map_evt["destin"] = "ALL";
map_evt["name"] = "MAP_INITED";
double tlat, tlon;
ui->widget_mainMap->centerLLA(&tlat,&tlon);
map_evt["main_lat"] = tlat;
map_evt["main_lon"] = tlon;
map_evt["nLevel"] = ui->widget_mainMap->level();
ui->widget_mainMap->post_event(map_evt);
}
QTVOSM_DEBUG("The osm_frame_widget class constructed.");
EnumPlugins();
UpdateLayerTable();
m_mutex_proteced.unlock();
}
void osm_frame_widget::UpdateLayerTable()
{
QVector<QString> names = ui->widget_mainMap->layerNames();
QVector<bool> activities = ui->widget_mainMap->layerActivities();
QVector<bool> visibles = ui->widget_mainMap->layerVisibilities();
int nItems = names.size();
if (m_pLayerDispMod->rowCount()>0)
m_pLayerDispMod->removeRows(0,m_pLayerDispMod->rowCount());
for (int i=0;i<nItems;++i)
{
m_pLayerDispMod->appendRow(new QStandardItem(names[nItems-1-i]));
m_pLayerDispMod->setData(m_pLayerDispMod->index(i,1),activities[nItems-1-i]);
m_pLayerDispMod->setData(m_pLayerDispMod->index(i,2),visibles[nItems-1-i]);
}
}
tilesviewer * osm_frame_widget::viewer()
{
return ui->widget_mainMap;
}
bool osm_frame_widget::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Close && !( obj==ui->tab_map))
{
if (m_PropPageslayer.contains(obj))
{
QWidget * wig = qobject_cast<QWidget *>(obj);
if (wig)
{
Qt::WindowFlags flg = wig->windowFlags();
flg &= ~(Qt::WindowMinMaxButtonsHint|Qt::WindowStaysOnTopHint|Qt::Window );
wig->setWindowFlags(flg);
ui->tabWidget_main->addTab(
wig,
m_PropPageslayer[obj]->get_name()
);
}
return true;
}
}
else if (obj==ui->tab_map)//Map
{
if (event->type() == QEvent::Close)
{
QWidget * wig = qobject_cast<QWidget *>(obj);
if (wig)
{
Qt::WindowFlags flg = wig->windowFlags();
flg &= ~(Qt::WindowMinMaxButtonsHint|Qt::WindowStaysOnTopHint|Qt::Window );
wig->setWindowFlags(flg);
ui->tabWidget_main->addTab(
wig,
"Map"
);
return true;
}
}
}
// standard event processing
return QObject::eventFilter(obj, event);
}
bool osm_frame_widget::AppendLayer(QString SLName,layer_interface * interface)
{
layer_interface * ci = interface->load_initial_plugin(SLName,ui->widget_mainMap);
if (0==ci)
return false;
if (false==ui->widget_mainMap->addLayer(ci))
return false;
QWidget * wig = ci->load_prop_window();
if (wig)
{
m_layerPropPages[ci] = wig;
m_PropPageslayer[wig] = ci;
ui->tabWidget_main->addTab(wig,ci->get_name());
wig->installEventFilter(this);
}
return true;
}
osm_frame_widget::~osm_frame_widget()
{
delete ui;
}
void osm_frame_widget::EnumPlugins()
{
QTVOSM_DEBUG("The osm_frame_widget is enuming plugins.");
QString strAppDir = QCoreApplication::applicationDirPath();
QDir pluginsDir(strAppDir);
QStringList filters;
filters << "qtvplugin_*.dll" << "libqtvplugin_*.so";
pluginsDir.setNameFilters(filters);
//Enum files
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();//try to load Plugins
if (plugin) {
layer_interface * pPlugin= qobject_cast<layer_interface *>(plugin);
if (pPlugin)
{
if (false==AppendLayer(fileName,pPlugin))
{
}
}
}
}
QTVOSM_DEBUG("The osm_frame_widget loaded all plugins.");
return ;
}
void osm_frame_widget::on_pushButton_visible_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
int nItems = layers.size();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
layers[nItems - 1 -row]->set_visible(true);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_hide_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
layers[nItems - 1 -row]->set_visible(false);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveDown_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerUp(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveBtm_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerTop(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveUp_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerDown(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::on_pushButton_moveTop_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
ui->widget_mainMap->moveLayerBottom(layers[nItems - 1 -row]);
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
}
}
void osm_frame_widget::delacmd_refresh_layer_view()
{
UpdateLayerTable();
ui->widget_mainMap->UpdateWindow();
}
void osm_frame_widget::on_pushButton_active_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
for (int i=0;i<layers.size();++i)
{
//It's exclusive, there should be at most only one layer_tiles active
if (i==(nItems - 1 -row))
{
layers[i]->set_active(true);
ui->widget_mainMap->adjust_layers(layers[i]);
}
}
UpdateLayerTable();
}
}
}
void osm_frame_widget::on_pushButton_deactive_clicked()
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
QModelIndexList lstSel = ui->tableView_layers->selectionModel()->selectedIndexes();
int nItems = layers.size();
if (lstSel.size())
{
int row = lstSel.first().row();
if (row >=0 && row < layers.size())
{
for (int i=0;i<layers.size();++i)
{
if (i==(nItems - 1 -row))
layers[i]->set_active(false);
}
UpdateLayerTable();
}
}
}
void osm_frame_widget::on_tabWidget_main_tabCloseRequested(int index)
{
QWidget * wig = ui->tabWidget_main->widget(index);
this->ui->tabWidget_main->removeTab(index);
Qt::WindowFlags flg = wig->windowFlags();
flg |= (Qt::WindowMinMaxButtonsHint|Qt::WindowStaysOnTopHint|Qt::Window );
wig->setWindowFlags(flg);
wig->show();
wig->move(100,100);
}
void osm_frame_widget::on_pushButton_saveToFile_clicked()
{
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
QString strLastSaveImgDir = settings.value("history/last_save_img_dir","./").toString();
QString newfm = QFileDialog::getSaveFileName(this,tr("save to image"),strLastSaveImgDir,
"Images (*.png *.bmp *.jpg);;All files(*.*)"
);
if (newfm.size()>2)
{
if (true == ui->widget_mainMap->saveToImage(newfm))
settings.setValue("history/last_save_img_dir",newfm);
}
}
#ifndef OSM_FRAME_WIDGET_H
#define OSM_FRAME_WIDGET_H
#include <QWidget>
#include <QMap>
#include <QStandardItemModel>
#include "osmtiles/layer_interface.h"
namespace Ui {
class osm_frame_widget;
}
class osm_frame_widget : public QWidget
{
Q_OBJECT
public:
explicit osm_frame_widget(QWidget *parent = 0);
~osm_frame_widget();
private:
Ui::osm_frame_widget *ui;
QStandardItemModel *m_pLayerDispMod;
QMap<layer_interface *, QWidget *> m_layerPropPages;
void UpdateLayerTable();
void AppendLayer(layer_interface * interface);
void EnumPlugins();
public slots:
void on_pushButton_visible_clicked();
void on_pushButton_hide_clicked();
void on_pushButton_moveUp_clicked();
void on_pushButton_moveTop_clicked();
void on_pushButton_moveDown_clicked();
void on_pushButton_moveBtm_clicked();
void on_pushButton_active_clicked();
};
#endif // OSM_FRAME_WIDGET_H
#ifndef OSM_FRAME_WIDGET_H
#define OSM_FRAME_WIDGET_H
#include <QWidget>
#include <QMap>
#include <QStandardItemModel>
#include <QMutex>
#include "osmtiles/layer_interface.h"
#include "osmtiles/tilesviewer.h"
using namespace QTVOSM;
namespace Ui {
class osm_frame_widget;
}
/*! osm_frame_widget is the container of tilesviewer
* This call maintains basice UI compments, such like layer table views, buttons, browser views.
* It also maintain layer order changes, 2 screen dislay.
*
\class osm_frame_widget osm_frame_widget.h "qtviewer_planetosm/osm_frame_widget.h"
\author goldenhawking \date 2015-12-11
*/
class osm_frame_widget : public QWidget
{
Q_OBJECT
public:
explicit osm_frame_widget(QWidget *parent = 0);
~osm_frame_widget();
public:
//Get tile viewer
tilesviewer * viewer();
protected:
bool eventFilter(QObject *obj, QEvent *event);
protected:
static QMutex m_mutex_proteced;
Ui::osm_frame_widget *ui;
QStandardItemModel *m_pLayerDispMod;
QMap<layer_interface *, QObject *> m_layerPropPages;
QMap<QObject *, layer_interface *> m_PropPageslayer;
void UpdateLayerTable();
bool AppendLayer(QString SLName,layer_interface * interface);
void EnumPlugins();
protected slots:
void delacmd_refresh_layer_view();
void on_tabWidget_main_tabCloseRequested(int index);
void on_pushButton_visible_clicked();
void on_pushButton_hide_clicked();
void on_pushButton_moveUp_clicked();
void on_pushButton_moveTop_clicked();
void on_pushButton_moveDown_clicked();
void on_pushButton_moveBtm_clicked();
void on_pushButton_active_clicked();
void on_pushButton_deactive_clicked();
void on_pushButton_saveToFile_clicked();
};
#endif // OSM_FRAME_WIDGET_H
#include "cProjectionMercator.h"
const double cProjectionMercator::R=6378137;
const double cProjectionMercator::pi=3.1415926535897932384626433832795;
\ No newline at end of file
#include "cProjectionMercator.h"
namespace QTVOSM
{
const double cProjectionMercator::R=6378137;
const double cProjectionMercator::pi=3.1415926535897932384626433832795;
}
#pragma once
#include <math.h>
class cProjectionMercator
{
public:
double m_lat,m_lon;
double m_x,m_y;
static const double R;
static const double pi;
cProjectionMercator(double v_cood=0,double h_cood=0)
:m_lat(v_cood),
m_lon(h_cood),
m_x(h_cood),
m_y(v_cood)
{
}
virtual ~cProjectionMercator(void)
{
}
cProjectionMercator & ToLatLon()
{
m_lon = 180.0 * (m_x / cProjectionMercator::R) /cProjectionMercator::pi;
m_lat = (atan(exp(m_y / cProjectionMercator::R))-cProjectionMercator::pi/4)*2.0/cProjectionMercator::pi*180.0;
return *this;
}
cProjectionMercator & ToMercator()
{
m_x = cProjectionMercator::R * m_lon* cProjectionMercator::pi /180.0;
m_y =
cProjectionMercator::R *
log
(
tan
(
m_lat/180.0* cProjectionMercator::pi/2.0 + cProjectionMercator::pi/4
)
);
return *this;
}
};
#pragma once
#include <math.h>
namespace QTVOSM
{
/*! cProjectionMercator is a toolkit class that turns coordinates between LLA(4326) and Mercator(900913)
cProjectionMercator cProjectionMercator.h "qtviewer_planetosm/osmtiles/cProjectionMercator.h"
\author goldenhawking \date 2015-12-11
*/
class cProjectionMercator
{
public:
double m_lat,m_lon;
double m_x,m_y;
static const double R;
static const double pi;
cProjectionMercator(double v_cood=0,double h_cood=0)
:m_lat(v_cood),
m_lon(h_cood),
m_x(h_cood),
m_y(v_cood)
{
}
virtual ~cProjectionMercator(void)
{
}
cProjectionMercator & ToLatLon()
{
m_lon = 180.0 * (m_x / cProjectionMercator::R) /cProjectionMercator::pi;
m_lat = (atan(exp(m_y / cProjectionMercator::R))-cProjectionMercator::pi/4)*2.0/cProjectionMercator::pi*180.0;
return *this;
}
cProjectionMercator & ToMercator()
{
m_x = cProjectionMercator::R * m_lon* cProjectionMercator::pi /180.0;
m_y =
cProjectionMercator::R *
log
(
tan
(
m_lat/180.0* cProjectionMercator::pi/2.0 + cProjectionMercator::pi/4
)
);
return *this;
}
};
}
#include <QThread>
#include <QCoreApplication>
#include <QPainter>
#include <QSettings>
#include "layer_browser.h"
#include "tilesviewer.h"
layer_browser::layer_browser(QObject *parent) :
QObject(parent)
{
m_name = QString("%1").arg((quint64)this);
}
void layer_browser::cb_paintEvent( QPainter * pImage )
{
if (!m_pViewer) return;
//calculate current position
int nCenter_X ,nCenter_Y;
if (true==m_pViewer->CV_PercentageToPixel(
m_pViewer->level(),
m_pViewer->centerX(),
m_pViewer->centerY(),
&nCenter_X,&nCenter_Y))
{
int sz_whole_idx = 1<<m_pViewer->level();
//current center
int nCenX = nCenter_X/256;
int nCenY = nCenter_Y/256;
//current left top tile idx
int nCurrLeftX = floor((nCenter_X-m_pViewer->width()/2)/256.0);
int nCurrTopY = floor((nCenter_Y-m_pViewer->height()/2)/256.0);
//current right btm
int nCurrRightX = ceil((nCenter_X+m_pViewer->width()/2)/256.0);
int nCurrBottomY = ceil((nCenter_Y+m_pViewer->height()/2)/256.0);
//draw images
bool needreg = false;
for (int col = nCurrLeftX;col<=nCurrRightX;col++)
{
for (int row = nCurrTopY;row<=nCurrBottomY;row++)
{
//generate a image
QImage image_source;
int req_row = row, req_col = col;
if (row<0 || row>=sz_whole_idx)
continue;
if (col>=sz_whole_idx)
req_col = col % sz_whole_idx;
if (col<0)
req_col = (col + (1-col/sz_whole_idx)*sz_whole_idx) % sz_whole_idx;
//query
if (this->getTileImage(m_pViewer->level(),req_col,req_row,image_source))
{
//bitblt
int nTileOffX = (col-nCenX)*256;
int nTileOffY = (row-nCenY)*256;
//0,0 lefttop offset
int zero_offX = nCenter_X % 256;
int zero_offY = nCenter_Y % 256;
//bitblt cood
int tar_x = m_pViewer->width()/2-zero_offX+nTileOffX;
int tar_y = m_pViewer->height()/2-zero_offY+nTileOffY;
//bitblt
pImage->drawImage(tar_x,tar_y,image_source);
}
}
}
}
}
layer_browser::~layer_browser()
{
}
QWidget * layer_browser::cb_create_propWindow()
{
return 0;
}
bool layer_browser::cb_mousePressEvent ( QMouseEvent * event )
{
if (!m_pViewer) return false;
bool res = false;
if (event->button()==Qt::LeftButton)
{
int nOffsetX = event->pos().x()-m_pViewer->width()/2;
int nOffsetY = event->pos().y()-m_pViewer->height()/2;
m_pViewer->DragView(-nOffsetX,-nOffsetY);
res = true;
}
return res;
}
bool layer_browser::cb_mouseReleaseEvent ( QMouseEvent * event )
{
return false;
}
bool layer_browser::cb_mouseMoveEvent(QMouseEvent * /*event*/)
{
return false;
}
bool layer_browser::cb_wheelEvent ( QWheelEvent * /*event*/ )
{
if (!m_pViewer) return false;
return true;
}
void layer_browser::cb_resizeEvent ( QResizeEvent * /*event*/)
{
}
bool layer_browser::cb_initlayer(QObject * viewer)
{
m_pViewer =qobject_cast<tilesviewer *>(viewer);
if (m_pViewer==0)
return false;
return true;
}
void layer_browser::cb_finilayer(void * /*viewer*/)
{
m_pViewer = 0;
}
void layer_browser::cb_levelChanged(int /*nLevel*/)
{
}
void layer_browser::cb_update()
{
}
//Get a single tile PNG from web service. return false if error occurred.
bool layer_browser::getTileImage(int nLevel,int nX,int nY,QImage & image)
{
if (!m_pViewer) return true;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
QString strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(cb_name()), QCoreApplication::applicationDirPath() +"/Cache").toString();
QString strVal = strLocalCache;
strVal += '/';
strVal += m_name;
strVal += '/';
strVal += QString::number(nLevel,10);
strVal += '/';
strVal += QString::number(nX,10);
strVal += '/';
strVal += QString::number(nY,10);
strVal += ".png";
bool res = true;
if (res)
{
QByteArray array_out;
QFile file(strVal);
if (file.open(QIODevice::ReadOnly)==true)
{
array_out = file.readAll();
image = QImage::fromData(array_out);
if (image.isNull()==true)
res = false;
}
else
res = false;
if (res==false)
image = QImage(256,256,QImage::Format_ARGB32);
}
return res;
}
#include <QThread>
#include <QCoreApplication>
#include <QPainter>
#include <QSettings>
#include "layer_browser.h"
#include "tilesviewer.h"
namespace QTVOSM
{
layer_browser::layer_browser(QObject *parent) :
QObject(parent)
{
m_name = QString("%1").arg((quint64)this);
}
void layer_browser::cb_paintEvent( QPainter * pImage )
{
if (!m_pViewer) return;
//calculate current position
double nCenter_X ,nCenter_Y;
if (true==m_pViewer->CV_Pct2World(
m_pViewer->centerX(),
m_pViewer->centerY(),
&nCenter_X,&nCenter_Y))
{
int sz_whole_idx = 1<<m_pViewer->level();
//current center
int nCenX = nCenter_X/256;
int nCenY = nCenter_Y/256;
//current left top tile idx
int nCurrLeftX = floor((nCenter_X-m_pViewer->width()/2)/256.0);
int nCurrTopY = floor((nCenter_Y-m_pViewer->height()/2)/256.0);
//current right btm
int nCurrRightX = ceil((nCenter_X+m_pViewer->width()/2)/256.0);
int nCurrBottomY = ceil((nCenter_Y+m_pViewer->height()/2)/256.0);
//draw images
for (int col = nCurrLeftX;col<=nCurrRightX;col++)
{
for (int row = nCurrTopY;row<=nCurrBottomY;row++)
{
//generate a image
QImage image_source;
int req_row = row, req_col = col;
if (row<0 || row>=sz_whole_idx)
continue;
if (col>=sz_whole_idx)
req_col = col % sz_whole_idx;
if (col<0)
req_col = (col + (1-col/sz_whole_idx)*sz_whole_idx) % sz_whole_idx;
//query
if (this->getTileImage(m_pViewer->level(),req_col,req_row,image_source))
{
//bitblt
int nTileOffX = (col-nCenX)*256;
int nTileOffY = (row-nCenY)*256;
//0,0 lefttop offset
int zero_offX = int(nCenter_X+0.5) % 256;
int zero_offY = int(nCenter_Y+0.5) % 256;
//bitblt cood
int tar_x = m_pViewer->width()/2-zero_offX+nTileOffX;
int tar_y = m_pViewer->height()/2-zero_offY+nTileOffY;
//bitblt
pImage->drawImage(tar_x,tar_y,image_source);
}
}
}
}
}
layer_browser::~layer_browser()
{
}
QWidget * layer_browser::load_prop_window()
{
return 0;
}
bool layer_browser::cb_mousePressEvent ( QMouseEvent * event )
{
if (!m_pViewer) return false;
bool res = false;
if (event->button()==Qt::LeftButton)
{
int nOffsetX = event->pos().x()-m_pViewer->width()/2;
int nOffsetY = event->pos().y()-m_pViewer->height()/2;
m_pViewer->DragView(-nOffsetX,-nOffsetY);
res = true;
}
return res;
}
layer_interface * layer_browser::load_initial_plugin(QString /*strSLibPath*/,viewer_interface * viewer)
{
m_pViewer =dynamic_cast<tilesviewer *>(viewer);
if (m_pViewer==0)
return 0;
return this;
}
//! \brief Get a single tile PNG from web service. return false if error occurred.
bool layer_browser::getTileImage(int nLevel,int nX,int nY,QImage & image)
{
if (!m_pViewer) return true;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
QString strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(get_name()), QCoreApplication::applicationDirPath() +"/OSMCache").toString();
QString strVal = strLocalCache;
strVal += '/';
strVal += m_name;
strVal += '/';
strVal += QString::number(nLevel,10);
strVal += '/';
strVal += QString::number(nX,10);
strVal += '/';
strVal += QString::number(nY,10);
strVal += ".png";
bool res = true;
if (res)
{
QByteArray array_out;
QFile file(strVal);
if (file.open(QIODevice::ReadOnly)==true)
{
array_out = file.readAll();
image = QImage::fromData(array_out);
if (image.isNull()==true)
res = false;
}
else
res = false;
if (res==false)
image = QImage(256,256,QImage::Format_ARGB32);
}
return res;
}
}
#ifndef LAYER_BROSWER_H
#define LAYER_BROSWER_H
#include <QObject>
#include "layer_interface.h"
#include "urlDownloader.h"
class tilesviewer;
class layer_browser :public QObject, public layer_interface
{
Q_OBJECT
public:
explicit layer_browser(QObject *parent = 0);
~layer_browser();
public:
virtual bool cb_initlayer(QObject * viewer);
virtual void cb_finilayer(void * viewer);
virtual QWidget * cb_create_propWindow();
virtual void cb_paintEvent( QPainter * pImage );
virtual bool cb_mousePressEvent ( QMouseEvent * event );
virtual bool cb_mouseReleaseEvent ( QMouseEvent * event );
virtual bool cb_mouseMoveEvent(QMouseEvent * event);
virtual bool cb_wheelEvent ( QWheelEvent * event );
virtual void cb_resizeEvent ( QResizeEvent * event);
virtual void cb_levelChanged(int nLevel);
virtual void cb_update();
public:
bool cb_isActive() {return true;}
void cb_setActive(bool at) { }
bool cb_isVisible() {return true;}
void cb_setVisible(bool vb) { }
QString cb_name() {return m_name;}
void cb_setName(QString vb) { m_name = vb; }
protected:
tilesviewer * m_pViewer;
QString m_name;
private:
//get single tile from web service
bool getTileImage(int nLevel,int nX,int nY,QImage & image);
};
#endif // LAYER_BROSWER_H
#ifndef LAYER_BROSWER_H
#define LAYER_BROSWER_H
#include <QObject>
#include "layer_interface.h"
#include "urlDownloader.h"
namespace QTVOSM{
class tilesviewer;
/*! this class defines a tile layer for browser-view (Bird-eye view)
*
* \class layer_browser layer_browser.h "qtviewer_planetosm/osmtiles/layer_browser.h"
* \author goldenhawking \date 2015-12-11
*/
class layer_browser :public QObject, public layer_interface
{
Q_OBJECT
public:
explicit layer_browser(QObject *parent = 0);
~layer_browser();
virtual QWidget * get_propWindow() {return 0;}
public:
virtual layer_interface * load_initial_plugin(QString strSLibPath,viewer_interface * viewer);
virtual QWidget * load_prop_window();
virtual void cb_paintEvent( QPainter * pImage );
virtual bool cb_mousePressEvent ( QMouseEvent * event );
public:
bool is_active() {return true;}
void set_active(bool ) { }
bool is_visible() {return true;}
void set_visible(bool ) { }
QString get_name() {return m_name;}
void set_name(QString vb) { m_name = vb; }
protected:
tilesviewer * m_pViewer;
QString m_name;
private:
//get single tile from web service
bool getTileImage(int nLevel,int nX,int nY,QImage & image);
};
}
#endif // LAYER_BROSWER_H
#ifndef LAYER_BASE_H
#define LAYER_BASE_H
#include <QObject>
#include <QWidget>
#include <QMouseEvent>
#include <QResizeEvent>
#define OSMLayerInterface_iid "org.goldenhawkingStudio.OSMViewer_iid.LayerInterface"
class layer_interface
{
public:
virtual ~layer_interface(){}
virtual bool cb_initlayer(QObject * ptrviewer) = 0;
virtual QWidget * cb_create_propWindow() = 0;
virtual void cb_finilayer(void * ptrviewer) = 0;
virtual void cb_update() = 0;
virtual void cb_paintEvent( QPainter * pImage ) = 0;
virtual bool cb_mousePressEvent ( QMouseEvent * event ) = 0;
virtual bool cb_mouseReleaseEvent ( QMouseEvent * event ) = 0;
virtual bool cb_mouseMoveEvent(QMouseEvent * event) = 0;
virtual bool cb_wheelEvent ( QWheelEvent * event ) = 0;
virtual void cb_resizeEvent ( QResizeEvent * event ) = 0;
virtual void cb_levelChanged(int nLevel) = 0;
virtual bool cb_isActive() =0;
virtual void cb_setActive(bool at) =0;
virtual bool cb_isVisible() =0;
virtual void cb_setVisible(bool vb) =0;
virtual QString cb_name() =0;
virtual void cb_setName(QString vb) =0;
};
Q_DECLARE_INTERFACE(layer_interface, OSMLayerInterface_iid)
#endif // LAYER_BASE_H
#ifndef LAYER_BASE_H
#define LAYER_BASE_H
#include <QObject>
#include <QWidget>
#include <QMouseEvent>
#include <QResizeEvent>
#include <QVariant>
#include <QMap>
#define OSMLayerInterface_iid "org.goldenhawkingStudio.OSMViewer_iid.LayerInterface"
#define QTVOSM_DEBUG(MSG) qDebug()<<"QTVOSM Debug>"<< MSG <<"\n\t"<<__FUNCTION__<<":"<<__FILE__<<__LINE__
#define QTVOSM_WARNING(MSG) qWarning()<<"QTVOSM Debug>"<< MSG <<"\n\t"<<__FUNCTION__<<":"<<__FILE__<<__LINE__
#define QTVOSM_FATAL(MSG) qFatal()<<"QTVOSM Debug>"<< MSG <<"\n\t"<<__FUNCTION__<<":"<<__FILE__<<__LINE__
class osm_frame_widget;
class qtaxviewer_planetosm;
namespace QTVOSM
{
class viewer_interface;
/*! the interface for layers. cb_ means 'CALLBACK'
\author goldenhawking \date 2015-12-11
*/
class layer_interface
{
friend class tilesviewer;
friend class ::osm_frame_widget;
friend class ::qtaxviewer_planetosm;
public:
virtual ~layer_interface(){}
/*! get_propWindow should return the pointer to prop window.
* this funtion is called by MAINWND or other layers when needed.
* \return QWidget * the window pointer.
*/
//initlize functions is protected, only viewer_interface can call it when start up
protected:
/*! load_InitialBind Initializer, plugin should return a instance belongs to ptrviewer in this callback.
* Very Important! Note that Even If there're more than one viewer_interface in an process, the Plugin-Shared lib will only be loaded once,
* Plugin designer has a responsblility to maintain a map between viewer_interface and layer_interface, return a brave new instance of layer_interface
* for each viewer_interface.
*
* \param strSLibPath QString strSLibPath the fullpath of this plugin descovered by Main Prg.
* \param ptrviewer viewer_interface * stands for the main view.
* \return layer_interface * return this plugin interface when succeeded, otherwise return 0;
*/
virtual layer_interface * load_initial_plugin(QString strSLibPath,viewer_interface * ptrviewer) = 0;
/*! MainWND will call this method when plugin loading.
* Plugin should create a new widget in this funtion, and return the pointer.
* \return QWidget * means the prop window just being created
*/
virtual QWidget * load_prop_window() = 0;
/*! load_retranslate_UI is called when layer is being inited.
* User should inher this method, when you want to include international local support.
*/
virtual void load_retranslate_UI(){}
//callback functions is protected, only viewer_interface can call it when start up
protected:
//Callback Systems
virtual void cb_paintEvent( QPainter * /*pImage*/ ) = 0;
virtual bool cb_mousePressEvent ( QMouseEvent * /*event*/ ){return false;}
virtual bool cb_mouseReleaseEvent ( QMouseEvent * /*event*/ ){return false;}
virtual bool cb_mouseMoveEvent(QMouseEvent *){return false;}
virtual bool cb_mouseDoubleClickEvent(QMouseEvent *){return false;}
virtual bool cb_wheelEvent ( QWheelEvent * ){return false;}
virtual void cb_resizeEvent ( QResizeEvent *){}
virtual void cb_levelChanged(int /*nLevel*/){}
//user-def event callback
virtual bool cb_event(const QMap<QString, QVariant> /*event*/){return false;}
public:
/*! is_exclusive returns whether this layer is Exclusive
* "Exclusive" means that at same time, there should be only one Exclusive plugins is active.
* Layer who want itself be Exclusive often has a demand of interaction with mouse, keyborad.
* Durning these interactions, it is unwilling to be disturbed by other layers.
*
* \return bool Exclusive Method
*/
virtual bool is_exclusive(){return false;}
virtual QWidget * get_propWindow() = 0;
virtual QString get_name() = 0;
virtual void set_name(QString) =0;
/*! return whether this layer is active.
*
* active layer will process mouse, key events, otherwise it should omit these messages.
*/
virtual bool is_active(){return false;}
virtual void set_active(bool /*at*/){}
virtual bool is_visible(){return false;}
virtual void set_visible(bool /*vb*/) {}
public:
//user-def direct function calls
virtual QMap<QString, QVariant> call_func(const QMap<QString, QVariant> /*paras*/){return std::move( QMap<QString, QVariant>());}
};
}
Q_DECLARE_INTERFACE(QTVOSM::layer_interface, OSMLayerInterface_iid)
#endif // LAYER_BASE_H
#include <QThread>
#include <QCoreApplication>
#include <QPainter>
#include <QSettings>
#include "layer_tiles.h"
#include "tilesviewer.h"
layer_tiles::layer_tiles(QObject *parent) :
QObject(parent)
{
m_bActive = false;
m_bVisible = false;
m_pViewer = 0;
//Create thread object for download
m_downloader = new urlDownloader(0);
m_downloadThread = new QThread(this);
m_downloader->moveToThread(m_downloadThread);
m_downloadThread->start();
//init basic cache and server site
this->m_strLocalCache = QCoreApplication::applicationDirPath() +"/Cache";
this->m_strServerURL = "http://localhost/osm_tiles2/%1/%2/%3.png";
m_bconnected = false;
m_propPage = 0;
//Drag
this->m_nStartPosX = this->m_nStartPosY = -1;
m_name = QString("%1").arg((quint64)this);
}
void layer_tiles::setServerUrl(QString url)
{
m_strServerURL = url;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
settings.setValue(QString("settings/ServerURL_%1").arg(cb_name()),m_strServerURL);
}
void layer_tiles::setLocalCache(QString cache)
{
m_strLocalCache = cache;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
settings.setValue(QString("settings/LocalCache_%1").arg(cb_name()), m_strLocalCache);
}
void layer_tiles::cb_paintEvent( QPainter * pImage )
{
if (!m_pViewer || m_bVisible==false) return;
//calculate current position
int nCenter_X ,nCenter_Y;
if (true==m_pViewer->CV_PercentageToPixel(
m_pViewer->level(),
m_pViewer->centerX(),
m_pViewer->centerY(),
&nCenter_X,&nCenter_Y))
{
int sz_whole_idx = 1<<m_pViewer->level();
//current center
int nCenX = nCenter_X/256;
int nCenY = nCenter_Y/256;
//current left top tile idx
int nCurrLeftX = floor((nCenter_X-m_pViewer->width()/2)/256.0);
int nCurrTopY = floor((nCenter_Y-m_pViewer->height()/2)/256.0);
//current right btm
int nCurrRightX = ceil((nCenter_X+m_pViewer->width()/2)/256.0);
int nCurrBottomY = ceil((nCenter_Y+m_pViewer->height()/2)/256.0);
//draw images
bool needreg = false;
int reg_left = sz_whole_idx,reg_right = -1,reg_bottom = -1,reg_top = sz_whole_idx;
for (int col = nCurrLeftX;col<=nCurrRightX;col++)
{
for (int row = nCurrTopY;row<=nCurrBottomY;row++)
{
//generate a image
QImage image_source;
int req_row = row, req_col = col;
if (row<0 || row>=sz_whole_idx)
continue;
if (col>=sz_whole_idx)
req_col = col % sz_whole_idx;
if (col<0)
req_col = (col + (1-col/sz_whole_idx)*sz_whole_idx) % sz_whole_idx;
//query
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
{
//bitblt
int nTileOffX = (col-nCenX)*256;
int nTileOffY = (row-nCenY)*256;
//0,0 lefttop offset
int zero_offX = nCenter_X % 256;
int zero_offY = nCenter_Y % 256;
//bitblt cood
int tar_x = m_pViewer->width()/2-zero_offX+nTileOffX;
int tar_y = m_pViewer->height()/2-zero_offY+nTileOffY;
//bitblt
pImage->drawImage(tar_x,tar_y,image_source);
}
}
}
if (needreg==true)
RegImages(reg_left,reg_right,reg_top,reg_bottom,m_pViewer->level());
}
}
layer_tiles::~layer_tiles()
{
m_downloadThread->quit();
m_downloadThread->wait();
m_downloader->deleteLater();
if (!m_propPage)
m_propPage->deleteLater();
}
bool layer_tiles::cb_mousePressEvent ( QMouseEvent * event )
{
if (!m_pViewer || m_bVisible==false || m_bActive==false) return false;
bool res = false;
if (event->button()==Qt::LeftButton)
{
this->m_nStartPosX = event->pos().x();
this->m_nStartPosY = event->pos().y();
res = true;
}
else if (event->button()==Qt::RightButton)
{
int nOffsetX = event->pos().x()-m_pViewer->width()/2;
int nOffsetY = event->pos().y()-m_pViewer->height()/2;
m_pViewer->DragView(-nOffsetX,-nOffsetY);
res = true;
}
return res;
}
bool layer_tiles::cb_mouseReleaseEvent ( QMouseEvent * event )
{
if (!m_pViewer || m_bVisible==false || m_bActive==false) return false;
bool res = false;
if (event->button()==Qt::LeftButton)
{
int nOffsetX = event->pos().x()-this->m_nStartPosX;
int nOffsetY = event->pos().y()-this->m_nStartPosY;
m_pViewer->DragView(nOffsetX,nOffsetY);
this->m_nStartPosX = this->m_nStartPosY = -1;
res = true;
}
return res;
}
bool layer_tiles::cb_mouseMoveEvent(QMouseEvent * /*event*/)
{
return false;
}
bool layer_tiles::cb_wheelEvent ( QWheelEvent * event )
{
if (!m_pViewer || m_bVisible==false || m_bActive==false) return false;
int nLevel = m_pViewer->level();
if (event->delta()<0)
{
nLevel++;
if (nLevel>18)
nLevel=18;
}
else if (event->delta()>0)
{
nLevel--;
if (nLevel<0)
nLevel=0;
}
if (nLevel != m_pViewer->level())
m_pViewer->setLevel(nLevel);
return true;
}
void layer_tiles::cb_resizeEvent ( QResizeEvent * /*event*/)
{
if (!m_pViewer || m_bVisible==false) return;
}
bool layer_tiles::cb_initlayer(QObject * viewer)
{
m_pViewer = qobject_cast<tilesviewer *>(viewer);
if (!m_pViewer)
return false;
connect(m_downloader,SIGNAL(evt_all_taskFinished()),m_pViewer,SLOT(UpdateWindow()));
//Get Cache Address
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
m_strServerURL = settings.value(QString("settings/ServerURL_%1").arg(m_name),"http://localhost/osm_tiles2/%1/%2/%3.png").toString();
m_strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(m_name), QCoreApplication::applicationDirPath() +"/Cache").toString();
return true;
}
void layer_tiles::cb_finilayer(void * /*viewer*/)
{
if (m_pViewer)
disconnect(m_downloader,SIGNAL(evt_all_taskFinished()),m_pViewer,SLOT(UpdateWindow()));
m_pViewer = 0;
}
QWidget * layer_tiles::cb_create_propWindow()
{
if (!m_propPage)
m_propPage = new layer_tiles_page(this,0);
return m_propPage;
}
void layer_tiles::cb_levelChanged(int /*nLevel*/)
{
if (!m_pViewer || m_bVisible==false) return;
}
void layer_tiles::cb_update()
{
if (!m_pViewer || m_bVisible==false) return;
}
//Get a single tile PNG from web service. return false if error occurred.
bool layer_tiles::getTileImage(int nLevel,int nX,int nY,QImage & image)
{
if (!m_pViewer || m_bVisible==false) return true;
QString strVal = m_strLocalCache;
strVal += '/';
strVal += m_name;
strVal += '/';
strVal += QString::number(nLevel,10);
strVal += '/';
strVal += QString::number(nX,10);
strVal += '/';
strVal += QString::number(nY,10);
strVal += ".png";
bool res = true;
if (res)
{
QByteArray array_out;
QFile file(strVal);
if (file.open(QIODevice::ReadOnly)==true)
{
array_out = file.readAll();
image = QImage::fromData(array_out);
if (image.isNull()==true)
res = false;
}
else
res = false;
}
return res;
}
//public slots for enable/disable web service
void layer_tiles::UpdateLayer()
{
m_pViewer->update();
}
//public slots for enable/disable web service
void layer_tiles::connectToTilesServer(bool bconnected)
{
this->m_bconnected = bconnected;
if (!m_pViewer) return;
m_pViewer->update();
}
bool layer_tiles::RegImages(int nLeft,int nRight,int nTop,int nBottom,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);
this->m_downloader->addDownloadUrl(strSourceUrl,strDestinDir,strFileName);
}
}
return true;
}
#include <QThread>
#include <QCoreApplication>
#include <QPainter>
#include <QSettings>
#include "layer_tiles.h"
#include "tilesviewer.h"
namespace QTVOSM{
/*!
\brief in this constructor, some initial approach will be token.
\fn layer_tiles::layer_tiles
\param parent parent objects
*/
layer_tiles::layer_tiles(QObject *parent) :
QObject(parent)
{
m_bActive = false;
m_bVisible = false;
m_pViewer = 0;
//!1,Create thread object for download. download will be hold in different threads/
m_downloader = new urlDownloader(0);
m_downloadThread = new QThread(this);
m_downloader->moveToThread(m_downloadThread);
m_downloadThread->start();
//!2,init basic cache and server site.if user does not give address, default set to "http://localhost/osm/%1/%2/%3.png"
this->m_strLocalCache = "/OSMCache";
this->m_strServerURL = "http://c.tile.openstreetmap.org/%1/%2/%3.png";
m_bconnected = false;
m_propPage = 0;
//!3, init the Drag position, for mouse drag and explore.
this->m_nStartPosX = this->m_nStartPosY = -1;
m_name = QString("%1").arg((quint64)this);
}
void layer_tiles::setServerUrl(QString url)
{
m_strServerURL = url;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
settings.setValue(QString("settings/ServerURL_%1").arg(get_name()),m_strServerURL);
emit svrurlChanged(url);
}
void layer_tiles::setLocalCache(QString cache)
{
m_strLocalCache = cache;
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
settings.setValue(QString("settings/LocalCache_%1").arg(get_name()), m_strLocalCache);
emit cacheChanged(cache);
}
/*!
\brief When the tileviewer enter its paint_event function, this callback will be called.
\fn layer_tiles::cb_paintEvent
\param pImage the In-mem image for paint .
*/
void layer_tiles::cb_paintEvent( QPainter * pPainter )
{
if (!m_pViewer || m_bVisible==false) return;
//!1,We should first calculate current windows' position, centerx,centery, in pixcel.
double nCenter_X ,nCenter_Y;
//!2,if the CV_PercentageToPixel returns true, painting will begin.
if (true==m_pViewer->CV_Pct2World(
m_pViewer->centerX(),
m_pViewer->centerY(),
&nCenter_X,&nCenter_Y))
{
int sz_whole_idx = 1<<m_pViewer->level();
//!2.1 get current center tile idx, in tile count.(tile is 256x256)
int nCenX = nCenter_X/256;
int nCenY = nCenter_Y/256;
//!2.2 calculate current left top tile idx
int nCurrLeftX = floor((nCenter_X-m_pViewer->width()/2)/256.0);
int nCurrTopY = floor((nCenter_Y-m_pViewer->height()/2)/256.0);
//!2.3 calculate current right bottom idx
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.
for (int col = nCurrLeftX;col<=nCurrRightX;col++)
{
//!2.5.1 a repeat from tileindx top to bottom.
for (int row = nCurrTopY;row<=nCurrBottomY;row++)
{
QImage image_source;
int req_row = row, req_col = col;
if (row<0 || row>=sz_whole_idx)
continue;
if (col>=sz_whole_idx)
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
{
//bitblt
int nTileOffX = (col-nCenX)*256;
int nTileOffY = (row-nCenY)*256;
//0,0 lefttop offset
int zero_offX = int(nCenter_X+0.5) % 256;
int zero_offY = int(nCenter_Y+0.5) % 256;
//bitblt cood
int tar_x = m_pViewer->width()/2-zero_offX+nTileOffX;
int tar_y = m_pViewer->height()/2-zero_offY+nTileOffY;
//bitblt
pPainter->drawImage(tar_x,tar_y,image_source);
}
}
}
//!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());
}
}
layer_tiles::~layer_tiles()
{
m_downloadThread->quit();
m_downloadThread->wait();
m_downloader->deleteLater();
if (!m_propPage)
m_propPage->deleteLater();
}
bool layer_tiles::cb_mousePressEvent ( QMouseEvent * event )
{
if (!m_pViewer || m_bVisible==false || m_bActive==false) return false;
bool res = false;
if (event->button()==Qt::LeftButton)
{
this->m_nStartPosX = event->pos().x();
this->m_nStartPosY = event->pos().y();
}
else if (event->button()==Qt::RightButton)
{
int nOffsetX = event->pos().x()-m_pViewer->width()/2;
int nOffsetY = event->pos().y()-m_pViewer->height()/2;
m_pViewer->DragView(-nOffsetX,-nOffsetY);
res = true;
}
return res;
}
bool layer_tiles::cb_mouseReleaseEvent ( QMouseEvent * event )
{
if (!m_pViewer || m_bVisible==false || m_bActive==false) return false;
bool res = false;
if (event->button()==Qt::LeftButton)
{
int nOffsetX = event->pos().x()-this->m_nStartPosX;
int nOffsetY = event->pos().y()-this->m_nStartPosY;
if (!(nOffsetX ==0 && nOffsetY==0))
{
m_pViewer->DragView(nOffsetX,nOffsetY);
this->m_nStartPosX = this->m_nStartPosY = -1;
res = true;
}
}
return res;
}
bool layer_tiles::cb_mouseMoveEvent(QMouseEvent * /*event*/)
{
return false;
}
bool layer_tiles::cb_wheelEvent ( QWheelEvent * event )
{
if (!m_pViewer || m_bVisible==false || m_bActive==false) return false;
int nLevel = m_pViewer->level();
if (event->delta()<0)
{
nLevel++;
if (nLevel>18)
nLevel=18;
}
else if (event->delta()>0)
{
nLevel--;
if (nLevel<0)
nLevel=0;
}
if (nLevel != m_pViewer->level())
m_pViewer->setLevel(nLevel);
return true;
}
void layer_tiles::cb_resizeEvent ( QResizeEvent * /*event*/)
{
if (!m_pViewer || m_bVisible==false) return;
}
layer_interface * layer_tiles::load_initial_plugin(QString /*strSLibPath*/,viewer_interface * viewer)
{
m_pViewer = dynamic_cast<tilesviewer *>(viewer);
if (!m_pViewer)
return 0;
connect(m_downloader,SIGNAL(evt_all_taskFinished()),m_pViewer,SLOT(UpdateWindow()));
//Get Cache Address
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();
return this;
}
QWidget * layer_tiles::load_prop_window()
{
if (!m_propPage)
m_propPage = new layer_tiles_page(this,0);
return m_propPage;
}
void layer_tiles::cb_levelChanged(int /*nLevel*/)
{
if (!m_pViewer || m_bVisible==false) return;
}
/*!
\brief Get a single tile PNG from web service. return false if error occurred.
\fn layer_tiles::getTileImage
\param nLevel current level
\param nX current col
\param nY current row
\param image the image object to hold the result data
\return bool succeed when ok.
*/
bool layer_tiles::getTileImage(int nLevel,int nX,int nY,QImage & image)
{
if (!m_pViewer || m_bVisible==false) return true;
QString strVal = m_strLocalCache;
strVal += '/';
strVal += m_name;
strVal += '/';
strVal += QString::number(nLevel,10);
strVal += '/';
strVal += QString::number(nX,10);
strVal += '/';
strVal += QString::number(nY,10);
strVal += ".png";
bool res = true;
if (res)
{
QByteArray array_out;
QFile file(strVal);
if (file.open(QIODevice::ReadOnly)==true)
{
array_out = file.readAll();
image = QImage::fromData(array_out);
if (image.isNull()==true)
res = false;
}
else
res = false;
}
return res;
}
void layer_tiles::UpdateLayer()
{
m_pViewer->update();
}
/*!
\brief connectToTilesServer will set connect flag to true.
notice that a connected tile means that it will try to doanload new tile images from
remote server, with no swearing for succeed doanload.
ther will be one event fired in this method.
\fn layer_tiles::connectToTilesServer
\param bconnected return current status
*/
void layer_tiles::connectToTilesServer(bool bconnected)
{
this->m_bconnected = bconnected;
if (!m_pViewer) return;
m_pViewer->update();
emit connected(m_bconnected);
//! 1. source=MAIN_MAP, destin = ALL, msg = CONNECTION
if (this->is_active())
{
QMap<QString, QVariant> map_evt;
map_evt["source"] = "MAIN_MAP";
map_evt["destin"] = "ALL";
map_evt["name"] = "CONNECTION";
double tlat, tlon;
m_pViewer->centerLLA(&tlat,&tlon);
map_evt["main_lat"] = tlat;
map_evt["main_lon"] = tlon;
map_evt["nLevel"] = m_pViewer->level();
map_evt["status"] =m_bconnected?"CONNECTED":"CLOSED";
m_pViewer->post_event(map_evt);
}
}
/*!
\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 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)
{
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);
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 >();
}
}
#ifndef LAYER_TILES_H
#define LAYER_TILES_H
#include <QObject>
#include "layer_interface.h"
#include "urlDownloader.h"
#include "layer_tiles_page.h"
class tilesviewer;
class layer_tiles :public QObject,public layer_interface
{
Q_OBJECT
friend class layer_tiles_page;
public:
explicit layer_tiles(QObject *parent = 0);
~layer_tiles();
QString serverUrl() {return m_strServerURL; }
QString localCache() {return m_strLocalCache; }
bool isConnected(){return m_bconnected;}
void connectToTilesServer(bool bconnected);
void UpdateLayer();
public:
virtual bool cb_initlayer(QObject * viewer);
virtual void cb_finilayer(void * viewer);
virtual QWidget * cb_create_propWindow();
virtual void cb_paintEvent( QPainter * pImage );
virtual bool cb_mousePressEvent ( QMouseEvent * event );
virtual bool cb_mouseReleaseEvent ( QMouseEvent * event );
virtual bool cb_mouseMoveEvent(QMouseEvent * event);
virtual bool cb_wheelEvent ( QWheelEvent * event );
virtual void cb_resizeEvent ( QResizeEvent * event);
virtual void cb_levelChanged(int nLevel);
virtual void cb_update();
public:
bool cb_isActive() {return m_bActive;}
void cb_setActive(bool at) { m_bActive = at; cb_update();}
bool cb_isVisible() {return m_bVisible;}
void cb_setVisible(bool vb) { m_bVisible = vb; cb_update(); }
QString cb_name() {return m_name;}
void cb_setName(QString vb) { m_name = vb; }
protected:
void setServerUrl(QString url);
void setLocalCache(QString cache);
tilesviewer * m_pViewer;
layer_tiles_page * m_propPage;
bool m_bActive;
bool m_bVisible;
quint8 m_nAlpha;
QString m_name;
private:
bool m_bconnected;
QString m_strLocalCache;
QString m_strServerURL;
//The download tools
urlDownloader * m_downloader;
QThread * m_downloadThread;
//drag
int m_nStartPosX;
int m_nStartPosY;
private:
//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);
};
#endif // LAYER_TILES_H
#ifndef LAYER_TILES_H
#define LAYER_TILES_H
#include <QObject>
#include <QVector>
#include "layer_interface.h"
#include "urlDownloader.h"
#include "layer_tiles_page.h"
namespace QTVOSM{
class tilesviewer;
/*! \brief layer_tiles is a basic Backgroud Layer, with is_exclusive = true.
* This means only ONE instances of layer_tiles could be active at sametime
*
* \class layer_tiles layer_tiles.h "qtviewer_planetosm/osmtiles/layer_tiles.h"
* \author goldenhawking \date 2015-12-11
*/
class layer_tiles :public QObject,public layer_interface
{
Q_OBJECT
friend class layer_tiles_page;
public:
explicit layer_tiles(QObject *parent = 0);
~layer_tiles();
QWidget * get_propWindow(){return m_propPage;}
void load_retranslate_UI(){m_propPage->reTransUI();}
QString serverUrl() {return m_strServerURL; }
QString localCache() {return m_strLocalCache; }
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();
virtual void cb_paintEvent( QPainter * pImage );
virtual bool cb_mousePressEvent ( QMouseEvent * event );
virtual bool cb_mouseReleaseEvent ( QMouseEvent * event );
virtual bool cb_mouseMoveEvent(QMouseEvent * event);
virtual bool cb_wheelEvent ( QWheelEvent * event );
virtual void cb_resizeEvent ( QResizeEvent * event);
virtual void cb_levelChanged(int nLevel);
public:
bool is_active() {return m_bActive;}
bool is_visible() {return m_bVisible;}
void set_visible(bool vb) { m_bVisible = vb; }
QString get_name() {return m_name;}
void set_name(QString vb) { m_name = vb; }
/*! OSM tiles has a responsability to maintain drag and mouse click,
It's exclusive, there should be only one layer_tiles active
*/
bool is_exclusive(){return true;}
void set_active(bool at) { m_bActive = at;}
protected:
tilesviewer * m_pViewer;
layer_tiles_page * m_propPage;
bool m_bActive;
bool m_bVisible;
quint8 m_nAlpha;
QString m_name;
private:
bool m_bconnected;
QString m_strLocalCache;
QString m_strServerURL;
//The download tools
urlDownloader * m_downloader;
QThread * m_downloadThread;
//drag
int m_nStartPosX;
int m_nStartPosY;
private:
//! 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);
public slots:
void setServerUrl(QString url);
void setLocalCache(QString cache);
signals:
void connected(bool);
void svrurlChanged(QString);
void cacheChanged(QString);
};
}
#endif // LAYER_TILES_H
#include "layer_tiles_page.h"
#include "ui_layer_tiles_page.h"
#include "layer_tiles.h"
#include <QSettings>
#include <QCoreApplication>
#include <QFileDialog>
layer_tiles_page::layer_tiles_page(layer_tiles * layer,QWidget *parent) :
QWidget(parent),
m_pLayer(layer),
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->cb_name()),"http://localhost/osm_tiles2/%1/%2/%3.png").toString();
QString strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(layer->cb_name()), QCoreApplication::applicationDirPath() +"/Cache").toString();
ui->lineEdit->setText(strLocalCache);
ui->plainTextEdit->setPlainText( strServerURL);
}
layer_tiles_page::~layer_tiles_page()
{
delete ui;
}
void layer_tiles_page::on_toolButton_browser_clicked()
{
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
QString strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(m_pLayer->cb_name()), QCoreApplication::applicationDirPath() +"/Cache").toString();
QString strFolder = QFileDialog::getExistingDirectory(this,tr("Select the local cache"),strLocalCache,QFileDialog::ShowDirsOnly);
if (strFolder.length())
ui->lineEdit->setText(strFolder);
}
void layer_tiles_page::on_pushButton_apply_clicked()
{
m_pLayer->setLocalCache(ui->lineEdit->text());
m_pLayer->setServerUrl(ui->plainTextEdit->toPlainText());
m_pLayer->UpdateLayer();
}
#include "layer_tiles_page.h"
#include "ui_layer_tiles_page.h"
#include "layer_tiles.h"
#include <QSettings>
#include <QCoreApplication>
#include <QFileDialog>
#include <QDebug>
#include <QCheckBox>
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->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();
ui->lineEdit->setText(strLocalCache);
ui->lineEdit_addressUrl->setText(strServerURL);
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);
connect (layer, &layer_tiles::connected ,this->ui->checkBox_connect, &QCheckBox::setChecked);
connect (layer, &layer_tiles::svrurlChanged ,this->ui->lineEdit_addressUrl, &QLineEdit::setText);
ui->checkBox_connect->setChecked(layer->isConnected());
}
void layer_tiles_page::reTransUI()
{
ui->retranslateUi(this);
}
layer_tiles_page::~layer_tiles_page()
{
delete ui;
}
void layer_tiles_page::on_toolButton_browser_clicked()
{
QSettings settings(QCoreApplication::applicationFilePath()+".ini",QSettings::IniFormat);
QString strLocalCache = settings.value(QString("settings/LocalCache_%1").arg(m_pLayer->get_name()), QCoreApplication::applicationDirPath() +"/OSMCache").toString();
QString strFolder = QFileDialog::getExistingDirectory(this,tr("Select the local cache"),strLocalCache,QFileDialog::ShowDirsOnly);
if (strFolder.length())
ui->lineEdit->setText(strFolder);
}
void layer_tiles_page::on_pushButton_apply_clicked()
{
m_pLayer->setLocalCache(ui->lineEdit->text());
m_pLayer->setServerUrl(ui->lineEdit_addressUrl->text());
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);
}
}
#ifndef LAYER_TILES_PAGE_H
#define LAYER_TILES_PAGE_H
#include <QWidget>
namespace Ui {
class layer_tiles_page;
}
class layer_tiles;
class layer_tiles_page : public QWidget
{
Q_OBJECT
public:
explicit layer_tiles_page(layer_tiles * layer,QWidget *parent = 0);
~layer_tiles_page();
private:
Ui::layer_tiles_page *ui;
layer_tiles * m_pLayer;
public slots:
void on_toolButton_browser_clicked();
void on_pushButton_apply_clicked();
};
#endif // LAYER_TILES_PAGE_H
#ifndef LAYER_TILES_PAGE_H
#define LAYER_TILES_PAGE_H
#include <QWidget>
#include <QStandardItemModel>
namespace Ui {
class layer_tiles_page;
}
namespace QTVOSM{
class layer_tiles;
/*!
\brief layer_tiles_page is the class of proper pages for layer_tiles
\class layer_tiles_page layer_tiles_page.h "qtviewer_planetosm/osmtiles/layer_tiles_page.h"
\author goldenhawking \date 2015-12-11
*/
class layer_tiles_page : public QWidget
{
Q_OBJECT
public:
explicit layer_tiles_page(layer_tiles * layer,QWidget *parent = 0);
~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 on_toolButton_browser_clicked();
void on_pushButton_apply_clicked();
void on_checkBox_connect_clicked(bool);
};
}
#endif // LAYER_TILES_PAGE_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>layer_tiles_page</class>
<widget class="QWidget" name="layer_tiles_page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>240</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Cahce Folder</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QToolButton" name="toolButton_browser">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_apply">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>layer_tiles_page</class>
<widget class="QWidget" name="layer_tiles_page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>332</width>
<height>305</height>
</rect>
</property>
<property name="windowTitle">
<string>Tiles Layer</string>
</property>
<property name="windowIcon">
<iconset resource="../resource/resource.qrc">
<normaloff>:/ui/icons/Crystal_folder19.png</normaloff>:/ui/icons/Crystal_folder19.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Pending tasks</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>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="lineEdit_addressUrl">
<property name="toolTip">
<string>such like &quot;http://localhost/osm_tiles2/%1/%2/%3.png&quot;</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_connect">
<property name="text">
<string>connect</string>
</property>
<property name="icon">
<iconset resource="../resource/resource.qrc">
<normaloff>:/ui/icons/cn11.png</normaloff>
<normalon>:/ui/icons/cn6.png</normalon>:/ui/icons/cn11.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Cahce Folder</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QToolButton" name="toolButton_browser">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_apply">
<property name="text">
<string>Apply</string>
</property>
<property name="icon">
<iconset resource="../resource/resource.qrc">
<normaloff>:/ui/icons/coffee.png</normaloff>:/ui/icons/coffee.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../resource/resource.qrc"/>
</resources>
<connections/>
</ui>
#ifndef TILESVIEWER_H
#define TILESVIEWER_H
#include <QWidget>
#include <QList>
#include <QSet>
#include "cProjectionMercator.h"
#include "viewer_interface.h"
namespace Ui {
class tilesviewer;
}
class layer_interface;
class tilesviewer : public QWidget , viewer_interface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID OSMViewInterface_iid )
Q_INTERFACES(viewer_interface)
public:
tilesviewer(QWidget *parent = 0);
~tilesviewer();
protected:
void paintEvent( QPaintEvent * event );
void mousePressEvent ( QMouseEvent * event );
void mouseReleaseEvent ( QMouseEvent * event );
void mouseMoveEvent(QMouseEvent * event);
void wheelEvent ( QWheelEvent * event ) ;
void resizeEvent ( QResizeEvent * event ) ;
protected:
//Center Lat,Lon
double m_dCenterX; //percentage, -0.5~0.5
double m_dCenterY; //percentage, -0.5~0.5
int m_nLevel; //0-18
//layers
QList < layer_interface * > m_listLayers;
QSet < layer_interface * > m_setLayers;
public:
//Convert LLA and DP Coords
bool oTVP_LLA2DP(double lat,double lon,qint32 * pX,qint32 *pY);
bool oTVP_DP2LLA(qint32 X,qint32 Y,double * plat,double * plon);
//cood convertion
bool CV_PercentageToPixel(int nLevel,double px,double py,int * nx,int * ny);
public:
//return current level
int level(){return m_nLevel; }
//center
double centerX(){return m_dCenterX;}
double centerY(){return m_dCenterY;}
//return current center view lat, lon
void centerLLA(double * lat, double * lon){oTVP_DP2LLA(width()/2,height()/2,lat,lon);}
//drag image for special pixes
void DragView(int nOffsetX,int nOffsetY);
public:
//layer Ctrl
bool addLayer(layer_interface * );
//layer Ctrl
void removeLayer(layer_interface * );
QVector<layer_interface * > layers();
QVector<QString> layerNames();
QVector<bool> layerVisibilities();
QVector<bool> layerActivities();
void moveLayerUp(layer_interface *);
void moveLayerDown(layer_interface *);
void moveLayerTop(layer_interface *);
void moveLayerBottom(layer_interface *);
public slots:
//set current level
void setLevel(int n);
//set current br level to n-4
void setBrLevel(int n);
//force update
void UpdateWindow();
//set center LLA
void setCenterLLA(double lat, double lon);
//set center LLA, not emit centerChanged
void setBrCenterLLA(double lat, double lon);
virtual QRect windowRect(){return this->rect();}
signals:
void evt_level_changed(int);
void evt_center_changed(double dLat, double dLon);
void evt_mouse_moved(double dLat, double dLon);
};
#endif // TILESVIEWER_H
#ifndef TILESVIEWER_H
#define TILESVIEWER_H
#include <QWidget>
#include <QList>
#include <QSet>
#include <QMutex>
#include <functional>
#include "cProjectionMercator.h"
#include "viewer_interface.h"
namespace Ui {
class tilesviewer;
}
namespace QTVOSM{
class layer_interface;
/*! \brief tilesviewer is the MAIN_MAP of this application
*
* It implement all interfaces of viewer_interface, maintain layrs, events, user interaction.
* \class tilesviewer tilesviewer.h "qtviewer_planetosm/osmtiles/tilesviewer.h"
* \author goldenhawking \date 2015-12-11
*/
class tilesviewer : public QWidget ,public viewer_interface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID OSMViewInterface_iid )
Q_INTERFACES(QTVOSM::viewer_interface)
public:
tilesviewer(QWidget *parent = 0);
~tilesviewer();
protected:
void paintEvent( QPaintEvent * event );
void mousePressEvent ( QMouseEvent * event );
void mouseReleaseEvent ( QMouseEvent * event );
void mouseMoveEvent(QMouseEvent * event);
void wheelEvent ( QWheelEvent * event ) ;
void resizeEvent ( QResizeEvent * event ) ;
void mouseDoubleClickEvent(QMouseEvent * event);
protected:
//Center Lat,Lon
double m_dCenterX; //percentage, -0.5~0.5
double m_dCenterY; //percentage, -0.5~0.5
int m_nLevel; //0-18
//layers
QList < layer_interface * > m_listLayers;
QSet < layer_interface * > m_setLayers;
//ASyn event systems
QMutex m_mutex_events;
QMutex m_mutex_listeners;
QList < QMap<QString, QVariant> > m_list_pendingEvts ;
QMap <QString, std::function<void (const QMap<QString, QVariant>)> > m_map_listeners;
public:
//Convert LLA and DP Coords
bool CV_LLA2DP(double lat,double lon,qint32 * pX,qint32 *pY);
bool CV_DP2LLA(qint32 X,qint32 Y,double * plat,double * plon);
//Convert Merkator and LLA
bool CV_MK2LLA(double mx, double my, double * plat, double * plon);
bool CV_LLA2MK(double lat,double lon, double * pmx, double * pmy);
//Convert Merkator and WorldPixel
bool CV_MK2World(double mx, double my, double * px, double * py);
bool CV_World2MK(double x,double y, double * pmx, double * pmy);
//Convert LLA and World
bool CV_LLA2World(double lat, double lon, double * px, double * py);
bool CV_World2LLA(double x,double y, double * plat, double * plon);
//Convert World and DP
bool CV_DP2World(qint32 dX, qint32 dY, double * px, double * py);
bool CV_World2DP(double x,double y, qint32 * dX, qint32 * dY);
//cood convertion
bool CV_Pct2World(double px,double py,double * nx,double * ny);
bool CV_World2Pct(double nx,double ny,double * px,double * py) ;
//events
bool send_event(const QMap<QString, QVariant> );
bool post_event(const QMap<QString, QVariant> );
void listen_event(QString name,std::function<void (const QMap<QString, QVariant>)> functor);
void unlisten_event(QString);
public:
//return current level
int level(){return m_nLevel; }
//center
double centerX(){return m_dCenterX;}
double centerY(){return m_dCenterY;}
//return current center view lat, lon
void centerLLA(double * lat, double * lon){CV_DP2LLA(width()/2,height()/2,lat,lon);}
//drag image for special pixes
void DragView(int nOffsetX,int nOffsetY);
public:
//layer Ctrl
bool addLayer(layer_interface * );
void removeLayer(layer_interface * );
bool adjust_layers(layer_interface * target );
virtual layer_interface * layer(const QString &);
QVector<layer_interface * > layers();
QVector<QString> layerNames();
QVector<bool> layerVisibilities();
QVector<bool> layerActivities();
void moveLayerUp(layer_interface *);
void moveLayerDown(layer_interface *);
void moveLayerTop(layer_interface *);
void moveLayerBottom(layer_interface *);
void updateLayerGridView();
public slots:
//set current level
void setLevel(int n);
//set current br level to n-4
void setBrLevel(int n);
//force update
void UpdateWindow();
//set center LLA
void setCenterLLA(double lat, double lon);
//set center LLA, not emit centerChanged
void setBrCenterLLA(double lat, double lon);
virtual QRect windowRect(){return this->rect();}
bool saveToImage(const QString & strFm);
protected slots:
void _do_next_evts();
signals:
void _inside_do_next_evts();
void evt_level_changed(int);
void evt_center_changed(double dLat, double dLon);
void cmd_update_layer_box();
};
}
#endif // TILESVIEWER_H
#include "urlDownloader.h"
#include <QNetworkRequest>
#include <QUrl>
#include <QDir>
urlDownloader::urlDownloader(QObject * pParent, int nMaxAsynThread)
:QObject(pParent)
,m_nMaxAsynThread(nMaxAsynThread)
{
m_pNetMge = 0;
connect(this,SIGNAL(evt_doNextJob()),
this,SLOT(newTaskAdded()),Qt::QueuedConnection
);
}
urlDownloader::~urlDownloader()
{
if (m_pNetMge)
m_pNetMge->deleteLater();
}
void urlDownloader::replyFinished(QNetworkReply* rply)
{
bool needDo = false;
bool allFinished = false;
m_mutex_protect.lock();
if (m_map_pendingTasks.contains(rply)==true)
{
if (rply->error()==QNetworkReply::NoError)
{
QString strDir = m_map_pendingTasks[rply][0];
QString strFile = m_map_pendingTasks[rply][1];
//mkdir
QDir dir(strDir);
dir.mkpath(strDir);
//saveFile
QFile file(strDir+"/"+strFile);
if (file.open(QIODevice::WriteOnly)==true)
{
file.write(rply->readAll());
file.close();
}
}
m_map_pendingTasks.remove(rply);
rply->deleteLater();
}
if (m_map_pendingTasks.size()<m_nMaxAsynThread && m_list_source.empty()==false)
needDo = true;
if (m_list_source.empty()==true && m_map_pendingTasks.empty()==true)
allFinished = true;
m_mutex_protect.unlock();
if (needDo)
emit evt_doNextJob();
if (allFinished == true)
emit evt_all_taskFinished();
}
void urlDownloader::newTaskAdded()
{
if (!m_pNetMge)
{
m_pNetMge = new QNetworkAccessManager(this);
connect(m_pNetMge, SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*)),Qt::QueuedConnection);
}
m_mutex_protect.lock();
while (m_map_pendingTasks.size()<m_nMaxAsynThread && m_list_source.empty()==false)
{
QString strSource = m_list_source.first();
QNetworkReply * ptply = m_pNetMge->get(QNetworkRequest(QUrl(strSource)));
m_map_pendingTasks[ptply].push_back(m_list_destinDir.first());
m_map_pendingTasks[ptply].push_back(m_list_destinFile.first());
m_list_source.pop_front();
m_list_destinFile.pop_front();
m_list_destinDir.pop_front();
}
m_mutex_protect.unlock();
}
void urlDownloader::addDownloadUrl(QString sourceUrl, QString DestinDir, QString filename)
{
bool bNeedEmit = false;
m_mutex_protect.lock();
if (m_map_pendingTasks.size()<m_nMaxAsynThread)
bNeedEmit = true;
m_list_source.push_back(sourceUrl);
m_list_destinDir.push_back(DestinDir);
m_list_destinFile.push_back(filename);
m_mutex_protect.unlock();
if (bNeedEmit)
emit evt_doNextJob();
}
#include "urlDownloader.h"
#include <QNetworkRequest>
#include <QUrl>
#include <QDir>
#include <assert.h>
namespace QTVOSM{
urlDownloader::urlDownloader(QObject * pParent, int nMaxAsynThread)
:QObject(pParent)
,m_nMaxAsynThread(nMaxAsynThread)
{
m_pNetMge = 0;
connect(this,SIGNAL(evt_doNextJob()),
this,SLOT(newTaskAdded()),Qt::QueuedConnection
);
}
urlDownloader::~urlDownloader()
{
if (m_pNetMge)
m_pNetMge->deleteLater();
}
void urlDownloader::replyFinished(QNetworkReply* rply)
{
bool needDo = false;
bool allFinished = false;
m_mutex_protect.lock();
if (m_map_pendingTasks.contains(rply)==true)
{
const tag_download_tasks & tk = m_map_pendingTasks[rply];
if (rply->error()==QNetworkReply::NoError)
{
QString strDir = tk.str_destinDir;
QString strFile = tk.str_destinFile;
//mkdir
QDir dir(strDir);
dir.mkpath(strDir);
//saveFile
QFile file(strDir+"/"+strFile);
if (file.open(QIODevice::WriteOnly)==true)
{
file.write(rply->readAll());
file.close();
}
}
QString uniqueKey = tk.str_url + ":" + tk.str_destinDir +":" + tk.str_destinFile;
m_set_tileAddress.remove(uniqueKey);
m_map_pendingTasks.remove(rply);
rply->deleteLater();
}
else
assert(false);
if (m_map_pendingTasks.size()<m_nMaxAsynThread && m_listTask.empty()==false)
needDo = true;
if (m_listTask.empty()==true && m_map_pendingTasks.empty()==true)
allFinished = true;
m_mutex_protect.unlock();
if (needDo)
emit evt_doNextJob();
if (allFinished == true)
emit evt_all_taskFinished();
}
void urlDownloader::newTaskAdded()
{
if (!m_pNetMge)
{
m_pNetMge = new QNetworkAccessManager(this);
connect(m_pNetMge, SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*)),Qt::QueuedConnection);
}
m_mutex_protect.lock();
while (m_map_pendingTasks.size()<m_nMaxAsynThread && m_listTask.empty()==false)
{
tag_download_tasks tk = m_listTask.first();
QNetworkReply * ptply = m_pNetMge->get(QNetworkRequest(QUrl(tk.str_url)));
m_map_pendingTasks[ptply]=tk;
m_listTask.pop_front();
}
m_mutex_protect.unlock();
}
void urlDownloader::addDownloadUrl(const QString & sourceUrl, const QString & DestinDir, const QString & filename,bool newerFirst )
{
bool bNeedEmit = false;
tag_download_tasks tk;
tk.str_url = sourceUrl;
tk.str_destinDir = DestinDir;
tk.str_destinFile = filename;
QString uniqueKey = sourceUrl + ":" + DestinDir +":" + filename;
m_mutex_protect.lock();
if (m_set_tileAddress.contains(uniqueKey)==true)
m_listTask.removeAll(tk);
else
m_set_tileAddress.insert(uniqueKey);
if (m_map_pendingTasks.size()<m_nMaxAsynThread)
bNeedEmit = true;
if (newerFirst)
m_listTask.push_front(tk);
else
m_listTask.push_back(tk);
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;
}
}
#ifndef URLDOWNLOADER_H
#define URLDOWNLOADER_H
#include <QObject>
#include <QVector>
#include <QThread>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMutex>
#include <QMap>
class urlDownloader : public QObject
{
Q_OBJECT
public:
urlDownloader(QObject * pParent, int nMaxAsynThread = 1);
~urlDownloader();
void addDownloadUrl(QString sourceUrl,QString DestinDir, QString filename);
protected:
QNetworkAccessManager * m_pNetMge;
QList<QString> m_list_source;
QList<QString> m_list_destinDir;
QList<QString> m_list_destinFile;
QMap <QNetworkReply * , QVector<QString> >m_map_pendingTasks;
QMutex m_mutex_protect;
int m_nMaxAsynThread;
protected slots:
void newTaskAdded();
void replyFinished(QNetworkReply*);
signals:
void evt_all_taskFinished();
void evt_doNextJob();
};
#endif // URLDOWNLOADER_H
#ifndef URLDOWNLOADER_H
#define URLDOWNLOADER_H
#include <QObject>
#include <QVector>
#include <QThread>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMutex>
#include <QMap>
#include <QSet>
namespace QTVOSM{
struct tag_download_tasks{
QString str_url;
QString str_destinDir;
QString str_destinFile;
bool operator == (const tag_download_tasks & t1)
{
return t1.str_url==str_url && t1.str_destinDir == str_destinDir && t1.str_destinFile == str_destinFile;
}
};
/*!
\brief urlDownloader is a toolclass for tile download.
\class urlDownloader urlDownloader.h "qtviewer_planetosm/osmtiles/urlDownloader.h"
*/
class urlDownloader : public QObject
{
Q_OBJECT
public:
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;
QNetworkAccessManager * m_pNetMge;
QList<tag_download_tasks> m_listTask;
QMap <QNetworkReply * ,tag_download_tasks >m_map_pendingTasks;
QMutex m_mutex_protect;
int m_nMaxAsynThread;
protected slots:
void newTaskAdded();
void replyFinished(QNetworkReply*);
signals:
void evt_all_taskFinished();
void evt_doNextJob();
};
}
#endif // URLDOWNLOADER_H
#ifndef VIEWER_INTERFACE_H
#define VIEWER_INTERFACE_H
#define OSMViewInterface_iid "org.goldenhawkingStudio.OSMViewer_iid.ViewerInterface"
class viewer_interface{
public:
virtual ~viewer_interface(){}
//Convert LLA and DP Coords
virtual bool oTVP_LLA2DP(double lat,double lon,qint32 * pX,qint32 *pY) = 0;
virtual bool oTVP_DP2LLA(qint32 X,qint32 Y,double * plat,double * plon) = 0;
virtual bool CV_PercentageToPixel(int nLevel,double px,double py,int * nx,int * ny) = 0;
//return current level
virtual int level() = 0;
//center
virtual double centerX() = 0;
virtual double centerY() = 0;
//return current center view lat, lon
virtual void centerLLA(double * lat, double * lon) = 0;
//drag image for special pixes
virtual void DragView(int nOffsetX,int nOffsetY) = 0;
//set current level
virtual void setLevel(int n) = 0;
//force update
virtual void UpdateWindow() = 0;
//set center LLA
virtual void setCenterLLA(double lat, double lon) = 0;
//set center LLA
virtual QRect windowRect() = 0;
};
Q_DECLARE_INTERFACE(viewer_interface, OSMViewInterface_iid)
#endif // VIEWER_INTERFACE_H
#ifndef VIEWER_INTERFACE_H
#define VIEWER_INTERFACE_H
#include <QMap>
#include <QVariant>
#include <QVector>
#include <QString>
#define OSMViewInterface_iid "org.goldenhawkingStudio.OSMViewer_iid.ViewerInterface"
namespace QTVOSM{
class layer_interface;
/*! viewer_interface is the basic interface of views.
* views is the canvas holds all layers. Actually, views is the MAINWND of a MAP.
* It contains a user interactive system, a coordinates system, it alse maintains the
* layers approaches, such as loading, ordering, setName, messages pumping
*
* The coordinates system in this framework listed below is very IMPORTANT:
* 1.Mercator projection: Project WGS 84 (LLA) to conformal cylindrical projection, which is wildy used by goole map, OSM, baidu map.
* Mercator coords unit is "Meter", the worldmap is square, means X,Y range are both from -pi * R to pi *R, R is the radius of earth.
* X's direction is from left,west (-) to right, east (+), Y's direction is from bottom,south(-) to top, north(+)
* the center (0,0) takes the same point at LLA (0,0,0), the Y axis is the prime meridian, X axis is the equator woof.
*
* 2.LLA, latitude, longitude and altitude
*
* 3.World Coordinate: uint:Pixel.
* Map system have different zoom level, from 0 to 18.
* At level 0, the Mercator Square is mapped onto a 256x256 tile.
* At level 1, the Mercator Square is mapped onto a 512x512 tile.
* At level 18,the Mercator Square is mapped onto a 67108864 x 67108864 tile. (size is 256 * 2 ^18)
* the coord direction of .World Coordinate is some different from Mercator projection.
* top-left is 0,0, right-bottom is 256 * 2 ^level-1,256 * 2 ^level-1
*
* 4.Percentage Coordinate: unit: 1%
* it simply stands for Mercator projection, as percentage, -0.5~0.5
*
* 5.Device Coords
* it corresponds to the widget coords.
*
* \class viewer_interface viewer_interface.h "qtviewer_planetosm/osmtiles/viewer_interface.h"
* \author goldenhawking \date 2015-12-11
*/
class viewer_interface{
public:
virtual ~viewer_interface(){}
public:
//! Convert LLA and DP Coords. from LLA to view port pixels
virtual bool CV_LLA2DP(double lat,double lon,qint32 * pX,qint32 *pY) = 0;
//! Convert LLA and DP Coords. from view port pixels to LLA
virtual bool CV_DP2LLA(qint32 X,qint32 Y,double * plat,double * plon) = 0;
//Convert Merkator and LLA
virtual bool CV_MK2LLA(double mx, double my, double * plat, double * plon) = 0;
virtual bool CV_LLA2MK(double lat,double lon, double * pmx, double * pmy) = 0;
//Convert Merkator and WorldPixel
virtual bool CV_MK2World(double mx, double my, double * px, double * py) = 0;
virtual bool CV_World2MK(double x,double y, double * pmx, double * pmy) = 0;
//Convert LLA and World
virtual bool CV_LLA2World(double lat, double lon, double * px, double * py) = 0;
virtual bool CV_World2LLA(double x,double y, double * plat, double * plon) = 0;
//Convert World and DP
virtual bool CV_DP2World(qint32 dX, qint32 dY, double * px, double * py) = 0;
virtual bool CV_World2DP(double x,double y, qint32 * dX, qint32 * dY) = 0;
//! Convert Global Percentage coods (-0.5% ~ 0.5%) to pixel coods {( 1<<nLevel ) * 256}
virtual bool CV_Pct2World(double px,double py,double * nx,double * ny) = 0;
virtual bool CV_World2Pct(double nx,double ny,double * px,double * py) = 0;
public:
//! return current level
virtual int level () = 0;
//! set current level, will re-paint the map when needed
virtual void setLevel (int n) = 0;
//! get centerX,percentage, -0.5~0.5
virtual double centerX () = 0;
//! get centerY,percentage, -0.5~0.5
virtual double centerY () = 0;
//! return current center view lat, lon
virtual void centerLLA (double * lat, double * lon) = 0;
//! set center LLA, will re-paint the map
virtual void setCenterLLA (double lat, double lon) = 0;
public:
//! make exclusive layrs being de-activated,except for target
virtual bool adjust_layers(layer_interface * target ) = 0;
virtual QVector<layer_interface * > layers() = 0;
virtual QVector<QString> layerNames() = 0;
virtual layer_interface * layer(const QString &) = 0;
virtual bool addLayer(layer_interface * ) = 0;
virtual void removeLayer(layer_interface * ) = 0;
virtual void moveLayerUp(layer_interface *)= 0;
virtual void moveLayerDown(layer_interface *)= 0;
virtual void moveLayerTop(layer_interface *)= 0;
virtual void moveLayerBottom(layer_interface *)= 0;
virtual void updateLayerGridView()= 0;
//! get the windows device size in pixels
virtual QRect windowRect() = 0;
//! force update
virtual void UpdateWindow() = 0;
//! drag image for special pixes
virtual void DragView(int nOffsetX,int nOffsetY) = 0;
virtual bool saveToImage(const QString & strFm) = 0;
public:
/*! post_event posts events to mainPRG and return immediately.
* the event system is formed by key-value maps. A message CAB at lease should contain 2
* pairs: destin and source
* destin means to whom this message is sent to. source means from whom this message is sent.
* MAIN_MAP means the main framework, it can be used both in source and destin
* OUTER means the plugins loaded from dynamic libraries and OCX containers. it can only be used in destin
* ALL means Every possible listenes. it can only be used in destin
* except these 3 names above, other names is freely used for convenience.
*
* \param QMap<QString.QVariant >
* \return bool Succeed = true.
*/
virtual bool post_event(const QMap<QString, QVariant> ) = 0;
/*! send events to mainPRG and return when all progress finished(Blocking).
* the event system is formed by key-value maps. A message CAB at lease should contain 2
* pairs: destin and source
* destin means to whom this message is sent to. source means from whom this message is sent.
* MAIN_MAP means the main framework, it can be used both in source and destin
* OUTER means the plugins loaded from dynamic libraries and OCX containers. it can only be used in destin
* ALL means Every possible listenes. it can only be used in destin
* except these 3 names above, other names is freely used for convenience.
*
* \param QMap<QString.QVariant >
* \return bool Succeed = true.
*/
virtual bool send_event(const QMap<QString, QVariant> ) = 0;
};
}
Q_DECLARE_INTERFACE(QTVOSM::viewer_interface, OSMViewInterface_iid)
#endif // VIEWER_INTERFACE_H
#include "qtaxviewer_planetosm.h"
#include "ui_osm_frame_widget.h"
#include <QAxFactory>
#include <QSettings>
#include <QCoreApplication>
#include <QLibraryInfo>
#include <QDebug>
#include <functional>
#include "osmtiles/tilesviewer.h"
#include "osmtiles/layer_tiles.h"
qtaxviewer_planetosm::qtaxviewer_planetosm(QWidget *parent )
:osm_frame_widget(parent)
{
m_mutex_proteced.lock();
QTVOSM_DEBUG("The qtaxviewer_planetosm class is constructing.");
connect (this,&qtaxviewer_planetosm::_evt_next_pending_evts,this,&qtaxviewer_planetosm::_next_pending_evts,Qt::QueuedConnection);
ui->widget_mainMap->listen_event("ACTIVEX", std::bind(&qtaxviewer_planetosm::evt_listener,this,std::placeholders::_1));
QCoreApplication * app = QCoreApplication::instance();
if (app)
{
qtTranslator.load("qt_" + QLocale::system().name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app->installTranslator(&qtTranslator);
QString strTransLocalFile =
QCoreApplication::applicationDirPath()+"/" +
"qtviewer_planetosm_"+
QLocale::system().name()+".qm";
if (true==appTranslator.load(strTransLocalFile ))
QTVOSM_DEBUG("Load translationfile")<<"\n\t"<<strTransLocalFile<<" Succeeded.";
else
QTVOSM_WARNING("Load translationfile")<<"\n\t"<<strTransLocalFile<<" Not Found.";
app->installTranslator(&appTranslator);
}
ui->retranslateUi(this);
QVector<layer_interface *> vec = ui->widget_mainMap->layers();
foreach(layer_interface * p, vec)
{
p->load_retranslate_UI();
}
QTVOSM_DEBUG("The qtaxviewer_planetosm class constructed.");
m_mutex_proteced.unlock();
}
qtaxviewer_planetosm::~qtaxviewer_planetosm()
{
ui->widget_mainMap->unlisten_event("ACTIVEX") ;
}
/*!
\brief setTileAddress set the address of the OSM layer.
a Address is almost like:
http://192.168.1.127/osm/%1/%2/%3.png
or
http://192.168.11.27/new/osm.cgi?z=%1&x=%2&y=%3
\fn qtaxviewer_planetosm::setTileAddress
\param addr QString type address.
*/
void qtaxviewer_planetosm::setTileAddress (QString addr)
{
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer("OSM");
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
lt->setServerUrl(addr);
}
}
QString qtaxviewer_planetosm::tileAddress() const
{
QString res = "http://c.tile.openstreetmap.org/%1/%2/%3.png";
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer("OSM");
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
res = lt->serverUrl();
}
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
task to download it from tileAddress()
\fn qtaxviewer_planetosm::ConnectToServer
*/
void qtaxviewer_planetosm::ConnectToServer (void)
{
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer("OSM");
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
lt->connectToTilesServer(true);
}
}
/*!
\brief return whether "auto download" checkbox is checked.
notice that even if this box is checked, if the URL of
remote tile server is not valid, this function will still return true.
\fn qtaxviewer_planetosm::IsConnected
\return int -1 means connected, 0 mean not.
*/
int qtaxviewer_planetosm::IsConnected(void)
{
tilesviewer * pv = this->ui->widget_mainMap ;
layer_interface * la = pv->layer("OSM");
if (la)
{
layer_tiles * lt = dynamic_cast<layer_tiles *>(la);
if (lt)
return lt->isConnected()==true?-1:0;
}
return 0;
}
int qtaxviewer_planetosm::GetLevel(void)
{
tilesviewer * pv = this->ui->widget_mainMap ;
return pv->level();
}
int qtaxviewer_planetosm::SetLevel(int lv)
{
tilesviewer * pv = this->ui->widget_mainMap ;
int res = pv->level();
pv->setLevel(lv);
return res;
}
double qtaxviewer_planetosm::GetCenterLatitude()
{
tilesviewer * pv = this->ui->widget_mainMap ;
double lat,lon;
pv->centerLLA(&lat,&lon);
return lat;
}
double qtaxviewer_planetosm::GetCenterLongitude()
{
tilesviewer * pv = this->ui->widget_mainMap ;
double lat,lon;
pv->centerLLA(&lat,&lon);
return lon;
}
int qtaxviewer_planetosm::SetCenterPos(double lat,double lon)
{
tilesviewer * pv = this->ui->widget_mainMap ;
pv->setCenterLLA(lat,lon);
return 1;
}
/*!
\brief this function does the samething as UI button "SaveImg"
it will call saveToImage() , and save current map view to file.
\fn qtaxviewer_planetosm::SaveCurrentViewToFile
\param fm filename in QString. ext name can specify the format.
\return int 1 means OK, 0 means failed.
*/
int qtaxviewer_planetosm::SaveCurrentViewToFile(QString fm)
{
tilesviewer * pv = this->ui->widget_mainMap ;
bool ok = pv->saveToImage(fm);
return ok==true?1:0;
}
/*!
\brief FrozenMap mean that
UI inputs, include MOUOSE, KEY, will take no effect for dragging
\fn qtaxviewer_planetosm::FrozenMap
\param status set status. >0 means frozen it, <0 means re-enable it, 0 means just get status
\return int the current status.
*/
int qtaxviewer_planetosm::FrozenMap(int status)
{
int ret = 0;
if (status==0)
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
for (int i=0;i<layers.size()&& ret == 0;++i)
{
//It's exclusive, there should be at most only one layer_tiles active
if (layers[i]->is_exclusive()==true && layers[i]->is_active()==true)
ret = -1;
}
if (ret==0)
ret = 1;
}
else if (status > 0)
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
for (int i=0;i<layers.size();++i)
{
//Turn all exclusive layers off( de-actived)
if (layers[i]->is_exclusive()==true && layers[i]->is_active()==true)
{
ret = 1;
layers[i]->set_active(false);
}
}
this->UpdateLayerTable();
}
else
{
QVector <layer_interface *> layers = ui->widget_mainMap->layers();
for (int i=0;i<layers.size() && ret == 0;++i)
{
//Turn first exclusive layers on( actived)
if (layers[i]->is_exclusive()==true && layers[i]->is_active()==true)
{
ret = -1;
layers[i]->set_active(true);
ui->widget_mainMap->adjust_layers(layers[i]);
}
}
this->UpdateLayerTable();
}
return ret;
}
/*!
\brief this protected function is designed to filter events, and fire OCX events when needed.
\fn qtaxviewer_planetosm::evt_listener
\param QMap<QString
\param e
*/
void qtaxviewer_planetosm::evt_listener(const QMap<QString, QVariant> e)
{
if (e["destin"]=="ALL" || e["destin"]=="OUTER")
{
bool needFire = false;
m_mutex_evts.lock();
m_list_events.push_back(e);
if (m_list_events.size()==1)
needFire = true;
m_mutex_evts.unlock();
if (needFire)
emit _evt_next_pending_evts();
}
}
/*!
\brief _next_pending_evts is the internal event loop for interesting events.
\fn qtaxviewer_planetosm::_next_pending_evts
*/
void qtaxviewer_planetosm::_next_pending_evts()
{
//!1, In this function, we will first check whether the queue m_list_events is empty.
const QMap<QString, QVariant> * e = 0;
bool needFire = false;
m_mutex_evts.lock();
//!2, If it is not empty, get the earlist item from begin.(FIFO)
if (m_list_events.empty()==false)
e = & *m_list_events.constBegin();
m_mutex_evts.unlock();
//!3,Extract dsource,destin, lat, lon from map
QString str_source = e->value("source").toString();
QString str_name = e->value("name").toString();
double d_lat = e->value("main_lat").toDouble();
double d_lon = e->value("main_lon").toDouble();
QString str_additional_prop;
//!4, for other key-value paras, just put it into str_additional_prop
for(QMap<QString, QVariant>::const_iterator p = e->begin();p!=e->end();++p)
{
if (p.key()!="source" && p.key()!="name" && p.key()!="main_lat" && p.key()!="main_lon")
{
str_additional_prop += p.key();
str_additional_prop +="=";
str_additional_prop +=p.value().toString();
str_additional_prop +=";";
}
}
//!5,Fire the OCX Event
emit evt_Message(str_source,str_name,d_lat,d_lon,str_additional_prop);
//pop from queue
m_mutex_evts.lock();
e = 0;
m_list_events.pop_front();
if (m_list_events.size())
needFire = true;
m_mutex_evts.unlock();
if (needFire)
emit _evt_next_pending_evts();
}
QAXFACTORY_DEFAULT(qtaxviewer_planetosm,
"{8FDF97AD-FEFA-44C9-973B-1B66D4C529DF}",
"{4272B226-BAF3-4B7D-87F5-FBFB9D472666}",
"{8530D719-A863-4C2A-A1C6-77DC9DC06A5F}",
"{38D95322-682B-4CD5-9F28-C24775D70E33}",
"{581539E7-58EB-4F90-9B98-B7C4603B7163}")
; Declares the module parameters.
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DumpIDL PRIVATE
#ifndef QTAXVIEWER_PLANETOSM_H
#define QTAXVIEWER_PLANETOSM_H
#include <QAxBindable>
#include <QTranslator>
#include <QMap>
#include <QVariant>
#include <QList>
#include <QMutex>
#include "osm_frame_widget.h"
/*!
\brief This class inher from osm_frame_widget and QAxBindable,
Provides event systems and function call interface
\class qtaxviewer_planetosm qtaxviewer_planetosm.h "qtviewer_planetosm/qtaxviewer_planetosm.h"
\author goldenhawking \date 2015-12-11
*/
class qtaxviewer_planetosm :public osm_frame_widget, public QAxBindable
{
Q_OBJECT
Q_PROPERTY(QString tileAddress READ tileAddress WRITE setTileAddress)
protected:
QTranslator qtTranslator;
QTranslator appTranslator;
//!event Listeners
QMutex m_mutex_evts;
QList<QMap<QString, QVariant> > m_list_events;
void evt_listener(const QMap<QString, QVariant> e);
public:
explicit qtaxviewer_planetosm(QWidget *parent = 0);
~qtaxviewer_planetosm();
//! return the tileAddress which OSM plugin take use of
QString tileAddress(void) const;
//! slots below is designed for activeX interfaces
public slots:
void setTileAddress (QString);
void ConnectToServer (void);
int IsConnected(void);
//Navigate
int GetLevel(void);
int SetLevel(int);
double GetCenterLatitude();
double GetCenterLongitude();
int SetCenterPos(double lat,double lon);
//! \brief PrintScreen
int SaveCurrentViewToFile(QString);
//! \brief acitve/ deactive Map drag
int FrozenMap(int status);
//! new interfaces
public slots:
protected slots:
//! internal evts
void _next_pending_evts();
signals:
void _evt_next_pending_evts();
//! Classical MFC-Styly messages
void evt_Message(QString ,QString ,double,double,QString);
};
#endif // QTAXVIEWER_PLANETOSM_H
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-19T17:46:14
#
#-------------------------------------------------
QT += core gui network axserver
linux:QMAKE_CXXFLAGS += -std=c++11
win32-g++:QMAKE_CXXFLAGS += -std=c++11
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ../../bin/qtaxviewer_planetosm
TEMPLATE = lib
CONFIG += dll
SOURCES += qtaxviewer_planetosm.cpp\
osm_frame_widget.cpp \
osmtiles/cProjectionMercator.cpp \
osmtiles/tilesviewer.cpp \
osmtiles/urlDownloader.cpp \
osmtiles/layer_tiles.cpp \
osmtiles/layer_browser.cpp \
osmtiles/layer_tiles_page.cpp
HEADERS += qtaxviewer_planetosm.h \
osm_frame_widget.h \
osmtiles/cProjectionMercator.h \
osmtiles/tilesviewer.h \
osmtiles/urlDownloader.h \
osmtiles/layer_tiles.h \
osmtiles/layer_browser.h \
osmtiles/layer_interface.h \
osmtiles/viewer_interface.h \
osmtiles/layer_tiles_page.h
FORMS += osm_frame_widget.ui \
osmtiles/layer_tiles_page.ui
DEF_FILE = qtaxviewer_planetosm.def
RC_FILE = qtaxviewer_planetosm.rc
OTHER_FILES += \
qtaxviewer_planetosm.def\
qtaxviewer_planetosm.rc\
qtaxviewer_planetosm.ico\
qtviewer_planetosm_zh_CN.ts
RESOURCES += \
resource/resource.qrc
TRANSLATIONS += qtviewer_planetosm_zh_CN.ts
1 TYPELIB "qtaxviewer_planetosm.rc"
1 ICON DISCARDABLE "qtaxviewer_planetosm.ico"
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-19T17:46:14
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ../../bin/qtviewer_planetosm
TEMPLATE = app
SOURCES += main.cpp\
osm_frame_widget.cpp \
osmtiles/cProjectionMercator.cpp \
osmtiles/tilesviewer.cpp \
osmtiles/urlDownloader.cpp \
osmtiles/layer_tiles.cpp \
osmtiles/layer_browser.cpp \
osmtiles/layer_tiles_page.cpp
HEADERS += osm_frame_widget.h \
osmtiles/cProjectionMercator.h \
osmtiles/tilesviewer.h \
osmtiles/urlDownloader.h \
osmtiles/layer_tiles.h \
osmtiles/layer_browser.h \
osmtiles/layer_interface.h \
osmtiles/viewer_interface.h \
osmtiles/layer_tiles_page.h
FORMS += osm_frame_widget.ui \
osmtiles/layer_tiles_page.ui
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-19T17:46:14
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
linux:QMAKE_CXXFLAGS += -std=c++11
win32-g++:QMAKE_CXXFLAGS += -std=c++11
TARGET = ../../bin/qtviewer_planetosm
TEMPLATE = app
SOURCES += main.cpp\
osm_frame_widget.cpp \
osmtiles/cProjectionMercator.cpp \
osmtiles/tilesviewer.cpp \
osmtiles/urlDownloader.cpp \
osmtiles/layer_tiles.cpp \
osmtiles/layer_browser.cpp \
osmtiles/layer_tiles_page.cpp
HEADERS += osm_frame_widget.h \
osmtiles/cProjectionMercator.h \
osmtiles/tilesviewer.h \
osmtiles/urlDownloader.h \
osmtiles/layer_tiles.h \
osmtiles/layer_browser.h \
osmtiles/layer_interface.h \
osmtiles/viewer_interface.h \
osmtiles/layer_tiles_page.h
FORMS += osm_frame_widget.ui \
osmtiles/layer_tiles_page.ui
win32{
RC_FILE = qtaxviewer_planetosm.rc
OTHER_FILES += \
qtaxviewer_planetosm.rc\
qtaxviewer_planetosm.ico\
qtviewer_planetosm_zh_CN.ts
}
RESOURCES += \
resource/resource.qrc
TRANSLATIONS += qtviewer_planetosm_zh_CN.ts
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
<name>QTVOSM::layer_tiles_page</name>
<message>
<location filename="osmtiles/layer_tiles_page.cpp" line="26"/>
<source>url</source>
<translation>源地址</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.cpp" line="27"/>
<source>destin dir</source>
<translation>目的文件夹</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.cpp" line="28"/>
<source>filename</source>
<translation>缓存文件名</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.cpp" line="48"/>
<source>Select the local cache</source>
<translation>选择本地缓存路径</translation>
</message>
</context>
<context>
<name>layer_tiles_page</name>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="14"/>
<source>Tiles Layer</source>
<translation>瓦片图层</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="24"/>
<source>Pending tasks</source>
<translation>缓存的下载任务</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="41"/>
<source>Address</source>
<translation>瓦片服务地址</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="50"/>
<source>such like &quot;http://localhost/osm_tiles2/%1/%2/%3.png&quot;</source>
<translation>类似&quot;http://localhost/osm_tiles2/%1/%2/%3.png&quot;</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="57"/>
<source>connect</source>
<translation>联接并按需下载</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="73"/>
<source>Cahce Folder</source>
<translation>本地缓存文件夹</translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="83"/>
<source>...</source>
<translation></translation>
</message>
<message>
<location filename="osmtiles/layer_tiles_page.ui" line="90"/>
<source>Apply</source>
<translation>应用</translation>
</message>
</context>
<context>
<name>osm_frame_widget</name>
<message>
<location filename="osm_frame_widget.ui" line="14"/>
<source>osm_frame_widget</source>
<translation>Open Street Map 浏览器框架</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="67"/>
<source>Map</source>
<translation>地图</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="139"/>
<source>Tools</source>
<translation>工具</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="284"/>
<source>Activate</source>
<translation>激活图层</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="245"/>
<source>export</source>
<translation>截图保存</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="301"/>
<source>Deactive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="325"/>
<source>Show</source>
<translation>显示</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="342"/>
<source>Hide</source>
<translation>隐藏</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="388"/>
<source>Up</source>
<translation>上移</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="405"/>
<source>Top</source>
<translation>置顶</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="429"/>
<source>Down</source>
<translation>下移</translation>
</message>
<message>
<location filename="osm_frame_widget.ui" line="446"/>
<source>Bottom</source>
<translation>置底</translation>
</message>
<message>
<location filename="osm_frame_widget.cpp" line="20"/>
<source>name</source>
<translation>图层</translation>
</message>
<message>
<location filename="osm_frame_widget.cpp" line="21"/>
<source>active</source>
<translation>激活</translation>
</message>
<message>
<location filename="osm_frame_widget.cpp" line="22"/>
<source>visible</source>
<translation>可见</translation>
</message>
<message>
<location filename="osm_frame_widget.cpp" line="367"/>
<source>save to image</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册