Compare commits
21 Commits
04b40d367c
...
04d9cf6edf
| Author | SHA1 | Date | |
|---|---|---|---|
| 04d9cf6edf | |||
| 66dc481d6e | |||
| f8e361190b | |||
| 745376adfb | |||
| 13d4e6cb75 | |||
| 0f13cf5196 | |||
| d403d0a242 | |||
| c959a712f7 | |||
| f9a8f5d6b1 | |||
| 49ae1473f9 | |||
| b8e8a1300e | |||
| 26396a4f72 | |||
| 2cb43ab411 | |||
| 8df58026c4 | |||
| f0c2369df0 | |||
| a0f2d80b4f | |||
| 347104d512 | |||
| bf11ca21c0 | |||
| f36038bf10 | |||
| 266e9ac351 | |||
| c6b2bb128a |
@@ -135,7 +135,7 @@ JavaScriptWrapImports: true
|
|||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
LambdaBodyIndentation: Signature
|
LambdaBodyIndentation: Signature
|
||||||
MacroBlockBegin: "PRIVATE_DEFINITION_START|STATIC_INITIALIZER_BEGIN"
|
MacroBlockBegin: "PRIVATE_DEFINITION_START|STATIC_INITIALIZER_BEGIN"
|
||||||
MacroBlockEnd: "PRIVATE_DEFINITION_END|STATIC_INITIALIZER_END"
|
MacroBlockEnd: "PRIVATE_DEFINITION_END|PRIVATE_DEFINITION_END_NO_INITIALIZE|STATIC_INITIALIZER_END"
|
||||||
MaxEmptyLinesToKeep: 2
|
MaxEmptyLinesToKeep: 2
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
ObjCBinPackProtocolList: Auto
|
ObjCBinPackProtocolList: Auto
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||||
cmake_policy(SET CMP0072 NEW) # FindOpenGL prefers GLVND by default
|
cmake_policy(SET CMP0072 NEW) # FindOpenGL prefers GLVND by default
|
||||||
project(QAD)
|
project(QAD)
|
||||||
set(QAD_MAJOR 2)
|
set(QAD_MAJOR 2)
|
||||||
set(QAD_MINOR 32)
|
set(QAD_MINOR 32)
|
||||||
set(QAD_REVISION 0)
|
set(QAD_REVISION 2)
|
||||||
set(QAD_SUFFIX )
|
set(QAD_SUFFIX )
|
||||||
set(QAD_COMPANY SHS)
|
set(QAD_COMPANY SHS)
|
||||||
set(QAD_DOMAIN org.SHS)
|
set(QAD_DOMAIN org.SHS)
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ set(__deps_application "QAD::Widgets")
|
|||||||
set(__deps_blockview "QAD::Widgets")
|
set(__deps_blockview "QAD::Widgets")
|
||||||
set(__deps_graphic "QAD::Widgets")
|
set(__deps_graphic "QAD::Widgets")
|
||||||
set(__deps_graphic_analysis "QAD::Graphic;PIP::FFTW")
|
set(__deps_graphic_analysis "QAD::Graphic;PIP::FFTW")
|
||||||
set(__deps_sql "QAD::Utils")
|
|
||||||
set(__deps_sql_table "QAD::Widgets")
|
set(__deps_sql_table "QAD::Widgets")
|
||||||
set(__deps_map "QAD::Utils;QAD::PIQt")
|
set(__deps_map "QAD::Utils;QAD::PIQt")
|
||||||
set(__deps_piqt "QAD::Widgets;PIP")
|
set(__deps_piqt "QAD::Widgets;PIP")
|
||||||
|
|||||||
@@ -137,6 +137,9 @@ endif()
|
|||||||
if (POLICY CMP0074)
|
if (POLICY CMP0074)
|
||||||
cmake_policy(SET CMP0074 NEW) # ignore <PackageName>_ROOT variables
|
cmake_policy(SET CMP0074 NEW) # ignore <PackageName>_ROOT variables
|
||||||
endif()
|
endif()
|
||||||
|
if (POLICY CMP0177)
|
||||||
|
cmake_policy(SET CMP0177 OLD)
|
||||||
|
endif()
|
||||||
set(__qt_bug_modules "UiTools")
|
set(__qt_bug_modules "UiTools")
|
||||||
|
|
||||||
set(__qt_modules_4 "CLucene;Core;Declarative;Gui;Help;main;Multimedia;Network;OpenGL;\
|
set(__qt_modules_4 "CLucene;Core;Declarative;Gui;Help;main;Multimedia;Network;OpenGL;\
|
||||||
@@ -723,7 +726,7 @@ macro(qad_target_link_libraries _NAME)
|
|||||||
list(APPEND _ARGS ${_i})
|
list(APPEND _ARGS ${_i})
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
target_link_libraries(${_TARGET} ${Qt${_v}_LIBRARIES} ${_ARGS})
|
target_link_libraries(${_TARGET} ${_ARGS} ${Qt${_v}_LIBRARIES})
|
||||||
#message("link ${_TARGET}: ${Qt${_v}_LIBRARIES} ${_ARGS}")
|
#message("link ${_TARGET}: ${Qt${_v}_LIBRARIES} ${_ARGS}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ if (MARKDOWN_LIBRARY)
|
|||||||
qad_library(doc "Core" "${MARKDOWN_LIBRARY}")
|
qad_library(doc "Core" "${MARKDOWN_LIBRARY}")
|
||||||
if(NOT _mkd_header_found)
|
if(NOT _mkd_header_found)
|
||||||
message(STATUS "Found markdown library, but *.h missing!")
|
message(STATUS "Found markdown library, but *.h missing!")
|
||||||
|
add_definitions("-DMARKDOWN_HEADER=\"markdown/markdown.h\"")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
add_definitions("-DNO_MARKDOWN")
|
add_definitions("-DNO_MARKDOWN")
|
||||||
|
|||||||
@@ -193,7 +193,8 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
|
|||||||
selpen = palette().color(QPalette::WindowText);
|
selpen = palette().color(QPalette::WindowText);
|
||||||
selpen.setStyle(Qt::DashLine);
|
selpen.setStyle(Qt::DashLine);
|
||||||
back_color = palette().color(QPalette::Base);
|
back_color = palette().color(QPalette::Base);
|
||||||
buttons_ = AllButtons;
|
back_color.setAlpha(255);
|
||||||
|
buttons_ = AllButtons;
|
||||||
setOpenGL(false);
|
setOpenGL(false);
|
||||||
setButtonsPosition(Graphic::Left);
|
setButtonsPosition(Graphic::Left);
|
||||||
setAntialiasing(false);
|
setAntialiasing(false);
|
||||||
@@ -341,6 +342,7 @@ void Graphic::procGesture(QGesture * g) {
|
|||||||
QPointF dp = -pg->delta();
|
QPointF dp = -pg->delta();
|
||||||
dp.rx() /= getScaleX();
|
dp.rx() /= getScaleX();
|
||||||
dp.ry() /= getScaleY();
|
dp.ry() /= getScaleY();
|
||||||
|
dp.ry() = -dp.y();
|
||||||
selrect.translate(dp);
|
selrect.translate(dp);
|
||||||
totalUpdate();
|
totalUpdate();
|
||||||
} break;
|
} break;
|
||||||
@@ -356,11 +358,7 @@ void Graphic::procGesture(QGesture * g) {
|
|||||||
} break;
|
} break;
|
||||||
case Qt::TapAndHoldGesture: {
|
case Qt::TapAndHoldGesture: {
|
||||||
QTapAndHoldGesture * pg = (QTapAndHoldGesture *)g;
|
QTapAndHoldGesture * pg = (QTapAndHoldGesture *)g;
|
||||||
if (pg->state() == Qt::GestureStarted)
|
if (pg->state() == Qt::GestureStarted) QMetaObject::invokeMethod(this, [this]() { showMenu(); }, Qt::QueuedConnection);
|
||||||
QMetaObject::invokeMethod(
|
|
||||||
this,
|
|
||||||
[this]() { showMenu(); },
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
} break;
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,7 +255,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="qad_graphic.qrc">
|
<iconset resource="qad_graphic.qrc">
|
||||||
<normaloff>:/icons/zoom-original.png</normaloff>:/icons/zoom-original.png</iconset>
|
<normaloff>:/icons/zoom-original.png</normaloff>:/icons/zoom-original.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -505,6 +505,9 @@
|
|||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Esc</string>
|
<string>Esc</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcutContext">
|
||||||
|
<enum>Qt::WidgetShortcut</enum>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionCheck_all">
|
<action name="actionCheck_all">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
#include "osm_math_p.h"
|
#include "osm_math_p.h"
|
||||||
|
|
||||||
|
|
||||||
MapItemBase::MapItemBase() {}
|
MapItemBase::MapItemBase() {
|
||||||
|
m_hints = QPainter::Antialiasing | QPainter::SmoothPixmapTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MapItemBase::~MapItemBase() {
|
MapItemBase::~MapItemBase() {
|
||||||
@@ -19,6 +21,18 @@ void MapItemBase::setInteracive(bool newInteracive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapItemBase::setRenderHints(QPainter::RenderHints h) {
|
||||||
|
m_hints = h;
|
||||||
|
updateParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapItemBase::setRenderHint(QPainter::RenderHint h, bool on) {
|
||||||
|
m_hints.setFlag(h, on);
|
||||||
|
updateParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapItemBase::setVisible(bool newVisible) {
|
void MapItemBase::setVisible(bool newVisible) {
|
||||||
m_visible = newVisible;
|
m_visible = newVisible;
|
||||||
updateParent();
|
updateParent();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
QAD - Qt ADvanced
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -38,10 +38,13 @@ public:
|
|||||||
explicit MapItemBase();
|
explicit MapItemBase();
|
||||||
virtual ~MapItemBase();
|
virtual ~MapItemBase();
|
||||||
|
|
||||||
|
|
||||||
bool isInteracive() const { return m_interacive; }
|
bool isInteracive() const { return m_interacive; }
|
||||||
void setInteracive(bool newInteracive);
|
void setInteracive(bool newInteracive);
|
||||||
|
|
||||||
|
QPainter::RenderHints renderHints() const { return m_hints; }
|
||||||
|
void setRenderHints(QPainter::RenderHints h);
|
||||||
|
void setRenderHint(QPainter::RenderHint h, bool on = true);
|
||||||
|
|
||||||
bool isVisible() const { return m_visible; }
|
bool isVisible() const { return m_visible; }
|
||||||
void setVisible(bool newVisible);
|
void setVisible(bool newVisible);
|
||||||
bool isHidden() const { return !isVisible(); }
|
bool isHidden() const { return !isVisible(); }
|
||||||
@@ -97,6 +100,7 @@ private:
|
|||||||
QPointF m_position, m_scale = {1., 1.}, m_offset;
|
QPointF m_position, m_scale = {1., 1.}, m_offset;
|
||||||
QRectF m_bounding;
|
QRectF m_bounding;
|
||||||
QCursor m_cursor;
|
QCursor m_cursor;
|
||||||
|
QPainter::RenderHints m_hints;
|
||||||
QMap<int, QVariant> data_;
|
QMap<int, QVariant> data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "mapview.h"
|
#include "mapview.h"
|
||||||
|
|
||||||
#include "osm_downloader_p.h"
|
#include "mapview_tile_cache_p.h"
|
||||||
|
#include "mapview_tile_downloader_p.h"
|
||||||
#include "osm_math_p.h"
|
#include "osm_math_p.h"
|
||||||
#include "osm_tile_cache_p.h"
|
|
||||||
#include "qad_types.h"
|
#include "qad_types.h"
|
||||||
|
|
||||||
#include <QGraphicsPixmapItem>
|
#include <QGraphicsPixmapItem>
|
||||||
@@ -18,10 +18,10 @@ const int tileSize = 256;
|
|||||||
|
|
||||||
|
|
||||||
MapView::MapView(QWidget * parent): QWidget(parent) {
|
MapView::MapView(QWidget * parent): QWidget(parent) {
|
||||||
downloader = new OSMDownloader(this);
|
downloader = new MapViewTileDownloader(this);
|
||||||
cache = new OSMTileCache(this);
|
cache = new MapViewTileCache(this);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
connect(cache, &OSMTileCache::tileReady, this, [this]() {
|
connect(cache, &MapViewTileCache::tileReady, this, [this]() {
|
||||||
if (!is_downloading) drawBackground();
|
if (!is_downloading) drawBackground();
|
||||||
});
|
});
|
||||||
int size = 16;
|
int size = 16;
|
||||||
@@ -81,6 +81,12 @@ void MapView::setZoom(double z) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapView::setContrast(double value) {
|
||||||
|
contrast = piClampd(value, 0., 100.);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString MapView::cachePath() const {
|
QString MapView::cachePath() const {
|
||||||
return cache->cacheRoot();
|
return cache->cacheRoot();
|
||||||
}
|
}
|
||||||
@@ -92,16 +98,35 @@ void MapView::setCachePath(const QString & p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapView::setOfflineMode(bool yes) {
|
||||||
|
is_offline = yes;
|
||||||
|
cache->setOfflineMode(yes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapView::setTileObsoleteTime(int secs) {
|
void MapView::setTileObsoleteTime(int secs) {
|
||||||
cache->setTileObsoleteTime(secs);
|
cache->setTileObsoleteTime(secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void collectDownloadIndeces(OSMTileCache * cache,
|
void MapView::setTileProvider(MapViewTileProviderBase * p) {
|
||||||
QQueue<OSM::TileIndex> & indeces,
|
if (p) max_level = p->maximumLevel();
|
||||||
OSM::TileIndex index,
|
cache->clearCache();
|
||||||
int target_zoom_level,
|
downloader->setTileProvider(p);
|
||||||
bool only_new) {
|
drawBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileProviderBase * MapView::tileProvider() const {
|
||||||
|
return downloader->tileProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void collectDownloadIndeces(MapViewTileCache * cache,
|
||||||
|
QQueue<MapViewTypes::TileIndex> & indeces,
|
||||||
|
MapViewTypes::TileIndex index,
|
||||||
|
int target_zoom_level,
|
||||||
|
bool only_new) {
|
||||||
if (only_new) {
|
if (only_new) {
|
||||||
if (!cache->isTileFileExists(index)) indeces << index;
|
if (!cache->isTileFileExists(index)) indeces << index;
|
||||||
} else
|
} else
|
||||||
@@ -112,22 +137,22 @@ void collectDownloadIndeces(OSMTileCache * cache,
|
|||||||
int y = index.y * 2;
|
int y = index.y * 2;
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
for (int j = 0; j < 2; ++j) {
|
for (int j = 0; j < 2; ++j) {
|
||||||
collectDownloadIndeces(cache, indeces, (OSM::TileIndex){z, x + i, y + j}, target_zoom_level, only_new);
|
collectDownloadIndeces(cache, indeces, (MapViewTypes::TileIndex){z, x + i, y + j}, target_zoom_level, only_new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapView::downloadCurrentView(int target_zoom_level, bool only_new) {
|
void MapView::downloadCurrentView(int target_zoom_level, bool only_new, int parallel) {
|
||||||
int sx = qMax(0, (int)floor(view_rect.left() * tiles_side));
|
int sx = qMax(0, (int)floor(view_rect.left() * tiles_side));
|
||||||
int sy = qMax(0, (int)floor(view_rect.top() * tiles_side));
|
int sy = qMax(0, (int)floor(view_rect.top() * tiles_side));
|
||||||
int ex = qMin(tiles_side, (int)ceil(view_rect.right() * tiles_side));
|
int ex = qMin(tiles_side, (int)ceil(view_rect.right() * tiles_side));
|
||||||
int ey = qMin(tiles_side, (int)ceil(view_rect.bottom() * tiles_side));
|
int ey = qMin(tiles_side, (int)ceil(view_rect.bottom() * tiles_side));
|
||||||
target_zoom_level = qMin(target_zoom_level, max_level);
|
target_zoom_level = qMin(target_zoom_level, max_level);
|
||||||
QQueue<OSM::TileIndex> indeces;
|
QQueue<MapViewTypes::TileIndex> indeces;
|
||||||
for (int ix = sx; ix < ex; ++ix) {
|
for (int ix = sx; ix < ex; ++ix) {
|
||||||
for (int iy = sy; iy < ey; ++iy) {
|
for (int iy = sy; iy < ey; ++iy) {
|
||||||
collectDownloadIndeces(cache, indeces, (OSM::TileIndex){zoom_level, ix, iy}, target_zoom_level, only_new);
|
collectDownloadIndeces(cache, indeces, (MapViewTypes::TileIndex){zoom_level, ix, iy}, target_zoom_level, only_new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (indeces.size() < 4) return;
|
if (indeces.size() < 4) return;
|
||||||
@@ -141,7 +166,7 @@ void MapView::downloadCurrentView(int target_zoom_level, bool only_new) {
|
|||||||
std::atomic_int value(0);
|
std::atomic_int value(0);
|
||||||
auto conn = connect(
|
auto conn = connect(
|
||||||
downloader,
|
downloader,
|
||||||
&OSMDownloader::tileDone,
|
&MapViewTileDownloader::tileDone,
|
||||||
this,
|
this,
|
||||||
[this, &dialog, &indeces, &value]() {
|
[this, &dialog, &indeces, &value]() {
|
||||||
// qDebug() << "done";
|
// qDebug() << "done";
|
||||||
@@ -160,8 +185,10 @@ void MapView::downloadCurrentView(int target_zoom_level, bool only_new) {
|
|||||||
downloader->clearQueue();
|
downloader->clearQueue();
|
||||||
});
|
});
|
||||||
is_downloading = true;
|
is_downloading = true;
|
||||||
for (int i = 0; i < 1; ++i)
|
for (int i = 0; i < parallel; ++i) {
|
||||||
|
if (indeces.isEmpty()) break;
|
||||||
downloader->queueTile(indeces.dequeue());
|
downloader->queueTile(indeces.dequeue());
|
||||||
|
}
|
||||||
// dialog.exec();
|
// dialog.exec();
|
||||||
dialog.setModal(true);
|
dialog.setModal(true);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
@@ -237,6 +264,11 @@ void MapView::wheelEvent(QWheelEvent * e) {
|
|||||||
void MapView::paintEvent(QPaintEvent *) {
|
void MapView::paintEvent(QPaintEvent *) {
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
p.drawPixmap(0, 0, background);
|
p.drawPixmap(0, 0, background);
|
||||||
|
if (contrast < 100.) {
|
||||||
|
auto col = palette().color(QPalette::Window);
|
||||||
|
col.setAlphaF(1. - contrast / 100.);
|
||||||
|
p.fillRect(rect(), col);
|
||||||
|
}
|
||||||
drawItems(p);
|
drawItems(p);
|
||||||
updateMouse(mapFromGlobal(QCursor::pos()));
|
updateMouse(mapFromGlobal(QCursor::pos()));
|
||||||
}
|
}
|
||||||
@@ -264,12 +296,14 @@ void MapView::drawBackground() {
|
|||||||
QPointF offset = view_rect.topLeft() * mins * scale_;
|
QPointF offset = view_rect.topLeft() * mins * scale_;
|
||||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
p.setPen(Qt::white);
|
p.setPen(Qt::white);
|
||||||
|
QSizeF tile_size(tileSize, tileSize);
|
||||||
|
if (downloader->tileProvider()) tile_size = downloader->tileProvider()->tileSize();
|
||||||
for (int ix = sx; ix < ex; ++ix) {
|
for (int ix = sx; ix < ex; ++ix) {
|
||||||
for (int iy = sy; iy < ey; ++iy) {
|
for (int iy = sy; iy < ey; ++iy) {
|
||||||
QRectF r((ix)*ts, (iy)*ts, ts, ts);
|
QRectF r((ix)*ts, (iy)*ts, ts, ts);
|
||||||
r.translate(-offset);
|
r.translate(-offset);
|
||||||
QRectF px_rct(QPointF(), QSizeF(tileSize, tileSize));
|
QRectF px_rct(QPointF(), tile_size /*QSizeF(tileSize, tileSize)*/);
|
||||||
auto tile = cache->getTile((OSM::TileIndex){zoom_level, ix, iy}, px_rct);
|
auto tile = cache->getTile((MapViewTypes::TileIndex){zoom_level, ix, iy}, px_rct);
|
||||||
if (!tile.isEmpty()) {
|
if (!tile.isEmpty()) {
|
||||||
p.drawPixmap(r, tile.pixmap, px_rct);
|
p.drawPixmap(r, tile.pixmap, px_rct);
|
||||||
} else {
|
} else {
|
||||||
@@ -286,8 +320,7 @@ void MapView::drawBackground() {
|
|||||||
|
|
||||||
void MapView::drawItems(QPainter & p) {
|
void MapView::drawItems(QPainter & p) {
|
||||||
auto src_tr = p.transform();
|
auto src_tr = p.transform();
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
QPainter::RenderHints cur_hints;
|
||||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
||||||
QPoint mouse = mapFromGlobal(QCursor::pos());
|
QPoint mouse = mapFromGlobal(QCursor::pos());
|
||||||
MapItemBase * hover = nullptr;
|
MapItemBase * hover = nullptr;
|
||||||
for (auto * i: items_) {
|
for (auto * i: items_) {
|
||||||
@@ -298,6 +331,10 @@ void MapView::drawItems(QPainter & p) {
|
|||||||
p.translate(i->m_offset.x(), -i->m_offset.y());
|
p.translate(i->m_offset.x(), -i->m_offset.y());
|
||||||
p.rotate(i->getRotation());
|
p.rotate(i->getRotation());
|
||||||
if (!i->ignore_scale) p.scale(i->getScale().x(), i->getScale().y());
|
if (!i->ignore_scale) p.scale(i->getScale().x(), i->getScale().y());
|
||||||
|
if (cur_hints != i->renderHints()) {
|
||||||
|
cur_hints = i->renderHints();
|
||||||
|
p.setRenderHints(cur_hints);
|
||||||
|
}
|
||||||
i->draw(&p);
|
i->draw(&p);
|
||||||
QTransform mtr;
|
QTransform mtr;
|
||||||
mtr.rotate(-i->getRotation());
|
mtr.rotate(-i->getRotation());
|
||||||
@@ -338,7 +375,7 @@ void MapView::zoomLevelChanged(int new_level) {
|
|||||||
tiles_side = 1 << zoom_level;
|
tiles_side = 1 << zoom_level;
|
||||||
// for (int x = 0; x < tiles_side; ++x)
|
// for (int x = 0; x < tiles_side; ++x)
|
||||||
// for (int y = 0; y < tiles_side; ++y)
|
// for (int y = 0; y < tiles_side; ++y)
|
||||||
// downloader->queueTile(OSM::TileIndex{zoom_level, x, y});
|
// downloader->queueTile(MapViewTypes::TileIndex{zoom_level, x, y});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
QAD - Qt ADvanced
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -28,16 +28,19 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
||||||
class OSMDownloader;
|
class MapViewTileDownloader;
|
||||||
class OSMTileCache;
|
class MapViewTileProviderBase;
|
||||||
|
class MapViewTileCache;
|
||||||
|
|
||||||
class QAD_MAP_EXPORT MapView: public QWidget {
|
class QAD_MAP_EXPORT MapView: public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QPointF center READ center WRITE setCenter)
|
Q_PROPERTY(QPointF center READ center WRITE setCenter)
|
||||||
Q_PROPERTY(double zoom READ getZoom WRITE setZoom)
|
Q_PROPERTY(double zoom READ getZoom WRITE setZoom)
|
||||||
|
Q_PROPERTY(double contrast READ getContrast WRITE setContrast)
|
||||||
|
Q_PROPERTY(bool offlineMode READ isOfflineMode WRITE setOfflineMode)
|
||||||
|
|
||||||
friend class OSMDownloader;
|
friend class MapViewTileDownloader;
|
||||||
friend class OSMTileCache;
|
friend class MapViewTileCache;
|
||||||
friend class MapItemBase;
|
friend class MapItemBase;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -56,14 +59,25 @@ public:
|
|||||||
double getZoom() const { return zoom_; }
|
double getZoom() const { return zoom_; }
|
||||||
void setZoom(double z);
|
void setZoom(double z);
|
||||||
|
|
||||||
|
double getContrast() const { return contrast; }
|
||||||
|
|
||||||
|
/// 0 - 100
|
||||||
|
void setContrast(double value);
|
||||||
|
|
||||||
|
/// {lat, lng}
|
||||||
QPointF clickedCoordinate() const { return last_click_coord; }
|
QPointF clickedCoordinate() const { return last_click_coord; }
|
||||||
|
|
||||||
QString cachePath() const;
|
QString cachePath() const;
|
||||||
void setCachePath(const QString & p);
|
void setCachePath(const QString & p);
|
||||||
|
|
||||||
void setTileObsoleteTime(int secs);
|
bool isOfflineMode() const { return is_offline; }
|
||||||
|
void setOfflineMode(bool yes);
|
||||||
|
|
||||||
void downloadCurrentView(int target_zoom_level = 17, bool only_new = true);
|
void setTileObsoleteTime(int secs);
|
||||||
|
void setTileProvider(MapViewTileProviderBase * p);
|
||||||
|
MapViewTileProviderBase * tileProvider() const;
|
||||||
|
|
||||||
|
void downloadCurrentView(int target_zoom_level = 17, bool only_new = true, int parallel = 1);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSize sizeHint() const override { return QSize(200, 200); }
|
QSize sizeHint() const override { return QSize(200, 200); }
|
||||||
@@ -89,18 +103,18 @@ private:
|
|||||||
QPointF mapToNorm(QPoint screen) const;
|
QPointF mapToNorm(QPoint screen) const;
|
||||||
QPoint mapFromNorm(QPointF norm) const;
|
QPoint mapFromNorm(QPointF norm) const;
|
||||||
|
|
||||||
OSMDownloader * downloader = nullptr;
|
MapViewTileDownloader * downloader = nullptr;
|
||||||
OSMTileCache * cache = nullptr;
|
MapViewTileCache * cache = nullptr;
|
||||||
MapItemBase * hover = nullptr;
|
MapItemBase * hover = nullptr;
|
||||||
QPointF center_ = QPointF(0.5, 0.5);
|
QPointF center_ = QPointF(0.5, 0.5);
|
||||||
QPointF last_click_coord = center_;
|
QPointF last_click_coord = center_;
|
||||||
QPoint press_point, zoom_anchor;
|
QPoint press_point, zoom_anchor;
|
||||||
QPixmap background;
|
QPixmap background;
|
||||||
QRectF view_rect;
|
QRectF view_rect;
|
||||||
QVector<MapItemBase *> items_;
|
QVector<MapItemBase *> items_;
|
||||||
QBrush brush_tr;
|
QBrush brush_tr;
|
||||||
bool is_pan = false, is_downloading = false;
|
bool is_pan = false, is_downloading = false, is_offline = false;
|
||||||
double zoom_ = 1., scale_ = 1., px2m = 1.;
|
double zoom_ = 1., scale_ = 1., px2m = 1., contrast = 100.;
|
||||||
int zoom_level = 0, tiles_side = 1, max_level = 19;
|
int zoom_level = 0, tiles_side = 1, max_level = 19;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
#include "mapview.h"
|
#include "mapview.h"
|
||||||
#include "osm_downloader_p.h"
|
#include "mapview_tile_cache_p.h"
|
||||||
#include "osm_tile_cache_p.h"
|
#include "mapview_tile_downloader_p.h"
|
||||||
#include "qad_locations.h"
|
#include "qad_locations.h"
|
||||||
|
|
||||||
|
|
||||||
OSMTileCache::OSMTileCache(MapView * p): QThread() {
|
MapViewTileCache::MapViewTileCache(MapView * p): QThread() {
|
||||||
qRegisterMetaType<OSM::TileIndex>();
|
qRegisterMetaType<MapViewTypes::TileIndex>();
|
||||||
qRegisterMetaType<OSM::TilePixmap>();
|
qRegisterMetaType<MapViewTypes::TilePixmap>();
|
||||||
parent = p;
|
parent = p;
|
||||||
setCacheRoot(QAD::userPath(QAD::ltCache, "map_osm") + "/");
|
setCacheRoot(QAD::userPath(QAD::ltCache, "mapview") + "/");
|
||||||
setAdditionalCacheSize(64);
|
setAdditionalCacheSize(64);
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OSMTileCache::~OSMTileCache() {
|
MapViewTileCache::~MapViewTileCache() {
|
||||||
requestInterruption();
|
requestInterruption();
|
||||||
cond.wakeAll();
|
cond.wakeAll();
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSMTileCache::tileDownloaded(OSM::TileIndex index, const QPixmap & pixmap) {
|
void MapViewTileCache::tileDownloaded(MapViewTypes::TileIndex index, const QPixmap & pixmap) {
|
||||||
auto * tile = new OSM::TilePixmap();
|
auto * tile = new MapViewTypes::TilePixmap();
|
||||||
tile->index = index;
|
tile->index = index;
|
||||||
tile->pixmap = pixmap;
|
tile->pixmap = pixmap;
|
||||||
saveTile(tile);
|
saveTile(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OSM::TilePixmap OSMTileCache::getTile(OSM::TileIndex index, QRectF & rect_src) {
|
MapViewTypes::TilePixmap MapViewTileCache::getTile(MapViewTypes::TileIndex index, QRectF & rect_src) {
|
||||||
OSM::TilePixmap ret = getTileFromCache(index);
|
MapViewTypes::TilePixmap ret = getTileFromCache(index);
|
||||||
if (ret.isEmpty() || ret.obsolete) {
|
if (ret.isEmpty() || ret.obsolete) {
|
||||||
parent->downloader->queueTile(index);
|
if (!is_offline) parent->downloader->queueTile(index);
|
||||||
}
|
}
|
||||||
if (ret.isEmpty()) {
|
if (ret.isEmpty()) {
|
||||||
QVector<QPointF> offsets;
|
QVector<QPointF> offsets;
|
||||||
@@ -56,7 +56,12 @@ OSM::TilePixmap OSMTileCache::getTile(OSM::TileIndex index, QRectF & rect_src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OSMTileCache::isTileFileExists(OSM::TileIndex index) const {
|
void MapViewTileCache::clearCache() {
|
||||||
|
tile_cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MapViewTileCache::isTileFileExists(MapViewTypes::TileIndex index) const {
|
||||||
QString hashdir = index.cacheDir();
|
QString hashdir = index.cacheDir();
|
||||||
if (!cache_dir.exists(hashdir)) return false;
|
if (!cache_dir.exists(hashdir)) return false;
|
||||||
QString hashname = hashdir + "/" + index.hashName();
|
QString hashname = hashdir + "/" + index.hashName();
|
||||||
@@ -64,16 +69,30 @@ bool OSMTileCache::isTileFileExists(OSM::TileIndex index) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSMTileCache::setCacheRoot(const QString & p) {
|
void MapViewTileCache::setCacheRoot(const QString & p) {
|
||||||
cache_root = p;
|
cache_root = p;
|
||||||
|
tileProviderChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileCache::tileProviderChanged() {
|
||||||
cache_dir.setPath(cache_root);
|
cache_dir.setPath(cache_root);
|
||||||
qDebug() << "[OSMTileCache] Cache dir" << cache_root;
|
auto * provider = parent->downloader->provider;
|
||||||
|
if (provider) {
|
||||||
|
cache_dir.setPath(cache_root + "/" + provider->cacheDir());
|
||||||
|
}
|
||||||
|
qDebug() << "[MapViewTileCache] Cache dir" << cache_dir.absolutePath();
|
||||||
if (!cache_dir.exists()) cache_dir.mkpath(".");
|
if (!cache_dir.exists()) cache_dir.mkpath(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OSM::TilePixmap OSMTileCache::getTileFromCache(OSM::TileIndex index) {
|
void MapViewTileCache::setOfflineMode(bool yes) {
|
||||||
OSM::TilePixmap ret;
|
is_offline = yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTypes::TilePixmap MapViewTileCache::getTileFromCache(MapViewTypes::TileIndex index) {
|
||||||
|
MapViewTypes::TilePixmap ret;
|
||||||
ret.index = index;
|
ret.index = index;
|
||||||
auto * tile = tile_cache[index.hash()];
|
auto * tile = tile_cache[index.hash()];
|
||||||
if (tile) {
|
if (tile) {
|
||||||
@@ -85,7 +104,7 @@ OSM::TilePixmap OSMTileCache::getTileFromCache(OSM::TileIndex index) {
|
|||||||
if (cache_dir.exists(hashname)) {
|
if (cache_dir.exists(hashname)) {
|
||||||
QString fname = cache_dir.absoluteFilePath(hashname);
|
QString fname = cache_dir.absoluteFilePath(hashname);
|
||||||
ret.pixmap.load(fname, "png");
|
ret.pixmap.load(fname, "png");
|
||||||
tile = new OSM::TilePixmap();
|
tile = new MapViewTypes::TilePixmap();
|
||||||
tile->index = index;
|
tile->index = index;
|
||||||
tile->pixmap = ret.pixmap;
|
tile->pixmap = ret.pixmap;
|
||||||
if (secs_obsolete > 0) {
|
if (secs_obsolete > 0) {
|
||||||
@@ -101,12 +120,12 @@ OSM::TilePixmap OSMTileCache::getTileFromCache(OSM::TileIndex index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSMTileCache::updateCacheSize() {
|
void MapViewTileCache::updateCacheSize() {
|
||||||
tile_cache.setMaxCost(fixed_size_b + add_size_b);
|
tile_cache.setMaxCost(fixed_size_b + add_size_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSMTileCache::saveTile(OSM::TilePixmap * tile) {
|
void MapViewTileCache::saveTile(MapViewTypes::TilePixmap * tile) {
|
||||||
tile_cache.insert(tile->index.hash(), tile, tile->pixmapBytes());
|
tile_cache.insert(tile->index.hash(), tile, tile->pixmapBytes());
|
||||||
emit tileReady(*tile);
|
emit tileReady(*tile);
|
||||||
cond_mutex.lock();
|
cond_mutex.lock();
|
||||||
@@ -118,7 +137,7 @@ void OSMTileCache::saveTile(OSM::TilePixmap * tile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSMTileCache::writeToDisk(const OSM::TilePixmap & tile) {
|
void MapViewTileCache::writeToDisk(const MapViewTypes::TilePixmap & tile) {
|
||||||
QString hashdir = tile.index.cacheDir();
|
QString hashdir = tile.index.cacheDir();
|
||||||
if (!cache_dir.exists(hashdir)) cache_dir.mkdir(hashdir);
|
if (!cache_dir.exists(hashdir)) cache_dir.mkdir(hashdir);
|
||||||
QFile f(cache_dir.absoluteFilePath(hashdir + "/" + tile.index.hashName()));
|
QFile f(cache_dir.absoluteFilePath(hashdir + "/" + tile.index.hashName()));
|
||||||
@@ -128,9 +147,9 @@ void OSMTileCache::writeToDisk(const OSM::TilePixmap & tile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSMTileCache::run() {
|
void MapViewTileCache::run() {
|
||||||
while (!isInterruptionRequested()) {
|
while (!isInterruptionRequested()) {
|
||||||
OSM::TilePixmap tile;
|
MapViewTypes::TilePixmap tile;
|
||||||
cond_mutex.lock();
|
cond_mutex.lock();
|
||||||
if (queue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
cond.wait(&cond_mutex);
|
cond.wait(&cond_mutex);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
QAD - Qt ADvanced
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -17,10 +17,10 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef osm_tile_cache_h
|
#ifndef mapview_tile_cache_h
|
||||||
#define osm_tile_cache_h
|
#define mapview_tile_cache_h
|
||||||
|
|
||||||
#include "osm_types_p.h"
|
#include "mapview_types.h"
|
||||||
|
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
|
|
||||||
class MapView;
|
class MapView;
|
||||||
|
|
||||||
class OSMTileCache: public QThread {
|
class MapViewTileCache: public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OSMTileCache(MapView * p);
|
explicit MapViewTileCache(MapView * p);
|
||||||
~OSMTileCache();
|
~MapViewTileCache();
|
||||||
|
|
||||||
void setMinimumCacheSize(int bytes) {
|
void setMinimumCacheSize(int bytes) {
|
||||||
fixed_size_b = bytes;
|
fixed_size_b = bytes;
|
||||||
@@ -48,19 +48,23 @@ public:
|
|||||||
}
|
}
|
||||||
void setTileObsoleteTime(int secs) { secs_obsolete = secs; }
|
void setTileObsoleteTime(int secs) { secs_obsolete = secs; }
|
||||||
|
|
||||||
void tileDownloaded(OSM::TileIndex index, const QPixmap & pixmap);
|
void tileDownloaded(MapViewTypes::TileIndex index, const QPixmap & pixmap);
|
||||||
OSM::TilePixmap getTile(OSM::TileIndex index, QRectF & rect_src);
|
MapViewTypes::TilePixmap getTile(MapViewTypes::TileIndex index, QRectF & rect_src);
|
||||||
|
void clearCache();
|
||||||
|
|
||||||
bool isTileFileExists(OSM::TileIndex index) const;
|
bool isTileFileExists(MapViewTypes::TileIndex index) const;
|
||||||
|
|
||||||
QString cacheRoot() const { return cache_root; }
|
QString cacheRoot() const { return cache_root; }
|
||||||
void setCacheRoot(const QString & p);
|
void setCacheRoot(const QString & p);
|
||||||
|
|
||||||
|
void tileProviderChanged();
|
||||||
|
void setOfflineMode(bool yes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OSM::TilePixmap getTileFromCache(OSM::TileIndex index);
|
MapViewTypes::TilePixmap getTileFromCache(MapViewTypes::TileIndex index);
|
||||||
void updateCacheSize();
|
void updateCacheSize();
|
||||||
void saveTile(OSM::TilePixmap * tile);
|
void saveTile(MapViewTypes::TilePixmap * tile);
|
||||||
void writeToDisk(const OSM::TilePixmap & tile);
|
void writeToDisk(const MapViewTypes::TilePixmap & tile);
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
MapView * parent;
|
MapView * parent;
|
||||||
@@ -70,15 +74,16 @@ private:
|
|||||||
QMutex cond_mutex;
|
QMutex cond_mutex;
|
||||||
int secs_obsolete = -1;
|
int secs_obsolete = -1;
|
||||||
int fixed_size_b = 0, add_size_b = 0;
|
int fixed_size_b = 0, add_size_b = 0;
|
||||||
QQueue<OSM::TilePixmap> queue;
|
bool is_offline = false;
|
||||||
QCache<quint64, OSM::TilePixmap> tile_cache;
|
QQueue<MapViewTypes::TilePixmap> queue;
|
||||||
|
QCache<quint64, MapViewTypes::TilePixmap> tile_cache;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tileReady(OSM::TilePixmap);
|
void tileReady(MapViewTypes::TilePixmap);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
97
libs/map/mapview_tile_downloader.cpp
Normal file
97
libs/map/mapview_tile_downloader.cpp
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#include "mapview.h"
|
||||||
|
#include "mapview_tile_cache_p.h"
|
||||||
|
#include "mapview_tile_downloader_p.h"
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileDownloader::MapViewTileDownloader(MapView * p): QThread() {
|
||||||
|
qRegisterMetaType<MapViewTypes::TileIndex>();
|
||||||
|
parent = p;
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileDownloader::~MapViewTileDownloader() {
|
||||||
|
requestInterruption();
|
||||||
|
cond.wakeAll();
|
||||||
|
wait();
|
||||||
|
if (provider) provider->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MapViewTileDownloader::queueTile(MapViewTypes::TileIndex index, bool force) {
|
||||||
|
// auto hash = tile.hash();
|
||||||
|
bool ret = false;
|
||||||
|
cond_mutex.lock();
|
||||||
|
if ((!queue.contains(index) && !in_progress.contains(index.hash())) || force) {
|
||||||
|
queue.enqueue(index);
|
||||||
|
cond.wakeOne();
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
cond_mutex.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::queueTiles(QList<MapViewTypes::TileIndex> indeces) {
|
||||||
|
cond_mutex.lock();
|
||||||
|
queue << indeces;
|
||||||
|
cond.wakeOne();
|
||||||
|
cond_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::clearQueue() {
|
||||||
|
cond_mutex.lock();
|
||||||
|
queue.clear();
|
||||||
|
cond_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::setTileProvider(MapViewTileProviderBase * p) {
|
||||||
|
if (provider) {
|
||||||
|
disconnect(provider, &MapViewTileProviderBase::tileReady, this, &MapViewTileDownloader::tileReady);
|
||||||
|
disconnect(provider, &MapViewTileProviderBase::parametersChanged, this, &MapViewTileDownloader::parametersChanged);
|
||||||
|
provider->deleteLater();
|
||||||
|
}
|
||||||
|
provider = p;
|
||||||
|
if (provider) {
|
||||||
|
connect(provider, &MapViewTileProviderBase::tileReady, this, &MapViewTileDownloader::tileReady);
|
||||||
|
connect(provider, &MapViewTileProviderBase::parametersChanged, this, &MapViewTileDownloader::parametersChanged);
|
||||||
|
}
|
||||||
|
parent->cache->tileProviderChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::requestTile(MapViewTypes::TileIndex index) {
|
||||||
|
if (!provider) return;
|
||||||
|
provider->requestTile(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::tileReady(MapViewTypes::TileIndex index, QPixmap pm) {
|
||||||
|
if (!pm.isNull()) parent->cache->tileDownloaded(index, pm);
|
||||||
|
cond_mutex.lock();
|
||||||
|
in_progress.remove(index.hash());
|
||||||
|
cond_mutex.unlock();
|
||||||
|
emit tileDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::parametersChanged() {
|
||||||
|
parent->cache->tileProviderChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileDownloader::run() {
|
||||||
|
while (!isInterruptionRequested()) {
|
||||||
|
cond_mutex.lock();
|
||||||
|
if (queue.isEmpty())
|
||||||
|
cond.wait(&cond_mutex);
|
||||||
|
else {
|
||||||
|
auto t = queue.dequeue();
|
||||||
|
in_progress.insert(t.hash());
|
||||||
|
QMetaObject::invokeMethod(parent, [this, t]() { requestTile(t); }, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
cond_mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
QAD - Qt ADvanced
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -17,10 +17,11 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef osm_downloader_h
|
#ifndef mapview_tile_downloader_h
|
||||||
#define osm_downloader_h
|
#define mapview_tile_downloader_h
|
||||||
|
|
||||||
#include "osm_types_p.h"
|
#include "mapview_tile_provider_base.h"
|
||||||
|
#include "mapview_types.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
@@ -33,32 +34,38 @@
|
|||||||
|
|
||||||
class MapView;
|
class MapView;
|
||||||
|
|
||||||
class OSMDownloader: public QThread {
|
class MapViewTileDownloader: public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
friend class MapViewTileCache;
|
||||||
explicit OSMDownloader(MapView * p);
|
|
||||||
~OSMDownloader();
|
|
||||||
|
|
||||||
bool queueTile(OSM::TileIndex index, bool force = false);
|
public:
|
||||||
void queueTiles(QList<OSM::TileIndex> indeces);
|
explicit MapViewTileDownloader(MapView * p);
|
||||||
|
~MapViewTileDownloader();
|
||||||
|
|
||||||
|
bool queueTile(MapViewTypes::TileIndex index, bool force = false);
|
||||||
|
void queueTiles(QList<MapViewTypes::TileIndex> indeces);
|
||||||
void clearQueue();
|
void clearQueue();
|
||||||
|
|
||||||
|
void setTileProvider(MapViewTileProviderBase * p);
|
||||||
|
MapViewTileProviderBase * tileProvider() const { return provider; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run() override;
|
void run() override;
|
||||||
void requestTile(OSM::TileIndex index);
|
void requestTile(MapViewTypes::TileIndex index);
|
||||||
|
|
||||||
MapView * parent;
|
MapView * parent;
|
||||||
QNetworkAccessManager * nam = nullptr;
|
MapViewTileProviderBase * provider = nullptr;
|
||||||
QString provider;
|
|
||||||
QWaitCondition cond;
|
QWaitCondition cond;
|
||||||
QMutex cond_mutex;
|
QMutex cond_mutex;
|
||||||
QQueue<OSM::TileIndex> queue;
|
QQueue<MapViewTypes::TileIndex> queue;
|
||||||
QSet<quint64> in_progress;
|
QSet<quint64> in_progress;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void tileReady(MapViewTypes::TileIndex index, QPixmap pm);
|
||||||
|
void parametersChanged();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tileDone();
|
void tileDone();
|
||||||
19
libs/map/mapview_tile_provider_base.cpp
Normal file
19
libs/map/mapview_tile_provider_base.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#include "mapview_tile_provider_base.h"
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileProviderBase::setParameters(const PIValueTree & vt) {
|
||||||
|
parameters.applyValues(vt);
|
||||||
|
applyParametersIntenal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileProviderBase::initParameters(const PIValueTree & vt) {
|
||||||
|
parameters = vt;
|
||||||
|
applyParametersIntenal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileProviderBase::applyParametersIntenal() {
|
||||||
|
applyParameters();
|
||||||
|
emit parametersChanged();
|
||||||
|
}
|
||||||
62
libs/map/mapview_tile_provider_base.h
Normal file
62
libs/map/mapview_tile_provider_base.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef mapview_tile_provider_base_h
|
||||||
|
#define mapview_tile_provider_base_h
|
||||||
|
|
||||||
|
#include "mapview_types.h"
|
||||||
|
#include "qad_map_export.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <pivaluetree.h>
|
||||||
|
|
||||||
|
|
||||||
|
class QAD_MAP_EXPORT MapViewTileProviderBase: public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MapViewTileProviderBase() {}
|
||||||
|
virtual ~MapViewTileProviderBase() {}
|
||||||
|
|
||||||
|
const PIValueTree & getParameters() const { return parameters; }
|
||||||
|
void setParameters(const PIValueTree & vt);
|
||||||
|
|
||||||
|
virtual QString name() const = 0;
|
||||||
|
virtual bool requestTile(MapViewTypes::TileIndex index) = 0;
|
||||||
|
virtual QSize tileSize() = 0;
|
||||||
|
virtual QString cacheDir() const { return name(); }
|
||||||
|
virtual int maximumLevel() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initParameters(const PIValueTree & vt);
|
||||||
|
|
||||||
|
virtual void applyParameters() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void applyParametersIntenal();
|
||||||
|
PIValueTree parameters;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void tileReady(MapViewTypes::TileIndex index, QPixmap pm);
|
||||||
|
void parametersChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
79
libs/map/mapview_tile_provider_maptiler.cpp
Normal file
79
libs/map/mapview_tile_provider_maptiler.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include "mapview_tile_provider_maptiler.h"
|
||||||
|
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <piqt.h>
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileProvider_MapTiler::MapViewTileProvider_MapTiler() {
|
||||||
|
nam = new QNetworkAccessManager();
|
||||||
|
PIValueTree p;
|
||||||
|
p.addChild(PIValueTree("url", "https://api.maptiler.com/tiles"));
|
||||||
|
p.addChild(PIValueTree("key", ""));
|
||||||
|
p.addChild(PIValueTree("tileset", ""));
|
||||||
|
initParameters(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileProvider_MapTiler::~MapViewTileProvider_MapTiler() {
|
||||||
|
piDeleteSafety(nam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString MapViewTileProvider_MapTiler::name() const {
|
||||||
|
static QString ret = "MapTiler";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MapViewTileProvider_MapTiler::requestTile(MapViewTypes::TileIndex index) {
|
||||||
|
QNetworkRequest req(url + QString("/%1/%2/%3/%4.jpg?key=%5").arg(tileset).arg(index.z).arg(index.x).arg(index.y).arg(key));
|
||||||
|
req.setHeader(QNetworkRequest::UserAgentHeader, "Qt/5");
|
||||||
|
auto * r = nam->get(req);
|
||||||
|
if (!r) return false;
|
||||||
|
// qDebug() << "Reqst:" << index.z << index.x << index.y << req.url().toString();
|
||||||
|
connect(r, &QNetworkReply::finished, this, [this, r, index]() {
|
||||||
|
r->deleteLater();
|
||||||
|
QPixmap tim;
|
||||||
|
if (r->error() != QNetworkReply::NoError) {
|
||||||
|
if (r->error() == QNetworkReply::ContentAccessDenied) {
|
||||||
|
qDebug() << "Error:" << index.z << index.x << index.y << r->error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "Retry:" << index.z << index.x << index.y << r->error();
|
||||||
|
QTimer::singleShot(500, this, [this, index] { requestTile(index); });
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
QByteArray data = r->readAll();
|
||||||
|
if (!data.isEmpty()) {
|
||||||
|
tim.loadFromData(data, "jpg");
|
||||||
|
// qDebug() << "Ready:" << index.z << index.x << index.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tileReady(index, tim);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QSize MapViewTileProvider_MapTiler::tileSize() {
|
||||||
|
return {512, 512};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString MapViewTileProvider_MapTiler::cacheDir() const {
|
||||||
|
return name() + "/" + tileset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MapViewTileProvider_MapTiler::maximumLevel() const {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileProvider_MapTiler::applyParameters() {
|
||||||
|
url = PI2QString(getParameters().childValue("url").toString());
|
||||||
|
key = PI2QString(getParameters().childValue("key").toString());
|
||||||
|
tileset = PI2QString(getParameters().childValue("tileset").toString());
|
||||||
|
}
|
||||||
50
libs/map/mapview_tile_provider_maptiler.h
Normal file
50
libs/map/mapview_tile_provider_maptiler.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef mapview_tile_provider_maptiler_h
|
||||||
|
#define mapview_tile_provider_maptiler_h
|
||||||
|
|
||||||
|
#include "mapview_tile_provider_base.h"
|
||||||
|
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
|
||||||
|
class QAD_MAP_EXPORT MapViewTileProvider_MapTiler: public MapViewTileProviderBase {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MapViewTileProvider_MapTiler();
|
||||||
|
~MapViewTileProvider_MapTiler();
|
||||||
|
|
||||||
|
QString name() const override;
|
||||||
|
bool requestTile(MapViewTypes::TileIndex index) override;
|
||||||
|
QSize tileSize() override;
|
||||||
|
QString cacheDir() const override;
|
||||||
|
int maximumLevel() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void applyParameters() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNetworkAccessManager * nam = nullptr;
|
||||||
|
QString url, key, tileset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
61
libs/map/mapview_tile_provider_osm.cpp
Normal file
61
libs/map/mapview_tile_provider_osm.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include "mapview_tile_provider_osm.h"
|
||||||
|
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <piqt.h>
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileProvider_OSM::MapViewTileProvider_OSM() {
|
||||||
|
nam = new QNetworkAccessManager();
|
||||||
|
PIValueTree p;
|
||||||
|
p.addChild(PIValueTree("url", "http://tile.openstreetmap.org"));
|
||||||
|
initParameters(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MapViewTileProvider_OSM::~MapViewTileProvider_OSM() {
|
||||||
|
piDeleteSafety(nam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString MapViewTileProvider_OSM::name() const {
|
||||||
|
static QString ret = "OSM";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MapViewTileProvider_OSM::requestTile(MapViewTypes::TileIndex index) {
|
||||||
|
QNetworkRequest req(url + QString("/%1/%2/%3.png").arg(index.z).arg(index.x).arg(index.y));
|
||||||
|
req.setHeader(QNetworkRequest::UserAgentHeader, "Qt/5");
|
||||||
|
auto * r = nam->get(req);
|
||||||
|
if (!r) return false;
|
||||||
|
connect(r, &QNetworkReply::finished, this, [this, r, index]() {
|
||||||
|
r->deleteLater();
|
||||||
|
QPixmap tim;
|
||||||
|
if (r->error() != QNetworkReply::NoError) {
|
||||||
|
qDebug() << "Error:" << r->error();
|
||||||
|
} else {
|
||||||
|
QByteArray data = r->readAll();
|
||||||
|
if (!data.isEmpty()) {
|
||||||
|
tim.loadFromData(data, "png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit tileReady(index, tim);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QSize MapViewTileProvider_OSM::tileSize() {
|
||||||
|
return {256, 256};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MapViewTileProvider_OSM::maximumLevel() const {
|
||||||
|
return 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MapViewTileProvider_OSM::applyParameters() {
|
||||||
|
url = PI2QString(getParameters().childValue("url").toString());
|
||||||
|
}
|
||||||
49
libs/map/mapview_tile_provider_osm.h
Normal file
49
libs/map/mapview_tile_provider_osm.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef mapview_tile_provider_osm_h
|
||||||
|
#define mapview_tile_provider_osm_h
|
||||||
|
|
||||||
|
#include "mapview_tile_provider_base.h"
|
||||||
|
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
|
||||||
|
class QAD_MAP_EXPORT MapViewTileProvider_OSM: public MapViewTileProviderBase {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MapViewTileProvider_OSM();
|
||||||
|
~MapViewTileProvider_OSM();
|
||||||
|
|
||||||
|
QString name() const override;
|
||||||
|
bool requestTile(MapViewTypes::TileIndex index) override;
|
||||||
|
QSize tileSize() override;
|
||||||
|
int maximumLevel() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void applyParameters() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNetworkAccessManager * nam = nullptr;
|
||||||
|
QString url;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
QAD - Qt ADvanced
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osm_types_p.h"
|
#include "mapview_types.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
using namespace OSM;
|
using namespace MapViewTypes;
|
||||||
|
|
||||||
|
|
||||||
QString TileIndex ::hashName() const {
|
QString TileIndex ::hashName() const {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
QAD - Qt ADvanced
|
QAD - Qt ADvanced
|
||||||
|
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -17,14 +17,17 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef osm_types_h
|
#ifndef mapview_types_h
|
||||||
#define osm_types_h
|
#define mapview_types_h
|
||||||
|
|
||||||
|
#include "qad_map_export.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
namespace OSM {
|
namespace MapViewTypes {
|
||||||
|
|
||||||
struct TileIndex {
|
struct QAD_MAP_EXPORT TileIndex {
|
||||||
int z;
|
int z;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
@@ -33,7 +36,7 @@ struct TileIndex {
|
|||||||
QString cacheDir() const;
|
QString cacheDir() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TilePixmap {
|
struct QAD_MAP_EXPORT TilePixmap {
|
||||||
TileIndex index;
|
TileIndex index;
|
||||||
QPixmap pixmap;
|
QPixmap pixmap;
|
||||||
bool obsolete = false;
|
bool obsolete = false;
|
||||||
@@ -49,9 +52,9 @@ inline bool operator==(const TilePixmap & v0, const TilePixmap & v1) {
|
|||||||
return v0.index == v1.index;
|
return v0.index == v1.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OSM
|
} // namespace MapViewTypes
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(OSM::TileIndex);
|
Q_DECLARE_METATYPE(MapViewTypes::TileIndex);
|
||||||
Q_DECLARE_METATYPE(OSM::TilePixmap);
|
Q_DECLARE_METATYPE(MapViewTypes::TilePixmap);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
#include "mapview.h"
|
|
||||||
#include "osm_downloader_p.h"
|
|
||||||
#include "osm_tile_cache_p.h"
|
|
||||||
|
|
||||||
|
|
||||||
OSMDownloader::OSMDownloader(MapView * p): QThread() {
|
|
||||||
qRegisterMetaType<OSM::TileIndex>();
|
|
||||||
nam = new QNetworkAccessManager();
|
|
||||||
parent = p;
|
|
||||||
provider = "http://tile.openstreetmap.org";
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OSMDownloader::~OSMDownloader() {
|
|
||||||
requestInterruption();
|
|
||||||
cond.wakeAll();
|
|
||||||
wait();
|
|
||||||
delete nam;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool OSMDownloader::queueTile(OSM::TileIndex index, bool force) {
|
|
||||||
// auto hash = tile.hash();
|
|
||||||
bool ret = false;
|
|
||||||
cond_mutex.lock();
|
|
||||||
if ((!queue.contains(index) && !in_progress.contains(index.hash())) || force) {
|
|
||||||
queue.enqueue(index);
|
|
||||||
cond.wakeOne();
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
cond_mutex.unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OSMDownloader::queueTiles(QList<OSM::TileIndex> indeces) {
|
|
||||||
cond_mutex.lock();
|
|
||||||
queue << indeces;
|
|
||||||
cond.wakeOne();
|
|
||||||
cond_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OSMDownloader::clearQueue() {
|
|
||||||
cond_mutex.lock();
|
|
||||||
queue.clear();
|
|
||||||
cond_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OSMDownloader::requestTile(OSM::TileIndex index) {
|
|
||||||
QNetworkRequest req(provider + QString("/%1/%2/%3.png").arg(index.z).arg(index.x).arg(index.y));
|
|
||||||
req.setHeader(QNetworkRequest::UserAgentHeader, "Qt/5");
|
|
||||||
auto * r = nam->get(req);
|
|
||||||
if (!r) return;
|
|
||||||
connect(r, &QNetworkReply::finished, this, [this, r, index]() {
|
|
||||||
r->deleteLater();
|
|
||||||
if (r->error() != QNetworkReply::NoError) {
|
|
||||||
qDebug() << "Error:" << r->error();
|
|
||||||
} else {
|
|
||||||
QByteArray data = r->readAll();
|
|
||||||
if (!data.isEmpty()) {
|
|
||||||
QPixmap tim;
|
|
||||||
tim.loadFromData(data, "png");
|
|
||||||
if (!tim.isNull()) parent->cache->tileDownloaded(index, tim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cond_mutex.lock();
|
|
||||||
in_progress.remove(index.hash());
|
|
||||||
cond_mutex.unlock();
|
|
||||||
emit tileDone();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OSMDownloader::run() {
|
|
||||||
while (!isInterruptionRequested()) {
|
|
||||||
cond_mutex.lock();
|
|
||||||
if (queue.isEmpty())
|
|
||||||
cond.wait(&cond_mutex);
|
|
||||||
else {
|
|
||||||
auto t = queue.dequeue();
|
|
||||||
in_progress.insert(t.hash());
|
|
||||||
QMetaObject::invokeMethod(
|
|
||||||
parent,
|
|
||||||
[this, t]() { requestTile(t); },
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
cond_mutex.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "mapplugin.h"
|
#include "mapplugin.h"
|
||||||
|
|
||||||
#include "mapview.h"
|
#include "mapview.h"
|
||||||
|
#include "mapview_tile_provider_osm.h"
|
||||||
|
|
||||||
#include <QtCore/QtPlugin>
|
#include <QtCore/QtPlugin>
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ bool MapPlugin::isInitialized() const {
|
|||||||
|
|
||||||
QWidget * MapPlugin::createWidget(QWidget * parent) {
|
QWidget * MapPlugin::createWidget(QWidget * parent) {
|
||||||
MapView * w = new MapView(parent);
|
MapView * w = new MapView(parent);
|
||||||
|
w->setTileProvider(new MapViewTileProvider_OSM());
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -887,6 +887,32 @@ inline PICout operator<<(PICout s, const QColor & v) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PICout operator<<(PICout s, const QVector2D & v) {
|
||||||
|
s << PIMathVectorT2d({v[0], v[1]});
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PICout operator<<(PICout s, const QVector3D & v) {
|
||||||
|
s << PIMathVectorT3d({v[0], v[1], v[2]});
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PICout operator<<(PICout s, const QVector4D & v) {
|
||||||
|
s << PIMathVectorT4d({v[0], v[1], v[2], v[3]});
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int N, int M, typename T>
|
||||||
|
inline PICout operator<<(PICout s, const QGenericMatrix<N, M, T> & v) {
|
||||||
|
s << Q2PIMathMatrixT(v);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PICout operator<<(PICout s, const QMatrix4x4 & v) {
|
||||||
|
s << Q2PIMathMatrixT(v);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PIQT_HAS_GEOPOSITION
|
#ifdef PIQT_HAS_GEOPOSITION
|
||||||
inline PICout operator<<(PICout s, const QGeoCoordinate & v) {
|
inline PICout operator<<(PICout s, const QGeoCoordinate & v) {
|
||||||
s << Q2PIGeoPosition(v);
|
s << Q2PIGeoPosition(v);
|
||||||
|
|||||||
@@ -31,15 +31,16 @@
|
|||||||
template<typename Index = int>
|
template<typename Index = int>
|
||||||
class QAD_UTILS_EXPORT IndexedTimer {
|
class QAD_UTILS_EXPORT IndexedTimer {
|
||||||
public:
|
public:
|
||||||
~IndexedTimer() {
|
~IndexedTimer() { stopAllIndexedTimers(); }
|
||||||
for (auto & i: timers)
|
|
||||||
i.destroy();
|
|
||||||
timers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setIndexedTimerType(Index index, Qt::TimerType type) { timers[index].type = type; }
|
void setIndexedTimerType(Index index, Qt::TimerType type) { timers[index].type = type; }
|
||||||
void setIndexedTimerSingleShot(Index index, bool yes) { timers[index].single_shot = yes; }
|
void setIndexedTimerSingleShot(Index index, bool yes) { timers[index].single_shot = yes; }
|
||||||
void bindIndexedTimer(Index index, std::function<void()> func) { timers[index].func = func; }
|
void bindIndexedTimer(Index index, std::function<void()> func) { timers[index].func = func; }
|
||||||
|
void stopAllIndexedTimers() {
|
||||||
|
for (auto & i: timers)
|
||||||
|
i.destroy();
|
||||||
|
timers.clear();
|
||||||
|
}
|
||||||
void stopIndexedTimer(Index index) {
|
void stopIndexedTimer(Index index) {
|
||||||
auto & t(timers[index]);
|
auto & t(timers[index]);
|
||||||
if (!t.isValid()) return;
|
if (!t.isValid()) return;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
qad_library(sql "Gui;Widgets;Sql" "qad_utils")
|
qad_library(sql "Sql" "")
|
||||||
|
|||||||
@@ -120,8 +120,10 @@ void VirtualKeyboard::adjust() {
|
|||||||
for (auto p: pages)
|
for (auto p: pages)
|
||||||
cols = piMaxi(cols, p->buttonColumns());
|
cols = piMaxi(cols, p->buttonColumns());
|
||||||
if (cols < 1) return;
|
if (cols < 1) return;
|
||||||
int spacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, nullptr, this);
|
int spacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, nullptr, this);
|
||||||
int pixel_width = width() - spacing * (cols - 1) - ui->verticalLayout->margin() * 2;
|
int m[4] = {0, 0, 0, 0};
|
||||||
|
ui->verticalLayout->getContentsMargins(&m[0], &m[1], &m[2], &m[3]);
|
||||||
|
int pixel_width = width() - spacing * (cols - 1) - m[0] * 2;
|
||||||
int bw = piMaxi(2, pixel_width / cols);
|
int bw = piMaxi(2, pixel_width / cols);
|
||||||
ui->stackedPages->setStyleSheet(QString("font:%1px").arg(bw / 2));
|
ui->stackedPages->setStyleSheet(QString("font:%1px").arg(bw / 2));
|
||||||
for (auto p: pages)
|
for (auto p: pages)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ QString ImageViewPlugin::whatsThis() const {
|
|||||||
|
|
||||||
|
|
||||||
bool ImageViewPlugin::isContainer() const {
|
bool ImageViewPlugin::isContainer() const {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
|
|
||||||
QCodeEditCompleter::QCodeEditCompleter(QWidget * parent): QTreeWidget(parent) {
|
QCodeEditCompleter::QCodeEditCompleter(QWidget * parent): QTreeWidget(parent) {
|
||||||
@@ -79,8 +80,13 @@ void QCodeEditCompleter::invoke(QPoint global_pos) {
|
|||||||
setCurrentItem(topLevelItem(1));
|
setCurrentItem(topLevelItem(1));
|
||||||
if (isHidden()) move(global_pos);
|
if (isHidden()) move(global_pos);
|
||||||
if (topLevelItemCount() > 0) {
|
if (topLevelItemCount() > 0) {
|
||||||
|
const auto screen = qApp->screenAt(global_pos);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
adjust();
|
adjust();
|
||||||
|
if (global_pos.y() + height() > screen->availableSize().height()) {
|
||||||
|
global_pos.setY(global_pos.y() -height() - fontHeight(this));
|
||||||
|
}
|
||||||
|
move(global_pos);
|
||||||
} else {
|
} else {
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ void SessionManager::save() {
|
|||||||
sr.setValue(buttons[i].first, buttons[i].second->isChecked(), false);
|
sr.setValue(buttons[i].first, buttons[i].second->isChecked(), false);
|
||||||
for (int i = 0; i < stacks.size(); ++i)
|
for (int i = 0; i < stacks.size(); ++i)
|
||||||
sr.setValue(stacks[i].first, stacks[i].second->currentIndex(), false);
|
sr.setValue(stacks[i].first, stacks[i].second->currentIndex(), false);
|
||||||
|
for (int i = 0; i < sliders.size(); ++i)
|
||||||
|
sr.setValue(sliders[i].first, sliders[i].second->value(), false);
|
||||||
for (int i = 0; i < actions.size(); ++i)
|
for (int i = 0; i < actions.size(); ++i)
|
||||||
sr.setValue(actions[i].first, actions[i].second->isChecked(), false);
|
sr.setValue(actions[i].first, actions[i].second->isChecked(), false);
|
||||||
for (int i = 0; i < stringlists.size(); ++i)
|
for (int i = 0; i < stringlists.size(); ++i)
|
||||||
@@ -221,6 +223,8 @@ void SessionManager::load(bool onlyMainwindow) {
|
|||||||
for (int i = 0; i < stacks.size(); ++i)
|
for (int i = 0; i < stacks.size(); ++i)
|
||||||
stacks[i].second->setCurrentIndex(
|
stacks[i].second->setCurrentIndex(
|
||||||
qMin<int>(sr.getValue(stacks[i].first, stacks[i].second->currentIndex()).toInt(), stacks[i].second->count()));
|
qMin<int>(sr.getValue(stacks[i].first, stacks[i].second->currentIndex()).toInt(), stacks[i].second->count()));
|
||||||
|
for (int i = 0; i < sliders.size(); ++i)
|
||||||
|
sliders[i].second->setValue(sr.getValue(sliders[i].first, sliders[i].second->value()).toInt());
|
||||||
for (int i = 0; i < actions.size(); ++i)
|
for (int i = 0; i < actions.size(); ++i)
|
||||||
actions[i].second->setChecked(sr.getValue(actions[i].first, actions[i].second->isChecked()).toBool());
|
actions[i].second->setChecked(sr.getValue(actions[i].first, actions[i].second->isChecked()).toBool());
|
||||||
for (int i = 0; i < stringlists.size(); ++i)
|
for (int i = 0; i < stringlists.size(); ++i)
|
||||||
@@ -267,6 +271,7 @@ void SessionManager::clear(bool with_filename) {
|
|||||||
tabs.clear();
|
tabs.clear();
|
||||||
buttons.clear();
|
buttons.clear();
|
||||||
stacks.clear();
|
stacks.clear();
|
||||||
|
sliders.clear();
|
||||||
actions.clear();
|
actions.clear();
|
||||||
stringlists.clear();
|
stringlists.clear();
|
||||||
strings.clear();
|
strings.clear();
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ public:
|
|||||||
void addEntry(QAction * e) { addEntry(e->objectName(), e); }
|
void addEntry(QAction * e) { addEntry(e->objectName(), e); }
|
||||||
void addEntry(QAbstractButton * e) { addEntry(e->objectName(), e); }
|
void addEntry(QAbstractButton * e) { addEntry(e->objectName(), e); }
|
||||||
void addEntry(QStackedWidget * e) { addEntry(e->objectName(), e); }
|
void addEntry(QStackedWidget * e) { addEntry(e->objectName(), e); }
|
||||||
|
void addEntry(QSlider * e) { addEntry(e->objectName(), e); }
|
||||||
void addMainWidget(QWidget * e) { addMainWidget(e->objectName(), e); }
|
void addMainWidget(QWidget * e) { addMainWidget(e->objectName(), e); }
|
||||||
void removeMainWidget(QWidget * e);
|
void removeMainWidget(QWidget * e);
|
||||||
|
|
||||||
@@ -81,6 +82,7 @@ public:
|
|||||||
void addEntry(const QString & name, QGroupBox * e) { groups.push_back(QPair<QString, QGroupBox *>(name, e)); }
|
void addEntry(const QString & name, QGroupBox * e) { groups.push_back(QPair<QString, QGroupBox *>(name, e)); }
|
||||||
void addEntry(const QString & name, QAbstractButton * e) { buttons.push_back(QPair<QString, QAbstractButton *>(name, e)); }
|
void addEntry(const QString & name, QAbstractButton * e) { buttons.push_back(QPair<QString, QAbstractButton *>(name, e)); }
|
||||||
void addEntry(const QString & name, QStackedWidget * e) { stacks.push_back(QPair<QString, QStackedWidget *>(name, e)); }
|
void addEntry(const QString & name, QStackedWidget * e) { stacks.push_back(QPair<QString, QStackedWidget *>(name, e)); }
|
||||||
|
void addEntry(const QString & name, QSlider * e) { sliders.push_back(QPair<QString, QSlider *>(name, e)); }
|
||||||
void addEntry(const QString & name, QAction * e) { actions.push_back(QPair<QString, QAction *>(name, e)); }
|
void addEntry(const QString & name, QAction * e) { actions.push_back(QPair<QString, QAction *>(name, e)); }
|
||||||
void addEntry(const QString & name, QStringList * e) { stringlists.push_back(QPair<QString, QStringList *>(name, e)); }
|
void addEntry(const QString & name, QStringList * e) { stringlists.push_back(QPair<QString, QStringList *>(name, e)); }
|
||||||
void addEntry(const QString & name, QString * e) { strings.push_back(QPair<QString, QString *>(name, e)); }
|
void addEntry(const QString & name, QString * e) { strings.push_back(QPair<QString, QString *>(name, e)); }
|
||||||
@@ -106,6 +108,7 @@ private:
|
|||||||
QVector<QPair<QString, QGroupBox *>> groups;
|
QVector<QPair<QString, QGroupBox *>> groups;
|
||||||
QVector<QPair<QString, QAbstractButton *>> buttons;
|
QVector<QPair<QString, QAbstractButton *>> buttons;
|
||||||
QVector<QPair<QString, QStackedWidget *>> stacks;
|
QVector<QPair<QString, QStackedWidget *>> stacks;
|
||||||
|
QVector<QPair<QString, QSlider *>> sliders;
|
||||||
QVector<QPair<QString, QAction *>> actions;
|
QVector<QPair<QString, QAction *>> actions;
|
||||||
QVector<QPair<QString, QStringList *>> stringlists;
|
QVector<QPair<QString, QStringList *>> stringlists;
|
||||||
QVector<QPair<QString, QString *>> strings;
|
QVector<QPair<QString, QString *>> strings;
|
||||||
|
|||||||
Reference in New Issue
Block a user