Skip to content

Commit

Permalink
Added sample for performance tuning
Browse files Browse the repository at this point in the history
  • Loading branch information
AmonRaNet committed Jan 3, 2024
1 parent 3402554 commit 9274a50
Show file tree
Hide file tree
Showing 11 changed files with 485 additions and 22 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_subdirectory(samples/layers)
add_subdirectory(samples/fun)
add_subdirectory(samples/10000)
add_subdirectory(samples/debug)
add_subdirectory(samples/performance)
add_subdirectory(samples/custom-tiles)
add_subdirectory(samples/moving-objects)
add_subdirectory(samples/mouse-actions)
Expand Down
8 changes: 8 additions & 0 deletions HOWTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ Special flags for draw items in [flags](samples/flags):

Map with several object-layers in [layers](samples/layers)

### Performance

Background map has biggest impact to performance because it covers whole map area all the time.
QGVLayerTiles always calculates needed set of tiles for current camera state and performance parameters
will adjust algorithm.

Example for performance tuning can be found in [performance](samples/performance)

### Debug and logging

How to catch debug info in qDebug or visually on map [debug](samples/debug)
Expand Down
2 changes: 2 additions & 0 deletions QGeoView.pro
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SUBDIRS = \
samples/fun \
samples/10000 \
samples/debug \
samples/performance \
samples/custom-tiles \
samples/moving-objects \
samples/mouse-actions \
Expand All @@ -24,6 +25,7 @@ samples.layers.depends = lib samples.shared
samples.fun.depends = lib samples.shared
samples.10000.depends = lib samples.shared
samples.debug.depends = lib samples.shared
samples.performance.depends = lib samples.shared
samples.custom-tiles.depends = lib samples.shared
samples.moving-objects.depends = lib samples.shared
samples.mouse-actions.depends = lib samples.shared
Expand Down
19 changes: 19 additions & 0 deletions lib/include/QGeoView/QGVLayerTiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ class QGV_LIB_DECL QGVLayerTiles : public QGVLayer
public:
QGVLayerTiles();

void setTilesMarginWithZoomChange(size_t value);
void setTilesMarginNoZoomChange(size_t value);
void setAnimationUpdateDelayMs(size_t value);
void setVisibleZoomLayersBelowCurrent(size_t value);
void setVisibleZoomLayersAboveCurrent(size_t value);
void setCameraUpdatesDuringAnimation(bool value);

protected:
void onProjection(QGVMap* geoMap) override;
void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override;
Expand All @@ -46,6 +53,7 @@ class QGV_LIB_DECL QGVLayerTiles : public QGVLayer
void processCamera();
void removeAllAbove(const QGV::GeoTilePos& tilePos);
void removeWhenCovered(const QGV::GeoTilePos& tilePos);
void removeForPerfomance(const QGV::GeoTilePos& tilePos);
void addTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj);
void removeTile(const QGV::GeoTilePos& tilePos);
bool isTileExists(const QGV::GeoTilePos& tilePos) const;
Expand All @@ -56,5 +64,16 @@ class QGV_LIB_DECL QGVLayerTiles : public QGVLayer
int mCurZoom;
QRect mCurRect;
QMap<int, QMap<QGV::GeoTilePos, QGVDrawItem*>> mIndex;

QElapsedTimer mLastAnimation;

struct
{
size_t TilesMarginWithZoomChange = 1;
size_t TilesMarginNoZoomChange = 3;
size_t AnimationUpdateDelayMs = 200;
bool CameraUpdatesDuringAnimation = true;
size_t VisibleZoomLayersBelowCurrent = 10;
size_t VisibleZoomLayersAboveCurrent = 10;
} mPerfomanceProfile;
};
86 changes: 66 additions & 20 deletions lib/src/QGVLayerTiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,48 @@

#include <QtMath>

namespace {
int minMargin = 1;
int maxMargin = 3;
int msAnimationUpdateDelay = 250;
}

QGVLayerTiles::QGVLayerTiles()
{
mCurZoom = -1;
sendToBack();
}

void QGVLayerTiles::setTilesMarginWithZoomChange(size_t value)
{
mPerfomanceProfile.TilesMarginWithZoomChange = value;
qgvDebug() << "TilesMarginWithZoomChange changed to" << value;
}

void QGVLayerTiles::setTilesMarginNoZoomChange(size_t value)
{
mPerfomanceProfile.TilesMarginNoZoomChange = value;
qgvDebug() << "TilesMarginNoZoomChange changed to" << value;
}

void QGVLayerTiles::setAnimationUpdateDelayMs(size_t value)
{
mPerfomanceProfile.AnimationUpdateDelayMs = value;
qgvDebug() << "AnimationUpdateDelayMs changed to" << value;
}

void QGVLayerTiles::setVisibleZoomLayersBelowCurrent(size_t value)
{
mPerfomanceProfile.VisibleZoomLayersBelowCurrent = value;
qgvDebug() << "VisibleZoomLayersBelowCurrent changed to" << value;
}

void QGVLayerTiles::setVisibleZoomLayersAboveCurrent(size_t value)
{
mPerfomanceProfile.VisibleZoomLayersAboveCurrent = value;
qgvDebug() << "VisibleZoomLayersAboveCurrent changed to" << value;
}

void QGVLayerTiles::setCameraUpdatesDuringAnimation(bool value)
{
mPerfomanceProfile.CameraUpdatesDuringAnimation = value;
qgvDebug() << "CameraUpdatesDuringAnimation changed to" << value;
}

void QGVLayerTiles::onProjection(QGVMap* geoMap)
{
QGVLayer::onProjection(geoMap);
Expand All @@ -41,22 +71,27 @@ void QGVLayerTiles::onProjection(QGVMap* geoMap)
void QGVLayerTiles::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState)
{
QGVLayer::onCamera(oldState, newState);

if (oldState == newState) {
return;
}

bool needUpdate = true;

if (newState.animation()) {
if (!mLastAnimation.isValid()) {
if (!mPerfomanceProfile.CameraUpdatesDuringAnimation) {
needUpdate = false;
} else if (!mLastAnimation.isValid()) {
mLastAnimation.start();
} else if (mLastAnimation.elapsed() < msAnimationUpdateDelay) {
} else if (mLastAnimation.elapsed() < static_cast<qint64>(mPerfomanceProfile.AnimationUpdateDelayMs)) {
needUpdate = false;
} else {
mLastAnimation.restart();
}
} else {
mLastAnimation.invalidate();
}

if (needUpdate) {
processCamera();
}
Expand Down Expand Up @@ -123,7 +158,8 @@ void QGVLayerTiles::processCamera()
const bool zoomChanged = (mCurZoom != newZoom);
mCurZoom = newZoom;

const int margin = (zoomChanged) ? minMargin : maxMargin;
const int margin =
(zoomChanged) ? mPerfomanceProfile.TilesMarginWithZoomChange : mPerfomanceProfile.TilesMarginNoZoomChange;
const int sizePerZoom = static_cast<int>(qPow(2, mCurZoom));
const QRect maxRect = QRect(QPoint(0, 0), QPoint(sizePerZoom, sizePerZoom));
const QPoint topLeft = QGV::GeoTilePos::geoToTilePos(mCurZoom, areaGeoRect.topLeft()).pos();
Expand All @@ -147,17 +183,15 @@ void QGVLayerTiles::processCamera()
for (const QGV::GeoTilePos& current : existingTiles(zoom)) {
removeAllAbove(current);
}
continue;
}
for (const QGV::GeoTilePos& nonCurrent : existingTiles(zoom)) {
if (!isTileFinished(nonCurrent)) {
qgvDebug() << "cancel non-finished" << nonCurrent;
removeTile(nonCurrent);
continue;
}
if (zoom < mCurZoom) {
removeWhenCovered(nonCurrent);
continue;
} else {
for (const QGV::GeoTilePos& nonCurrent : existingTiles(zoom)) {
if (!isTileFinished(nonCurrent)) {
qgvDebug() << "cancel non-finished" << nonCurrent;
removeTile(nonCurrent);
} else if (zoom < mCurZoom) {
removeWhenCovered(nonCurrent);
}
removeForPerfomance(nonCurrent);
}
}
}
Expand All @@ -184,6 +218,7 @@ void QGVLayerTiles::processCamera()
missing.insert(radius, tilePos);
}
}

for (const QGV::GeoTilePos& tilePos : missing) {
addTile(tilePos, nullptr);
}
Expand Down Expand Up @@ -229,6 +264,17 @@ void QGVLayerTiles::removeWhenCovered(const QGV::GeoTilePos& tilePos)
}
}

void QGVLayerTiles::removeForPerfomance(const QGV::GeoTilePos& tilePos)
{
const auto minZoom = mCurZoom - static_cast<int>(mPerfomanceProfile.VisibleZoomLayersBelowCurrent);
const auto maxZoom = mCurZoom + static_cast<int>(mPerfomanceProfile.VisibleZoomLayersAboveCurrent);

if (tilePos.zoom() < minZoom || tilePos.zoom() > maxZoom) {
qgvDebug() << "delete because of performance request" << minZoom << maxZoom;
removeTile(tilePos);
}
}

void QGVLayerTiles::addTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj)
{
if (isTileFinished(tilePos)) {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/QGVMapQGView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@

namespace {
int wheelAreaMargin = 10;
double wheelExponentDown = qPow(2, 1.0 / 5.0);
double wheelExponentUp = qPow(2, 1.0 / 2.0);
double wheelExponentDown = qPow(2, 1.0 / 2.0);
double wheelExponentUp = qPow(2, 1.0 / 1.5);
}

QGVMapQGView::QGVMapQGView(QGVMap* geoMap)
Expand Down
37 changes: 37 additions & 0 deletions samples/performance/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
set(CMAKE_CXX_STANDARD 11)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Set the QT version
find_package(Qt6 COMPONENTS Core QUIET)
if (NOT Qt6_FOUND)
set(QT_VERSION 5 CACHE STRING "Qt version for QGeoView")
else()
set(QT_VERSION 6 CACHE STRING "Qt version for QGeoView")
endif()

find_package(Qt${QT_VERSION} REQUIRED COMPONENTS
Core
Gui
Widgets
Network
)

add_executable(qgeoview-samples-performance
main.cpp
mainwindow.h
mainwindow.cpp
)

target_link_libraries(qgeoview-samples-performance
PRIVATE
Qt${QT_VERSION}::Core
Qt${QT_VERSION}::Network
Qt${QT_VERSION}::Gui
Qt${QT_VERSION}::Widgets
QGeoView
qgeoview-samples-shared
)
37 changes: 37 additions & 0 deletions samples/performance/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/***************************************************************************
* QGeoView is a Qt / C ++ widget for visualizing geographic data.
* Copyright (C) 2018-2023 Andrey Yaroshenko.
*
* 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 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 https://www.gnu.org/licenses.
****************************************************************************/

#include <QApplication>
#include <QCommandLineParser>

#include "mainwindow.h"

int main(int argc, char* argv[])
{
QApplication app(argc, argv);
app.setApplicationName("QGeoView Samples");

QCommandLineParser parser;
parser.addHelpOption();
parser.addVersionOption();
parser.process(app);

MainWindow window;
window.show();
return app.exec();
}
Loading

0 comments on commit 9274a50

Please sign in to comment.