From 3dfb906f3891a4c4114bdbf0b7c68173a55c9d45 Mon Sep 17 00:00:00 2001 From: AmonRaNet Date: Sun, 26 Apr 2020 19:30:19 +0200 Subject: [PATCH] Add git pre-commit hooks - Added git pre-commit hooks - Fixed mixed line-endings (final: \n) - Fixed clang-format errors - Updated legacy header --- .gitignore | 86 +- .pre-commit-config.yaml | 28 + Doxyfile | 2 +- QGeoView.pro | 1 - README.md | 1 + ReleaseNotes.md | 8 + _config.yml | 2 +- demo/demoitem.cpp | 160 +-- demo/demoitem.h | 120 +- demo/main.cpp | 74 +- demo/mainwindow.cpp | 359 +++--- demo/mainwindow.h | 118 +- demo/mainwindow.ui | 184 +-- demo/samples/background.cpp | 201 ++- demo/samples/background.h | 88 +- demo/samples/customtiles.cpp | 181 ++- demo/samples/customtiles.h | 86 +- demo/samples/ellipse.cpp | 112 +- demo/samples/ellipse.h | 80 +- demo/samples/flags.cpp | 219 ++-- demo/samples/flags.h | 78 +- demo/samples/items.cpp | 193 +-- demo/samples/items.h | 82 +- demo/samples/mouse.cpp | 207 ++-- demo/samples/mouse.h | 90 +- demo/samples/mytile.cpp | 137 ++- demo/samples/mytile.h | 86 +- demo/samples/mytiles.cpp | 122 +- demo/samples/mytiles.h | 82 +- demo/samples/placemark.cpp | 84 +- demo/samples/placemark.h | 66 +- demo/samples/rectangle.cpp | 190 +-- demo/samples/rectangle.h | 96 +- demo/samples/utilities.cpp | 379 +++--- demo/samples/utilities.h | 116 +- demo/samples/waveanimation.cpp | 166 +-- demo/samples/waveanimation.h | 86 +- demo/samples/widgets.cpp | 165 ++- demo/samples/widgets.h | 76 +- demo/selectordialog.cpp | 198 +-- demo/selectordialog.h | 114 +- lib/include/QGeoView/QGVCamera.h | 286 ++--- lib/include/QGeoView/QGVDrawItem.h | 126 +- lib/include/QGeoView/QGVGlobal.h | 398 +++--- lib/include/QGeoView/QGVImage.h | 134 +- lib/include/QGeoView/QGVItem.h | 176 +-- lib/include/QGeoView/QGVLayer.h | 78 +- lib/include/QGeoView/QGVLayerBing.h | 96 +- lib/include/QGeoView/QGVLayerGoogle.h | 96 +- lib/include/QGeoView/QGVLayerOSM.h | 82 +- lib/include/QGeoView/QGVLayerTiles.h | 120 +- lib/include/QGeoView/QGVLayerTilesOnline.h | 90 +- lib/include/QGeoView/QGVMap.h | 216 ++-- lib/include/QGeoView/QGVMapQGItem.h | 90 +- lib/include/QGeoView/QGVMapQGView.h | 200 +-- lib/include/QGeoView/QGVMapRubberBand.h | 104 +- lib/include/QGeoView/QGVProjection.h | 94 +- lib/include/QGeoView/QGVProjectionEPSG3857.h | 90 +- lib/include/QGeoView/QGVWidget.h | 124 +- lib/include/QGeoView/QGVWidgetCompass.h | 94 +- lib/include/QGeoView/QGVWidgetScale.h | 94 +- lib/include/QGeoView/QGVWidgetText.h | 78 +- lib/include/QGeoView/QGVWidgetZoom.h | 94 +- lib/src/QGVCamera.cpp | 745 ++++++------ lib/src/QGVDrawItem.cpp | 412 ++++--- lib/src/QGVGlobal.cpp | 1000 ++++++++------- lib/src/QGVImage.cpp | 310 ++--- lib/src/QGVItem.cpp | 585 +++++---- lib/src/QGVLayer.cpp | 78 +- lib/src/QGVLayerBing.cpp | 210 ++-- lib/src/QGVLayerGoogle.cpp | 220 ++-- lib/src/QGVLayerOSM.cpp | 148 +-- lib/src/QGVLayerTiles.cpp | 556 ++++----- lib/src/QGVLayerTilesOnline.cpp | 210 ++-- lib/src/QGVMap.cpp | 719 +++++------ lib/src/QGVMapQGItem.cpp | 204 ++-- lib/src/QGVMapQGView.cpp | 1078 ++++++++--------- lib/src/QGVMapRubberBand.cpp | 216 ++-- lib/src/QGVProjection.cpp | 81 +- lib/src/QGVProjectionEPSG3857.cpp | 180 +-- lib/src/QGVWidget.cpp | 280 +++-- lib/src/QGVWidgetCompass.cpp | 284 ++--- lib/src/QGVWidgetScale.cpp | 330 ++--- lib/src/QGVWidgetText.cpp | 98 +- lib/src/QGVWidgetZoom.cpp | 224 ++-- scripts/add_header.py | 66 +- scripts/clang_format.py | 32 - .../{qgv_lgpl_head.txt => legacy_head.txt} | 34 +- 88 files changed, 8086 insertions(+), 8097 deletions(-) create mode 100644 .pre-commit-config.yaml mode change 100644 => 100755 scripts/add_header.py delete mode 100644 scripts/clang_format.py rename scripts/{qgv_lgpl_head.txt => legacy_head.txt} (93%) diff --git a/.gitignore b/.gitignore index 160daa6..5f4869b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,43 @@ -# C++ objects and libs -*.slo -*.lo -*.o -*.a -*.la -*.lai -*.so -*.dll -*.dylib - -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp -/.qmake.cache -/.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build* - -# Qt unit tests -target_wrapper.* - -# QtCreator -*.autosave - -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* - -# QtCreator CMake -CMakeLists.txt.user* +# C++ objects and libs +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.dll +*.dylib + +# Qt-es +object_script.*.Release +object_script.*.Debug +*_plugin_import.cpp +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +*.qmlc +*.jsc +Makefile* +*build* + +# Qt unit tests +target_wrapper.* + +# QtCreator +*.autosave + +# QtCreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCreator CMake +CMakeLists.txt.user* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..adbd156 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ +repos: + - repo: local + hooks: + - id: legacy-headers + name: Update legacy headers + entry: scripts/add_header.py + args: [--apply,.,scripts/legacy_head.txt] + language: script + always_run: true + pass_filenames: false + stages: [commit] + + - repo: https://github.com/pocc/pre-commit-hooks + rev: python + hooks: + - id: clang-format + args: [-i] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.5.0 + hooks: + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + - id: end-of-file-fixer + - id: mixed-line-ending + args: [--fix=lf] + - id: check-added-large-files + args: [--maxkb=100] diff --git a/Doxyfile b/Doxyfile index fc50ea9..f4ccf25 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,5 +1,5 @@ PROJECT_NAME = "QGeoView" -PROJECT_NUMBER = 1.0 +PROJECT_NUMBER = 1.0 PROJECT_BRIEF = "QGeoView documentation" ALWAYS_DETAILED_SEC = YES diff --git a/QGeoView.pro b/QGeoView.pro index dded2de..619e259 100644 --- a/QGeoView.pro +++ b/QGeoView.pro @@ -1,4 +1,3 @@ TEMPLATE = subdirs SUBDIRS = lib \ demo - diff --git a/README.md b/README.md index 5a27a67..8a694cc 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ What things you need: * Qt 5.6 or higher (core, gui, widgets, network) * qmake or cmake * doxygen (optional) + * pre-commits (optional) https://pre-commit.com/ ### Installing diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 311ff69..e4fff9d 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,13 @@ # Release Notes +## v1.0.2 - 26.04.2020 + +Maintenance work: + - Added git pre-commit hooks + - Fixed mixed line-endings (final: \n) + - Fixed clang-format errors + - Updated legacy header + ## v1.0.1 - 30.12.2019 Relicense to LGPL 3.0 instead of GPL 3.0 diff --git a/_config.yml b/_config.yml index c419263..277f1f2 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-cayman \ No newline at end of file +theme: jekyll-theme-cayman diff --git a/demo/demoitem.cpp b/demo/demoitem.cpp index ef012c1..5fd0654 100644 --- a/demo/demoitem.cpp +++ b/demo/demoitem.cpp @@ -1,80 +1,80 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "demoitem.h" - -DemoItem::DemoItem(QGVMap* geoMap, SelectorDialog::Type type, QObject* parent) - : QObject(parent) - , mGeoMap(geoMap) -{ - mSelectorDialog.reset(new SelectorDialog(type)); -} - -QGVMap* DemoItem::geoMap() const -{ - return mGeoMap; -} - -SelectorDialog* DemoItem::selector() const -{ - return mSelectorDialog.data(); -} - -void DemoItem::init() -{ - onInit(); - Q_EMIT ready(this); -} -void DemoItem::start() -{ - onStart(); - Q_EMIT started(this); -} -void DemoItem::end() -{ - onEnd(); - Q_EMIT ended(this); -} - -QGV::GeoPos DemoItem::randPos(const QGV::GeoRect& targetArea) -{ - const double latRange = targetArea.latTop() - targetArea.latBottom(); - const double lonRange = targetArea.lonRigth() - targetArea.lonLeft(); - static const int range = 1000; - return { targetArea.latBottom() + latRange * (qrand() % range) / range, - targetArea.lonLeft() + lonRange * (qrand() % range) / range }; -} - -QGV::GeoRect DemoItem::randRect(const QGV::GeoRect& targetArea, const QSizeF& size) -{ - const auto baseGeo = randPos(targetArea); - const auto base = geoMap()->getProjection()->geoToProj(baseGeo); - return geoMap()->getProjection()->projToGeo({ base, base + QPointF(size.width(), size.height()) }); -} - -QGV::GeoRect DemoItem::randRect(const QGV::GeoRect& targetArea, int baseSize) -{ - const auto size = randSize(baseSize); - return randRect(targetArea, size); -} - -QSizeF DemoItem::randSize(int baseSize) -{ - const int range = -baseSize / 2; - return QSize(baseSize + (qrand() % range), baseSize + (qrand() % range)); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "demoitem.h" + +DemoItem::DemoItem(QGVMap* geoMap, SelectorDialog::Type type, QObject* parent) + : QObject(parent) + , mGeoMap(geoMap) +{ + mSelectorDialog.reset(new SelectorDialog(type)); +} + +QGVMap* DemoItem::geoMap() const +{ + return mGeoMap; +} + +SelectorDialog* DemoItem::selector() const +{ + return mSelectorDialog.data(); +} + +void DemoItem::init() +{ + onInit(); + Q_EMIT ready(this); +} +void DemoItem::start() +{ + onStart(); + Q_EMIT started(this); +} +void DemoItem::end() +{ + onEnd(); + Q_EMIT ended(this); +} + +QGV::GeoPos DemoItem::randPos(const QGV::GeoRect& targetArea) +{ + const double latRange = targetArea.latTop() - targetArea.latBottom(); + const double lonRange = targetArea.lonRigth() - targetArea.lonLeft(); + static const int range = 1000; + return { targetArea.latBottom() + latRange * (qrand() % range) / range, + targetArea.lonLeft() + lonRange * (qrand() % range) / range }; +} + +QGV::GeoRect DemoItem::randRect(const QGV::GeoRect& targetArea, const QSizeF& size) +{ + const auto baseGeo = randPos(targetArea); + const auto base = geoMap()->getProjection()->geoToProj(baseGeo); + return geoMap()->getProjection()->projToGeo({ base, base + QPointF(size.width(), size.height()) }); +} + +QGV::GeoRect DemoItem::randRect(const QGV::GeoRect& targetArea, int baseSize) +{ + const auto size = randSize(baseSize); + return randRect(targetArea, size); +} + +QSizeF DemoItem::randSize(int baseSize) +{ + const int range = -baseSize / 2; + return QSize(baseSize + (qrand() % range), baseSize + (qrand() % range)); +} diff --git a/demo/demoitem.h b/demo/demoitem.h index 84e40bf..26a8f19 100644 --- a/demo/demoitem.h +++ b/demo/demoitem.h @@ -1,60 +1,60 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include -#include - -#include "selectordialog.h" - -class DemoItem : public QObject -{ - Q_OBJECT -public: - explicit DemoItem(QGVMap* geoMap, SelectorDialog::Type type, QObject* parent = 0); - virtual ~DemoItem() = default; - - QGVMap* geoMap() const; - SelectorDialog* selector() const; - - virtual QString label() const = 0; - virtual QString comment() const = 0; - void init(); - void start(); - void end(); - - QGV::GeoPos randPos(const QGV::GeoRect& targetArea); - QGV::GeoRect randRect(const QGV::GeoRect& targetArea, const QSizeF& size); - QGV::GeoRect randRect(const QGV::GeoRect& targetArea, int baseSize); - QSizeF randSize(int baseSize); - -protected: - virtual void onInit() = 0; - virtual void onStart() = 0; - virtual void onEnd() = 0; - -Q_SIGNALS: - void ready(DemoItem* item); - void started(DemoItem* item); - void ended(DemoItem* item); - -private: - QGVMap* mGeoMap; - QScopedPointer mSelectorDialog; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include +#include + +#include "selectordialog.h" + +class DemoItem : public QObject +{ + Q_OBJECT +public: + explicit DemoItem(QGVMap* geoMap, SelectorDialog::Type type, QObject* parent = 0); + virtual ~DemoItem() = default; + + QGVMap* geoMap() const; + SelectorDialog* selector() const; + + virtual QString label() const = 0; + virtual QString comment() const = 0; + void init(); + void start(); + void end(); + + QGV::GeoPos randPos(const QGV::GeoRect& targetArea); + QGV::GeoRect randRect(const QGV::GeoRect& targetArea, const QSizeF& size); + QGV::GeoRect randRect(const QGV::GeoRect& targetArea, int baseSize); + QSizeF randSize(int baseSize); + +protected: + virtual void onInit() = 0; + virtual void onStart() = 0; + virtual void onEnd() = 0; + +Q_SIGNALS: + void ready(DemoItem* item); + void started(DemoItem* item); + void ended(DemoItem* item); + +private: + QGVMap* mGeoMap; + QScopedPointer mSelectorDialog; +}; diff --git a/demo/main.cpp b/demo/main.cpp index 79c72a8..9573e89 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -1,37 +1,37 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 -#include - -#include "mainwindow.h" - -int main(int argc, char* argv[]) -{ - QApplication app(argc, argv); - app.setApplicationName("QGeoView Demo"); - - QCommandLineParser parser; - parser.addHelpOption(); - parser.addVersionOption(); - parser.process(app); - - MainWindow window; - window.show(); - return app.exec(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 +#include + +#include "mainwindow.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + app.setApplicationName("QGeoView Demo"); + + QCommandLineParser parser; + parser.addHelpOption(); + parser.addVersionOption(); + parser.process(app); + + MainWindow window; + window.show(); + return app.exec(); +} diff --git a/demo/mainwindow.cpp b/demo/mainwindow.cpp index 8265944..fa9b1e1 100644 --- a/demo/mainwindow.cpp +++ b/demo/mainwindow.cpp @@ -1,179 +1,180 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "mainwindow.h" -#include "samples/background.h" -#include "samples/customtiles.h" -#include "samples/flags.h" -#include "samples/items.h" -#include "samples/mouse.h" -#include "samples/utilities.h" -#include "samples/widgets.h" -#include "ui_mainwindow.h" - -#include -#include -#include -#include - -MainWindow::MainWindow() - : ui(new Ui::MainWindow) - , mCurrentItem(nullptr) -{ - ui->setupUi(this); - connect(ui->demoList, &QListWidget::doubleClicked, this, &MainWindow::onItemDoubleClick); - - auto actPosition = new QAction("Print position", this); - ui->geoMap->addAction(actPosition); - connect(actPosition, &QAction::triggered, actPosition, [this]() { - auto cam = ui->geoMap->getCamera(); - auto rect = cam.getProjection()->projToGeo(cam.projRect()); - auto pos = cam.getProjection()->projToGeo(cam.projRect().center()); - qInfo() << "current geo-rect" << rect; - qInfo() << "current geo-center" << pos; - }); - - auto actSelectView = new QAction("Select all (view)", this); - ui->geoMap->addAction(actSelectView); - connect(actSelectView, &QAction::triggered, actSelectView, [this]() { - ui->geoMap->unselectAll(); - auto selection = ui->geoMap->search(ui->geoMap->getCamera().projRect()); - for (auto item : selection) { - item->select(); - } - }); - - auto actUnselect = new QAction("Unselect all", this); - ui->geoMap->addAction(actUnselect); - connect(actUnselect, &QAction::triggered, actUnselect, [this]() { ui->geoMap->unselectAll(); }); - - auto actFront = new QAction("Bring to front (selected)", this); - ui->geoMap->addAction(actFront); - connect(actFront, &QAction::triggered, actFront, [this]() { - for (QGVItem* item : ui->geoMap->getSelections()) { - item->bringToFront(); - } - }); - - auto actBack = new QAction("Send to back (selected)", this); - ui->geoMap->addAction(actBack); - connect(actBack, &QAction::triggered, actBack, [this]() { - for (QGVItem* item : ui->geoMap->getSelections()) { - item->sendToBack(); - } - }); - - auto actOpacityPlus = new QAction("+25% opacity (selected)", this); - ui->geoMap->addAction(actOpacityPlus); - connect(actOpacityPlus, &QAction::triggered, actOpacityPlus, [this]() { - for (QGVItem* item : ui->geoMap->getSelections()) { - item->setOpacity(item->getOpacity() + 0.25); - } - }); - - auto actOpacityMinus = new QAction("-25% opacity (selected)", this); - ui->geoMap->addAction(actOpacityMinus); - connect(actOpacityMinus, &QAction::triggered, actOpacityMinus, [this]() { - for (QGVItem* item : ui->geoMap->getSelections()) { - item->setOpacity(item->getOpacity() - 0.25); - } - }); - - auto actImage = new QAction("Copy as image", this); - ui->geoMap->addAction(actImage); - connect(actImage, &QAction::triggered, actPosition, - [this]() { QGuiApplication::clipboard()->setImage(ui->geoMap->grabMapView(true).toImage()); }); - - QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); -} - -MainWindow::~MainWindow() -{ - delete ui; -} - -void MainWindow::init() -{ - /* - * All "online" items required instance of QNetworkAccessManager. - * Also it is recommended to use QNetworkCache for this manager to reduce - * network load and speed-up download. - */ - QDir("cacheDir").removeRecursively(); - mCache = new QNetworkDiskCache(this); - mCache->setCacheDirectory("cacheDir"); - mManager = new QNetworkAccessManager(this); - mManager->setCache(mCache); - QGV::setNetworkManager(mManager); - - mDemo = { - new WidgetsDemo(ui->geoMap, this), new BackgroundDemo(ui->geoMap, this), new MouseDemo(ui->geoMap, this), - new ItemsDemo(ui->geoMap, this), new FlagsDemo(ui->geoMap, this), new CustomTiles(ui->geoMap, this), - new UtilitiesDemo(ui->geoMap, this), - }; - for (DemoItem* item : mDemo) { - ui->demoList->addItem(item->label()); - auto lstItem = ui->demoList->item(ui->demoList->count() - 1); - lstItem->setData(Qt::UserRole, QVariant::fromValue(item)); - connect(item, &DemoItem::started, this, &MainWindow::onItemStarted); - connect(item, &DemoItem::ended, this, &MainWindow::onItemEnded); - item->init(); - } - ui->demoList->setCurrentRow(0); - - /* - * By default geomap started with zoom 1, which is usually a to high - * resolution for view. - * With this code we change camera to show "worldwide" area. - */ - auto target = ui->geoMap->getProjection()->boundaryGeoRect(); - ui->geoMap->cameraTo(QGVCameraActions(ui->geoMap).scaleTo(target)); -} - -void MainWindow::stopCurrent() -{ - if (mCurrentItem == nullptr) { - return; - } - ui->demoComment->setText(""); - auto old = mCurrentItem; - mCurrentItem = nullptr; - old->end(); -} - -void MainWindow::onItemDoubleClick() -{ - stopCurrent(); - mCurrentItem = ui->demoList->currentItem()->data(Qt::UserRole).value(); - mCurrentItem->start(); -} - -void MainWindow::onItemStarted(DemoItem* item) -{ - ui->demoComment->setText(item->comment()); -} - -void MainWindow::onItemEnded(DemoItem* /*item*/) -{ - stopCurrent(); -} - -void MainWindow::hideEvent(QHideEvent* /*event*/) -{ - QApplication::quit(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "mainwindow.h" +#include "samples/background.h" +#include "samples/customtiles.h" +#include "samples/flags.h" +#include "samples/items.h" +#include "samples/mouse.h" +#include "samples/utilities.h" +#include "samples/widgets.h" +#include "ui_mainwindow.h" + +#include +#include +#include +#include + +MainWindow::MainWindow() + : ui(new Ui::MainWindow) + , mCurrentItem(nullptr) +{ + ui->setupUi(this); + connect(ui->demoList, &QListWidget::doubleClicked, this, &MainWindow::onItemDoubleClick); + + auto actPosition = new QAction("Print position", this); + ui->geoMap->addAction(actPosition); + connect(actPosition, &QAction::triggered, actPosition, [this]() { + auto cam = ui->geoMap->getCamera(); + auto rect = cam.getProjection()->projToGeo(cam.projRect()); + auto pos = cam.getProjection()->projToGeo(cam.projRect().center()); + qInfo() << "current geo-rect" << rect; + qInfo() << "current geo-center" << pos; + }); + + auto actSelectView = new QAction("Select all (view)", this); + ui->geoMap->addAction(actSelectView); + connect(actSelectView, &QAction::triggered, actSelectView, [this]() { + ui->geoMap->unselectAll(); + auto selection = ui->geoMap->search(ui->geoMap->getCamera().projRect()); + for (auto item : selection) { + item->select(); + } + }); + + auto actUnselect = new QAction("Unselect all", this); + ui->geoMap->addAction(actUnselect); + connect(actUnselect, &QAction::triggered, actUnselect, [this]() { ui->geoMap->unselectAll(); }); + + auto actFront = new QAction("Bring to front (selected)", this); + ui->geoMap->addAction(actFront); + connect(actFront, &QAction::triggered, actFront, [this]() { + for (QGVItem* item : ui->geoMap->getSelections()) { + item->bringToFront(); + } + }); + + auto actBack = new QAction("Send to back (selected)", this); + ui->geoMap->addAction(actBack); + connect(actBack, &QAction::triggered, actBack, [this]() { + for (QGVItem* item : ui->geoMap->getSelections()) { + item->sendToBack(); + } + }); + + auto actOpacityPlus = new QAction("+25% opacity (selected)", this); + ui->geoMap->addAction(actOpacityPlus); + connect(actOpacityPlus, &QAction::triggered, actOpacityPlus, [this]() { + for (QGVItem* item : ui->geoMap->getSelections()) { + item->setOpacity(item->getOpacity() + 0.25); + } + }); + + auto actOpacityMinus = new QAction("-25% opacity (selected)", this); + ui->geoMap->addAction(actOpacityMinus); + connect(actOpacityMinus, &QAction::triggered, actOpacityMinus, [this]() { + for (QGVItem* item : ui->geoMap->getSelections()) { + item->setOpacity(item->getOpacity() - 0.25); + } + }); + + auto actImage = new QAction("Copy as image", this); + ui->geoMap->addAction(actImage); + connect(actImage, &QAction::triggered, actPosition, [this]() { + QGuiApplication::clipboard()->setImage(ui->geoMap->grabMapView(true).toImage()); + }); + + QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::init() +{ + /* + * All "online" items required instance of QNetworkAccessManager. + * Also it is recommended to use QNetworkCache for this manager to reduce + * network load and speed-up download. + */ + QDir("cacheDir").removeRecursively(); + mCache = new QNetworkDiskCache(this); + mCache->setCacheDirectory("cacheDir"); + mManager = new QNetworkAccessManager(this); + mManager->setCache(mCache); + QGV::setNetworkManager(mManager); + + mDemo = { + new WidgetsDemo(ui->geoMap, this), new BackgroundDemo(ui->geoMap, this), new MouseDemo(ui->geoMap, this), + new ItemsDemo(ui->geoMap, this), new FlagsDemo(ui->geoMap, this), new CustomTiles(ui->geoMap, this), + new UtilitiesDemo(ui->geoMap, this), + }; + for (DemoItem* item : mDemo) { + ui->demoList->addItem(item->label()); + auto lstItem = ui->demoList->item(ui->demoList->count() - 1); + lstItem->setData(Qt::UserRole, QVariant::fromValue(item)); + connect(item, &DemoItem::started, this, &MainWindow::onItemStarted); + connect(item, &DemoItem::ended, this, &MainWindow::onItemEnded); + item->init(); + } + ui->demoList->setCurrentRow(0); + + /* + * By default geomap started with zoom 1, which is usually a to high + * resolution for view. + * With this code we change camera to show "worldwide" area. + */ + auto target = ui->geoMap->getProjection()->boundaryGeoRect(); + ui->geoMap->cameraTo(QGVCameraActions(ui->geoMap).scaleTo(target)); +} + +void MainWindow::stopCurrent() +{ + if (mCurrentItem == nullptr) { + return; + } + ui->demoComment->setText(""); + auto old = mCurrentItem; + mCurrentItem = nullptr; + old->end(); +} + +void MainWindow::onItemDoubleClick() +{ + stopCurrent(); + mCurrentItem = ui->demoList->currentItem()->data(Qt::UserRole).value(); + mCurrentItem->start(); +} + +void MainWindow::onItemStarted(DemoItem* item) +{ + ui->demoComment->setText(item->comment()); +} + +void MainWindow::onItemEnded(DemoItem* /*item*/) +{ + stopCurrent(); +} + +void MainWindow::hideEvent(QHideEvent* /*event*/) +{ + QApplication::quit(); +} diff --git a/demo/mainwindow.h b/demo/mainwindow.h index 6e7479d..451273e 100644 --- a/demo/mainwindow.h +++ b/demo/mainwindow.h @@ -1,59 +1,59 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include -#include -#include - -#include -#include -#include - -#include "demoitem.h" - -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - MainWindow(); - ~MainWindow(); - -private Q_SLOTS: - void init(); - -private: - void stopCurrent(); - void onItemDoubleClick(); - void onItemStarted(DemoItem* item); - void onItemEnded(DemoItem* item); - void hideEvent(QHideEvent* event); - -private: - Ui::MainWindow* ui; - QNetworkAccessManager* mManager; - QNetworkDiskCache* mCache; - DemoItem* mCurrentItem; - QList mDemo; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +#include "demoitem.h" + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + ~MainWindow(); + +private Q_SLOTS: + void init(); + +private: + void stopCurrent(); + void onItemDoubleClick(); + void onItemStarted(DemoItem* item); + void onItemEnded(DemoItem* item); + void hideEvent(QHideEvent* event); + +private: + Ui::MainWindow* ui; + QNetworkAccessManager* mManager; + QNetworkDiskCache* mCache; + DemoItem* mCurrentItem; + QList mDemo; +}; diff --git a/demo/mainwindow.ui b/demo/mainwindow.ui index 6862e5e..6c2294b 100644 --- a/demo/mainwindow.ui +++ b/demo/mainwindow.ui @@ -1,92 +1,92 @@ - - - MainWindow - - - - 0 - 0 - 836 - 542 - - - - QGV Demo - - - - - - - - - - - false - - - QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - - - 4 - - - - - - - - - - 0 - 0 - - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::SelectRows - - - true - - - true - - - - - - - background-color: rgb(195, 195, 195); - - - true - - - Please select demo item and start it (double click) - - - - - - - - - - - - - QGVMap - QWidget -
QGeoView/QGVMap.h
- 1 -
-
- - -
+ + + MainWindow + + + + 0 + 0 + 836 + 542 + + + + QGV Demo + + + + + + + + + + + false + + + QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable + + + 4 + + + + + + + + + + 0 + 0 + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SelectRows + + + true + + + true + + + + + + + background-color: rgb(195, 195, 195); + + + true + + + Please select demo item and start it (double click) + + + + + + + + + + + + + QGVMap + QWidget +
QGeoView/QGVMap.h
+ 1 +
+
+ + +
diff --git a/demo/samples/background.cpp b/demo/samples/background.cpp index e3147b2..ade0147 100644 --- a/demo/samples/background.cpp +++ b/demo/samples/background.cpp @@ -1,101 +1,100 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "background.h" - -#include -#include -#include -#include - -BackgroundDemo::BackgroundDemo(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Single, parent) -{ -} - -QString BackgroundDemo::label() const -{ - return "Background maps"; -} - -QString BackgroundDemo::comment() const -{ - return "QGV supports multiple tile map types. This includes:
" - "- OpenStreetMaps
" - "- Google Maps
" - "- Bing Maps
" - "- Custom maps(OSM-like, for e.g MapServer)"; -} - -void BackgroundDemo::onInit() -{ - /* - * Footer will be used to show fixed text about selected background layer. - * Widget owned by map. - */ - mFooter = new QGVWidgetText(); - geoMap()->addWidget(mFooter); - /* - * List of available tile maps. - */ - const QString customURI = "http://c.tile.stamen.com/watercolor/${z}/${x}/${y}.jpg"; - const QList> layers = { - { "OSM", new QGVLayerOSM() }, - { "GOOGLE_SATELLITE", new QGVLayerGoogle(QGV::TilesType::Satellite) }, - { "GOOGLE_HYBRID", new QGVLayerGoogle(QGV::TilesType::Hybrid) }, - { "GOOGLE_SCHEMA", new QGVLayerGoogle(QGV::TilesType::Schema) }, - { "BING_SATELLITE", new QGVLayerBing(QGV::TilesType::Satellite) }, - { "BING_HYBRID", new QGVLayerBing(QGV::TilesType::Hybrid) }, - { "BING_SCHEMA", new QGVLayerBing(QGV::TilesType::Schema) }, - { "CUSTOM_OSM", new QGVLayerOSM(customURI) }, - }; - /* - * Layers will be owned by map. - */ - for (auto pair : layers) { - auto name = pair.first; - auto layer = pair.second; - layer->hide(); - geoMap()->addItem(layer); - selector()->addItem(name, std::bind(&BackgroundDemo::setSelected, this, layer, std::placeholders::_1)); - } - selector()->select(0); -} - -void BackgroundDemo::onStart() -{ - selector()->show(); -} - -void BackgroundDemo::onEnd() -{ - selector()->hide(); -} - -void BackgroundDemo::setSelected(QGVLayer* layer, bool selected) -{ - if (layer == nullptr) { - return; - } - layer->setVisible(selected); - if (selected) { - mFooter->setText(layer->getName() + ", " + layer->getDescription()); - } else { - mFooter->setText(""); - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "background.h" + +#include +#include +#include +#include + +BackgroundDemo::BackgroundDemo(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Single, parent) +{} + +QString BackgroundDemo::label() const +{ + return "Background maps"; +} + +QString BackgroundDemo::comment() const +{ + return "QGV supports multiple tile map types. This includes:
" + "- OpenStreetMaps
" + "- Google Maps
" + "- Bing Maps
" + "- Custom maps(OSM-like, for e.g MapServer)"; +} + +void BackgroundDemo::onInit() +{ + /* + * Footer will be used to show fixed text about selected background layer. + * Widget owned by map. + */ + mFooter = new QGVWidgetText(); + geoMap()->addWidget(mFooter); + /* + * List of available tile maps. + */ + const QString customURI = "http://c.tile.stamen.com/watercolor/${z}/${x}/${y}.jpg"; + const QList> layers = { + { "OSM", new QGVLayerOSM() }, + { "GOOGLE_SATELLITE", new QGVLayerGoogle(QGV::TilesType::Satellite) }, + { "GOOGLE_HYBRID", new QGVLayerGoogle(QGV::TilesType::Hybrid) }, + { "GOOGLE_SCHEMA", new QGVLayerGoogle(QGV::TilesType::Schema) }, + { "BING_SATELLITE", new QGVLayerBing(QGV::TilesType::Satellite) }, + { "BING_HYBRID", new QGVLayerBing(QGV::TilesType::Hybrid) }, + { "BING_SCHEMA", new QGVLayerBing(QGV::TilesType::Schema) }, + { "CUSTOM_OSM", new QGVLayerOSM(customURI) }, + }; + /* + * Layers will be owned by map. + */ + for (auto pair : layers) { + auto name = pair.first; + auto layer = pair.second; + layer->hide(); + geoMap()->addItem(layer); + selector()->addItem(name, std::bind(&BackgroundDemo::setSelected, this, layer, std::placeholders::_1)); + } + selector()->select(0); +} + +void BackgroundDemo::onStart() +{ + selector()->show(); +} + +void BackgroundDemo::onEnd() +{ + selector()->hide(); +} + +void BackgroundDemo::setSelected(QGVLayer* layer, bool selected) +{ + if (layer == nullptr) { + return; + } + layer->setVisible(selected); + if (selected) { + mFooter->setText(layer->getName() + ", " + layer->getDescription()); + } else { + mFooter->setText(""); + } +} diff --git a/demo/samples/background.h b/demo/samples/background.h index a04abb1..5a87303 100644 --- a/demo/samples/background.h +++ b/demo/samples/background.h @@ -1,44 +1,44 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -#include -#include - -class BackgroundDemo : public DemoItem -{ - Q_OBJECT - -public: - explicit BackgroundDemo(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - void setSelected(QGVLayer* layer, bool selected); - -private: - QGVWidgetText* mFooter; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +#include +#include + +class BackgroundDemo : public DemoItem +{ + Q_OBJECT + +public: + explicit BackgroundDemo(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + void setSelected(QGVLayer* layer, bool selected); + +private: + QGVWidgetText* mFooter; +}; diff --git a/demo/samples/customtiles.cpp b/demo/samples/customtiles.cpp index 932b679..ef89f42 100644 --- a/demo/samples/customtiles.cpp +++ b/demo/samples/customtiles.cpp @@ -1,91 +1,90 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "customtiles.h" -#include "mytiles.h" - -CustomTiles::CustomTiles(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Multi, parent) -{ -} - -QString CustomTiles::label() const -{ - return "Custom tiles"; -} - -QString CustomTiles::comment() const -{ - return "Here is a simple example of custom tile layer.
" - "Typical usage is:
" - "- the custom background maps
" - "- the georeferenced maps (for example heat maps)
"; -} - -void CustomTiles::onInit() -{ - /* - * List of demo tile layers. - */ - const QList> layers = { - { "My tiles(blue)", new MyTiles(targetAreaOut1(), Qt::blue) }, - { "My tiles(red)", new MyTiles(targetAreaOut2(), Qt::red) }, - }; - /* - * Layers will be owned by map. - */ - for (auto pair : layers) { - auto name = pair.first; - auto layer = pair.second; - layer->hide(); - geoMap()->addItem(layer); - selector()->addItem(name, std::bind(&CustomTiles::setSelected, this, layer, std::placeholders::_1)); - } - selector()->select(0); -} - -void CustomTiles::onStart() -{ - selector()->show(); - geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetAreaIn())); -} - -void CustomTiles::onEnd() -{ - selector()->hide(); -} - -QGV::GeoRect CustomTiles::targetAreaIn() const -{ - return QGV::GeoRect(QGV::GeoPos(48.236117, 11.499786), QGV::GeoPos(48.061851, 11.637178)); -} - -QGV::GeoRect CustomTiles::targetAreaOut1() const -{ - return QGV::GeoRect(QGV::GeoPos(48.406227, 9.731185), QGV::GeoPos(47.829682, 11.25)); -} - -QGV::GeoRect CustomTiles::targetAreaOut2() const -{ - return QGV::GeoRect(QGV::GeoPos(48.381619, 11.610039), QGV::GeoPos(47.804796, 13.449587)); -} - -void CustomTiles::setSelected(QGVLayer* layer, bool selected) -{ - layer->setVisible(selected); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "customtiles.h" +#include "mytiles.h" + +CustomTiles::CustomTiles(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Multi, parent) +{} + +QString CustomTiles::label() const +{ + return "Custom tiles"; +} + +QString CustomTiles::comment() const +{ + return "Here is a simple example of custom tile layer.
" + "Typical usage is:
" + "- the custom background maps
" + "- the georeferenced maps (for example heat maps)
"; +} + +void CustomTiles::onInit() +{ + /* + * List of demo tile layers. + */ + const QList> layers = { + { "My tiles(blue)", new MyTiles(targetAreaOut1(), Qt::blue) }, + { "My tiles(red)", new MyTiles(targetAreaOut2(), Qt::red) }, + }; + /* + * Layers will be owned by map. + */ + for (auto pair : layers) { + auto name = pair.first; + auto layer = pair.second; + layer->hide(); + geoMap()->addItem(layer); + selector()->addItem(name, std::bind(&CustomTiles::setSelected, this, layer, std::placeholders::_1)); + } + selector()->select(0); +} + +void CustomTiles::onStart() +{ + selector()->show(); + geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetAreaIn())); +} + +void CustomTiles::onEnd() +{ + selector()->hide(); +} + +QGV::GeoRect CustomTiles::targetAreaIn() const +{ + return QGV::GeoRect(QGV::GeoPos(48.236117, 11.499786), QGV::GeoPos(48.061851, 11.637178)); +} + +QGV::GeoRect CustomTiles::targetAreaOut1() const +{ + return QGV::GeoRect(QGV::GeoPos(48.406227, 9.731185), QGV::GeoPos(47.829682, 11.25)); +} + +QGV::GeoRect CustomTiles::targetAreaOut2() const +{ + return QGV::GeoRect(QGV::GeoPos(48.381619, 11.610039), QGV::GeoPos(47.804796, 13.449587)); +} + +void CustomTiles::setSelected(QGVLayer* layer, bool selected) +{ + layer->setVisible(selected); +} diff --git a/demo/samples/customtiles.h b/demo/samples/customtiles.h index 83708a0..1a0d6f9 100644 --- a/demo/samples/customtiles.h +++ b/demo/samples/customtiles.h @@ -1,43 +1,43 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -#include - -class CustomTiles : public DemoItem -{ - Q_OBJECT - -public: - explicit CustomTiles(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - QGV::GeoRect targetAreaIn() const; - QGV::GeoRect targetAreaOut1() const; - QGV::GeoRect targetAreaOut2() const; - void setSelected(QGVLayer* layer, bool selected); -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +#include + +class CustomTiles : public DemoItem +{ + Q_OBJECT + +public: + explicit CustomTiles(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + QGV::GeoRect targetAreaIn() const; + QGV::GeoRect targetAreaOut1() const; + QGV::GeoRect targetAreaOut2() const; + void setSelected(QGVLayer* layer, bool selected); +}; diff --git a/demo/samples/ellipse.cpp b/demo/samples/ellipse.cpp index 829fb60..7202047 100644 --- a/demo/samples/ellipse.cpp +++ b/demo/samples/ellipse.cpp @@ -1,56 +1,56 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "ellipse.h" - -#include -#include -#include - -Ellipse::Ellipse(const QGV::GeoRect& geoRect, QColor color) - : mGeoRect(geoRect) - , mColor(color) -{ - setSelectable(true); -} - -void Ellipse::onProjection(QGVMap* geoMap) -{ - QGVDrawItem::onProjection(geoMap); - mProjRect = geoMap->getProjection()->geoToProj(mGeoRect); -} - -QPainterPath Ellipse::projShape() const -{ - QPainterPath path; - path.addEllipse(mProjRect); - return path; -} - -void Ellipse::projPaint(QPainter* painter) -{ - painter->setPen(QPen(QBrush(Qt::black), 1)); - painter->setBrush(QBrush(mColor)); - painter->drawEllipse(mProjRect); -} - -QString Ellipse::projTooltip(const QPointF& projPos) const -{ - auto geo = getMap()->getProjection()->projToGeo(projPos); - return "Ellipse with color " + mColor.name() + "\nPosition " + geo.latToString() + " " + geo.lonToString(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "ellipse.h" + +#include +#include +#include + +Ellipse::Ellipse(const QGV::GeoRect& geoRect, QColor color) + : mGeoRect(geoRect) + , mColor(color) +{ + setSelectable(true); +} + +void Ellipse::onProjection(QGVMap* geoMap) +{ + QGVDrawItem::onProjection(geoMap); + mProjRect = geoMap->getProjection()->geoToProj(mGeoRect); +} + +QPainterPath Ellipse::projShape() const +{ + QPainterPath path; + path.addEllipse(mProjRect); + return path; +} + +void Ellipse::projPaint(QPainter* painter) +{ + painter->setPen(QPen(QBrush(Qt::black), 1)); + painter->setBrush(QBrush(mColor)); + painter->drawEllipse(mProjRect); +} + +QString Ellipse::projTooltip(const QPointF& projPos) const +{ + auto geo = getMap()->getProjection()->projToGeo(projPos); + return "Ellipse with color " + mColor.name() + "\nPosition " + geo.latToString() + " " + geo.lonToString(); +} diff --git a/demo/samples/ellipse.h b/demo/samples/ellipse.h index 1e2a75c..fd2b833 100644 --- a/demo/samples/ellipse.h +++ b/demo/samples/ellipse.h @@ -1,40 +1,40 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -class Ellipse : public QGVDrawItem -{ - Q_OBJECT - -public: - explicit Ellipse(const QGV::GeoRect& geoRect, QColor color); - -private: - void onProjection(QGVMap* geoMap) override; - QPainterPath projShape() const override; - void projPaint(QPainter* painter) override; - QString projTooltip(const QPointF& projPos) const override; - -private: - QGV::GeoRect mGeoRect; - QRectF mProjRect; - QColor mColor; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +class Ellipse : public QGVDrawItem +{ + Q_OBJECT + +public: + explicit Ellipse(const QGV::GeoRect& geoRect, QColor color); + +private: + void onProjection(QGVMap* geoMap) override; + QPainterPath projShape() const override; + void projPaint(QPainter* painter) override; + QString projTooltip(const QPointF& projPos) const override; + +private: + QGV::GeoRect mGeoRect; + QRectF mProjRect; + QColor mColor; +}; diff --git a/demo/samples/flags.cpp b/demo/samples/flags.cpp index f2dea83..7a34f56 100644 --- a/demo/samples/flags.cpp +++ b/demo/samples/flags.cpp @@ -1,110 +1,109 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "flags.h" -#include "rectangle.h" - -#include - -FlagsDemo::FlagsDemo(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Multi, parent) -{ -} - -QString FlagsDemo::label() const -{ - return "Item flags"; -} - -QString FlagsDemo::comment() const -{ - return "QGVDrawItem supports several flags or they combinations. Like:
" - "- ignore the map azimuth
" - "- ignore the map scale
" - "- item highlight
" - "- mouse tracking
" - "- custom transformation, highlight and selection

" - "The behavior of the flag should be visible by appropriate action (for example: selection, zooming or " - "mouse move).
" - "Use the context menu to see other properties, such as the z-level, opacity."; -} - -void FlagsDemo::onInit() -{ - const auto target = targetArea(); - const int size = 1000; - /* - * List of demo custom items. - */ - const QList> items = { - { "Ignore azimuth(blue)", new Rectangle(randRect(target, size), QGV::ItemFlag::IgnoreAzimuth, Qt::blue) }, - { "Ignore scale(red)", new Rectangle(randRect(target, 40), QGV::ItemFlag::IgnoreScale, Qt::red) }, - { "Highlightable(green)", new Rectangle(randRect(target, size), QGV::ItemFlag::Highlightable, Qt::green) }, - { "Highlightable-custom(gray)", - new Rectangle(randRect(target, size), QGV::ItemFlag::Highlightable | QGV::ItemFlag::HighlightCustom, - Qt::gray) }, - { "Custom selectable(cyan)", new Rectangle(randRect(target, size), QGV::ItemFlag::SelectCustom, Qt::cyan) }, - { "Clickable by mouse(magenta)", new Rectangle(randRect(target, size), QGV::ItemFlag::Clickable, Qt::magenta) }, - { "Custom transform(yellow)", new Rectangle(randRect(target, size), QGV::ItemFlag::Transformed, Qt::yellow) }, - }; - /* - * Layers will be owned by map. - */ - auto layer = new QGVLayer(); - layer->setName("Demo for flags"); - layer->setDescription("Demo for flags"); - /* - * Items will be owned by layer. - */ - for (auto pair : items) { - auto name = pair.first; - auto item = pair.second; - item->setProperty("drawDebug", name); - if (item->isFlag(QGV::ItemFlag::Clickable)) { - item->setSelectable(false); - } - layer->addItem(item); - selector()->addItem(name, std::bind(&FlagsDemo::setSelected, this, item, std::placeholders::_1)); - } - geoMap()->addItem(layer); - selector()->selectAll(); -} - -void FlagsDemo::onStart() -{ - selector()->show(); - geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetArea())); -} - -void FlagsDemo::onEnd() -{ - selector()->hide(); -} - -QGV::GeoRect FlagsDemo::targetArea() const -{ - return QGV::GeoRect(QGV::GeoPos(51.848624, 14.325923), QGV::GeoPos(51.743758, 14.453527)); -} - -void FlagsDemo::setSelected(QGVItem* item, bool selected) -{ - if (item == nullptr) { - return; - } - item->setVisible(selected); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "flags.h" +#include "rectangle.h" + +#include + +FlagsDemo::FlagsDemo(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Multi, parent) +{} + +QString FlagsDemo::label() const +{ + return "Item flags"; +} + +QString FlagsDemo::comment() const +{ + return "QGVDrawItem supports several flags or they combinations. Like:
" + "- ignore the map azimuth
" + "- ignore the map scale
" + "- item highlight
" + "- mouse tracking
" + "- custom transformation, highlight and selection

" + "The behavior of the flag should be visible by appropriate action (for example: selection, zooming or " + "mouse move).
" + "Use the context menu to see other properties, such as the z-level, opacity."; +} + +void FlagsDemo::onInit() +{ + const auto target = targetArea(); + const int size = 1000; + /* + * List of demo custom items. + */ + const QList> items = { + { "Ignore azimuth(blue)", new Rectangle(randRect(target, size), QGV::ItemFlag::IgnoreAzimuth, Qt::blue) }, + { "Ignore scale(red)", new Rectangle(randRect(target, 40), QGV::ItemFlag::IgnoreScale, Qt::red) }, + { "Highlightable(green)", new Rectangle(randRect(target, size), QGV::ItemFlag::Highlightable, Qt::green) }, + { "Highlightable-custom(gray)", + new Rectangle( + randRect(target, size), QGV::ItemFlag::Highlightable | QGV::ItemFlag::HighlightCustom, Qt::gray) }, + { "Custom selectable(cyan)", new Rectangle(randRect(target, size), QGV::ItemFlag::SelectCustom, Qt::cyan) }, + { "Clickable by mouse(magenta)", new Rectangle(randRect(target, size), QGV::ItemFlag::Clickable, Qt::magenta) }, + { "Custom transform(yellow)", new Rectangle(randRect(target, size), QGV::ItemFlag::Transformed, Qt::yellow) }, + }; + /* + * Layers will be owned by map. + */ + auto layer = new QGVLayer(); + layer->setName("Demo for flags"); + layer->setDescription("Demo for flags"); + /* + * Items will be owned by layer. + */ + for (auto pair : items) { + auto name = pair.first; + auto item = pair.second; + item->setProperty("drawDebug", name); + if (item->isFlag(QGV::ItemFlag::Clickable)) { + item->setSelectable(false); + } + layer->addItem(item); + selector()->addItem(name, std::bind(&FlagsDemo::setSelected, this, item, std::placeholders::_1)); + } + geoMap()->addItem(layer); + selector()->selectAll(); +} + +void FlagsDemo::onStart() +{ + selector()->show(); + geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetArea())); +} + +void FlagsDemo::onEnd() +{ + selector()->hide(); +} + +QGV::GeoRect FlagsDemo::targetArea() const +{ + return QGV::GeoRect(QGV::GeoPos(51.848624, 14.325923), QGV::GeoPos(51.743758, 14.453527)); +} + +void FlagsDemo::setSelected(QGVItem* item, bool selected) +{ + if (item == nullptr) { + return; + } + item->setVisible(selected); +} diff --git a/demo/samples/flags.h b/demo/samples/flags.h index 33e512d..c093f01 100644 --- a/demo/samples/flags.h +++ b/demo/samples/flags.h @@ -1,39 +1,39 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -class FlagsDemo : public DemoItem -{ - Q_OBJECT - -public: - explicit FlagsDemo(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - QGV::GeoRect targetArea() const; - void setSelected(QGVItem* item, bool selected); -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +class FlagsDemo : public DemoItem +{ + Q_OBJECT + +public: + explicit FlagsDemo(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + QGV::GeoRect targetArea() const; + void setSelected(QGVItem* item, bool selected); +}; diff --git a/demo/samples/items.cpp b/demo/samples/items.cpp index 17ad9f0..ce1e560 100644 --- a/demo/samples/items.cpp +++ b/demo/samples/items.cpp @@ -1,96 +1,97 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "items.h" -#include "ellipse.h" - -ItemsDemo::ItemsDemo(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Multi, parent) -{ -} - -QString ItemsDemo::label() const -{ - return "Layers and items"; -} - -QString ItemsDemo::comment() const -{ - return "QGV supports the tree-like storage for geo-map items. All QGV items should be derived " - "from QGVItem, where each QGVItem can belong to a map or any other QGVItem.
" - "QGVItem itself is not rendered on QGVMap and is only used to organize items. " - "For example, QGVLayer is not directly represented on map, but instead is used as a container " - "of other items. All visual items are derived from QGVDrawItem.
" - "Items always get parental properties (like visibility, opacity, etc).
" - "QGVMap::rootItem() is a map root item, which owns all other items."; -} - -void ItemsDemo::onInit() -{ - /* - * List of demo color layers. - */ - const QList> colors = { - { "Blue Layer", Qt::blue }, { "Red Layer", Qt::red }, { "Green Layer", Qt::green }, - }; - /* - * Layers will be owned by map. - */ - for (auto pair : colors) { - auto name = pair.first; - auto color = pair.second; - auto layer = new QGVLayer(); - layer->setName(name); - layer->setDescription("Demo for " + name); - geoMap()->addItem(layer); - selector()->addItem(name, std::bind(&ItemsDemo::setSelected, this, layer, std::placeholders::_1)); - /* - * Items will be owned by layer. - */ - for (int i = 0; i < 10; i++) { - auto radius = 100 + qrand() % 1000; - layer->addItem(new Ellipse(randRect(targetArea(), QSizeF(radius, radius)), color)); - } - } - selector()->selectAll(); -} - -void ItemsDemo::onStart() -{ - selector()->show(); - geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetArea())); -} - -void ItemsDemo::onEnd() -{ - selector()->hide(); -} - -QGV::GeoRect ItemsDemo::targetArea() const -{ - return QGV::GeoRect(QGV::GeoPos(46.419424, 28.888922), QGV::GeoPos(46.282726, 29.119152)); - ; -} - -void ItemsDemo::setSelected(QGVLayer* layer, bool selected) -{ - if (layer == nullptr) { - return; - } - layer->setVisible(selected); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "items.h" +#include "ellipse.h" + +ItemsDemo::ItemsDemo(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Multi, parent) +{} + +QString ItemsDemo::label() const +{ + return "Layers and items"; +} + +QString ItemsDemo::comment() const +{ + return "QGV supports the tree-like storage for geo-map items. All QGV items should be derived " + "from QGVItem, where each QGVItem can belong to a map or any other QGVItem.
" + "QGVItem itself is not rendered on QGVMap and is only used to organize items. " + "For example, QGVLayer is not directly represented on map, but instead is used as a container " + "of other items. All visual items are derived from QGVDrawItem.
" + "Items always get parental properties (like visibility, opacity, etc).
" + "QGVMap::rootItem() is a map root item, which owns all other items."; +} + +void ItemsDemo::onInit() +{ + /* + * List of demo color layers. + */ + const QList> colors = { + { "Blue Layer", Qt::blue }, + { "Red Layer", Qt::red }, + { "Green Layer", Qt::green }, + }; + /* + * Layers will be owned by map. + */ + for (auto pair : colors) { + auto name = pair.first; + auto color = pair.second; + auto layer = new QGVLayer(); + layer->setName(name); + layer->setDescription("Demo for " + name); + geoMap()->addItem(layer); + selector()->addItem(name, std::bind(&ItemsDemo::setSelected, this, layer, std::placeholders::_1)); + /* + * Items will be owned by layer. + */ + for (int i = 0; i < 10; i++) { + auto radius = 100 + qrand() % 1000; + layer->addItem(new Ellipse(randRect(targetArea(), QSizeF(radius, radius)), color)); + } + } + selector()->selectAll(); +} + +void ItemsDemo::onStart() +{ + selector()->show(); + geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetArea())); +} + +void ItemsDemo::onEnd() +{ + selector()->hide(); +} + +QGV::GeoRect ItemsDemo::targetArea() const +{ + return QGV::GeoRect(QGV::GeoPos(46.419424, 28.888922), QGV::GeoPos(46.282726, 29.119152)); + ; +} + +void ItemsDemo::setSelected(QGVLayer* layer, bool selected) +{ + if (layer == nullptr) { + return; + } + layer->setVisible(selected); +} diff --git a/demo/samples/items.h b/demo/samples/items.h index ad6a721..02a869f 100644 --- a/demo/samples/items.h +++ b/demo/samples/items.h @@ -1,41 +1,41 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -#include - -class ItemsDemo : public DemoItem -{ - Q_OBJECT - -public: - explicit ItemsDemo(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - QGV::GeoRect targetArea() const; - void setSelected(QGVLayer* layer, bool selected); -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +#include + +class ItemsDemo : public DemoItem +{ + Q_OBJECT + +public: + explicit ItemsDemo(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + QGV::GeoRect targetArea() const; + void setSelected(QGVLayer* layer, bool selected); +}; diff --git a/demo/samples/mouse.cpp b/demo/samples/mouse.cpp index cfd279d..d389717 100644 --- a/demo/samples/mouse.cpp +++ b/demo/samples/mouse.cpp @@ -1,104 +1,103 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "mouse.h" - -MouseDemo::MouseDemo(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Multi, parent) -{ -} - -QString MouseDemo::label() const -{ - return "Mouse actions"; -} - -QString MouseDemo::comment() const -{ - return "QGV supports different mouse actions, like:
" - "- mouse tracking
" - "- zoom by mouse wheel
" - "- zoom by rubber band(right button)
" - "- item selection by left button or rubber band (right button + ctrl/shift)
" - "- unselect all items by double
" - "- map move by left button
" - "- context menu by right button
" - "- item tooltip
"; -} - -void MouseDemo::onInit() -{ - /* - * QGVWidgetText will be used to show current position. - * Widgets owned by map. - */ - mText = new QGVWidgetText(); - mText->setAnchor(QPoint(0, 0), { Qt::TopEdge }); - geoMap()->addWidget(mText); - connect(geoMap(), &QGVMap::mapMouseMove, this, &MouseDemo::onMouseMove); - /* - * Features selector - */ - const QList> actions = { - { "Move tracking", std::bind(&MouseDemo::startTracking, this, std::placeholders::_1) }, - { "Zoom(wheel)", - std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::ZoomWheel, std::placeholders::_1) }, - { "Zoom(rect)", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::ZoomRect, std::placeholders::_1) }, - { "Selection", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::Selection, std::placeholders::_1) }, - { "Move", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::Move, std::placeholders::_1) }, - { "Context menu", - std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::ContextMenu, std::placeholders::_1) }, - { "Tooltip", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::Tooltip, std::placeholders::_1) }, - }; - for (auto pair : actions) { - auto name = pair.first; - auto func = pair.second; - selector()->addItem(name, func); - } - selector()->selectAll(); -} - -void MouseDemo::onStart() -{ - selector()->show(); -} - -void MouseDemo::onEnd() -{ - selector()->hide(); -} - -void MouseDemo::startTracking(bool start) -{ - geoMap()->setMouseTracking(start); -} - -void MouseDemo::enableAction(QGV::MouseAction action, bool enable) -{ - geoMap()->setMouseAction(action, enable); -} - -void MouseDemo::onMouseMove(QPointF projPos) -{ - /* - * Current projection position can be converted to geo-coordinates and - * printed by corresponding functions - */ - auto geoPos = geoMap()->getProjection()->projToGeo(projPos); - mText->setText(QString("%1, %2").arg(geoPos.latToString()).arg(geoPos.lonToString())); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "mouse.h" + +MouseDemo::MouseDemo(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Multi, parent) +{} + +QString MouseDemo::label() const +{ + return "Mouse actions"; +} + +QString MouseDemo::comment() const +{ + return "QGV supports different mouse actions, like:
" + "- mouse tracking
" + "- zoom by mouse wheel
" + "- zoom by rubber band(right button)
" + "- item selection by left button or rubber band (right button + ctrl/shift)
" + "- unselect all items by double
" + "- map move by left button
" + "- context menu by right button
" + "- item tooltip
"; +} + +void MouseDemo::onInit() +{ + /* + * QGVWidgetText will be used to show current position. + * Widgets owned by map. + */ + mText = new QGVWidgetText(); + mText->setAnchor(QPoint(0, 0), { Qt::TopEdge }); + geoMap()->addWidget(mText); + connect(geoMap(), &QGVMap::mapMouseMove, this, &MouseDemo::onMouseMove); + /* + * Features selector + */ + const QList> actions = { + { "Move tracking", std::bind(&MouseDemo::startTracking, this, std::placeholders::_1) }, + { "Zoom(wheel)", + std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::ZoomWheel, std::placeholders::_1) }, + { "Zoom(rect)", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::ZoomRect, std::placeholders::_1) }, + { "Selection", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::Selection, std::placeholders::_1) }, + { "Move", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::Move, std::placeholders::_1) }, + { "Context menu", + std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::ContextMenu, std::placeholders::_1) }, + { "Tooltip", std::bind(&MouseDemo::enableAction, this, QGV::MouseAction::Tooltip, std::placeholders::_1) }, + }; + for (auto pair : actions) { + auto name = pair.first; + auto func = pair.second; + selector()->addItem(name, func); + } + selector()->selectAll(); +} + +void MouseDemo::onStart() +{ + selector()->show(); +} + +void MouseDemo::onEnd() +{ + selector()->hide(); +} + +void MouseDemo::startTracking(bool start) +{ + geoMap()->setMouseTracking(start); +} + +void MouseDemo::enableAction(QGV::MouseAction action, bool enable) +{ + geoMap()->setMouseAction(action, enable); +} + +void MouseDemo::onMouseMove(QPointF projPos) +{ + /* + * Current projection position can be converted to geo-coordinates and + * printed by corresponding functions + */ + auto geoPos = geoMap()->getProjection()->projToGeo(projPos); + mText->setText(QString("%1, %2").arg(geoPos.latToString()).arg(geoPos.lonToString())); +} diff --git a/demo/samples/mouse.h b/demo/samples/mouse.h index ca1b13b..767569c 100644 --- a/demo/samples/mouse.h +++ b/demo/samples/mouse.h @@ -1,45 +1,45 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -#include - -class MouseDemo : public DemoItem -{ - Q_OBJECT - -public: - explicit MouseDemo(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - void startTracking(bool start); - void enableAction(QGV::MouseAction action, bool enable); - void onMouseMove(QPointF projPos); - -private: - QGVWidgetText* mText; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +#include + +class MouseDemo : public DemoItem +{ + Q_OBJECT + +public: + explicit MouseDemo(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + void startTracking(bool start); + void enableAction(QGV::MouseAction action, bool enable); + void onMouseMove(QPointF projPos); + +private: + QGVWidgetText* mText; +}; diff --git a/demo/samples/mytile.cpp b/demo/samples/mytile.cpp index 7291b61..91430f1 100644 --- a/demo/samples/mytile.cpp +++ b/demo/samples/mytile.cpp @@ -1,69 +1,68 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "mytile.h" - -#include -#include -#include - -MyTile::MyTile(const QGV::GeoTilePos& tilePos, QColor color) - : mTilePos(tilePos) - , mColor(color) -{ -} - -void MyTile::onProjection(QGVMap* geoMap) -{ - QGVDrawItem::onProjection(geoMap); - mProjRect = geoMap->getProjection()->geoToProj(mTilePos.toGeoRect()); -} - -QPainterPath MyTile::projShape() const -{ - QPainterPath path; - path.addRect(mProjRect); - return path; -} - -void MyTile::projPaint(QPainter* painter) -{ - QPen pen = QPen(QBrush(Qt::black), 1); - pen.setCosmetic(true); - painter->setPen(pen); - painter->setBrush(QBrush(mColor)); - painter->drawRect(mProjRect); - drawText(painter); -} - -void MyTile::drawText(QPainter* painter) -{ - QString text = QString("Custom tile\nZ:%1\nX:%2\nY:%3") - .arg(mTilePos.zoom()) - .arg(mTilePos.pos().x()) - .arg(mTilePos.pos().y()); - QPen pen = QPen(Qt::black); - pen.setWidth(1); - pen.setCosmetic(true); - QBrush brush = QBrush(Qt::white); - painter->setPen(pen); - painter->setBrush(brush); - auto path = QGV::createTextPath(mProjRect.toRect(), text, QFont(), pen.width()); - path = QGV::createTransfromScale(mProjRect.center(), 0.75).map(path); - painter->drawPath(path); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "mytile.h" + +#include +#include +#include + +MyTile::MyTile(const QGV::GeoTilePos& tilePos, QColor color) + : mTilePos(tilePos) + , mColor(color) +{} + +void MyTile::onProjection(QGVMap* geoMap) +{ + QGVDrawItem::onProjection(geoMap); + mProjRect = geoMap->getProjection()->geoToProj(mTilePos.toGeoRect()); +} + +QPainterPath MyTile::projShape() const +{ + QPainterPath path; + path.addRect(mProjRect); + return path; +} + +void MyTile::projPaint(QPainter* painter) +{ + QPen pen = QPen(QBrush(Qt::black), 1); + pen.setCosmetic(true); + painter->setPen(pen); + painter->setBrush(QBrush(mColor)); + painter->drawRect(mProjRect); + drawText(painter); +} + +void MyTile::drawText(QPainter* painter) +{ + QString text = QString("Custom tile\nZ:%1\nX:%2\nY:%3") + .arg(mTilePos.zoom()) + .arg(mTilePos.pos().x()) + .arg(mTilePos.pos().y()); + QPen pen = QPen(Qt::black); + pen.setWidth(1); + pen.setCosmetic(true); + QBrush brush = QBrush(Qt::white); + painter->setPen(pen); + painter->setBrush(brush); + auto path = QGV::createTextPath(mProjRect.toRect(), text, QFont(), pen.width()); + path = QGV::createTransfromScale(mProjRect.center(), 0.75).map(path); + painter->drawPath(path); +} diff --git a/demo/samples/mytile.h b/demo/samples/mytile.h index 000e3c0..9123475 100644 --- a/demo/samples/mytile.h +++ b/demo/samples/mytile.h @@ -1,43 +1,43 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -#include -#include - -class MyTile : public QGVDrawItem -{ - Q_OBJECT - -public: - explicit MyTile(const QGV::GeoTilePos& tilePos, QColor color); - -private: - void onProjection(QGVMap* geoMap) override; - QPainterPath projShape() const override; - void projPaint(QPainter* painter) override; - void drawText(QPainter* painter); - -private: - QGV::GeoTilePos mTilePos; - QRectF mProjRect; - QColor mColor; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +#include +#include + +class MyTile : public QGVDrawItem +{ + Q_OBJECT + +public: + explicit MyTile(const QGV::GeoTilePos& tilePos, QColor color); + +private: + void onProjection(QGVMap* geoMap) override; + QPainterPath projShape() const override; + void projPaint(QPainter* painter) override; + void drawText(QPainter* painter); + +private: + QGV::GeoTilePos mTilePos; + QRectF mProjRect; + QColor mColor; +}; diff --git a/demo/samples/mytiles.cpp b/demo/samples/mytiles.cpp index 2c0417f..dbc440d 100644 --- a/demo/samples/mytiles.cpp +++ b/demo/samples/mytiles.cpp @@ -1,61 +1,61 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "mytiles.h" -#include "mytile.h" - -MyTiles::MyTiles(const QGV::GeoRect& activeRect, QColor color) - : mActiveGeoRect(activeRect) - , mColor(color) -{ - setZValue(-1); -} - -void MyTiles::onProjection(QGVMap* geoMap) -{ - QGVLayerTiles::onProjection(geoMap); - mActiveTileRect = QRect(QGV::GeoTilePos::geoToTilePos(minZoomlevel(), mActiveGeoRect.topLeft()).pos(), - QGV::GeoTilePos::geoToTilePos(minZoomlevel(), mActiveGeoRect.bottomRight()).pos()); -} - -int MyTiles::minZoomlevel() const -{ - return 9; -} - -int MyTiles::maxZoomlevel() const -{ - return 14; -} - -void MyTiles::request(const QGV::GeoTilePos& tilePos) -{ - auto tilePosParent = tilePos.parent(minZoomlevel()).pos(); - if (!mActiveTileRect.contains(tilePosParent)) { - return; - } - QGVDrawItem* tile = new MyTile(tilePos, mColor); - tile->setOpacity(0.5); - tile->setSelectable(false); - onTile(tilePos, tile); -} - -void MyTiles::cancel(const QGV::GeoTilePos& /*tilePos*/) -{ - qt_noop(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "mytiles.h" +#include "mytile.h" + +MyTiles::MyTiles(const QGV::GeoRect& activeRect, QColor color) + : mActiveGeoRect(activeRect) + , mColor(color) +{ + setZValue(-1); +} + +void MyTiles::onProjection(QGVMap* geoMap) +{ + QGVLayerTiles::onProjection(geoMap); + mActiveTileRect = QRect(QGV::GeoTilePos::geoToTilePos(minZoomlevel(), mActiveGeoRect.topLeft()).pos(), + QGV::GeoTilePos::geoToTilePos(minZoomlevel(), mActiveGeoRect.bottomRight()).pos()); +} + +int MyTiles::minZoomlevel() const +{ + return 9; +} + +int MyTiles::maxZoomlevel() const +{ + return 14; +} + +void MyTiles::request(const QGV::GeoTilePos& tilePos) +{ + auto tilePosParent = tilePos.parent(minZoomlevel()).pos(); + if (!mActiveTileRect.contains(tilePosParent)) { + return; + } + QGVDrawItem* tile = new MyTile(tilePos, mColor); + tile->setOpacity(0.5); + tile->setSelectable(false); + onTile(tilePos, tile); +} + +void MyTiles::cancel(const QGV::GeoTilePos& /*tilePos*/) +{ + qt_noop(); +} diff --git a/demo/samples/mytiles.h b/demo/samples/mytiles.h index 94b8cb2..67883b5 100644 --- a/demo/samples/mytiles.h +++ b/demo/samples/mytiles.h @@ -1,41 +1,41 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -class MyTiles : public QGVLayerTiles -{ - Q_OBJECT - -public: - MyTiles(const QGV::GeoRect& activeRect, QColor color); - -private: - void onProjection(QGVMap* geoMap) override; - int minZoomlevel() const override final; - int maxZoomlevel() const override final; - void request(const QGV::GeoTilePos& tilePos) override final; - void cancel(const QGV::GeoTilePos& tilePos) override; - -private: - QGV::GeoRect mActiveGeoRect; - QRect mActiveTileRect; - QColor mColor; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +class MyTiles : public QGVLayerTiles +{ + Q_OBJECT + +public: + MyTiles(const QGV::GeoRect& activeRect, QColor color); + +private: + void onProjection(QGVMap* geoMap) override; + int minZoomlevel() const override final; + int maxZoomlevel() const override final; + void request(const QGV::GeoTilePos& tilePos) override final; + void cancel(const QGV::GeoTilePos& tilePos) override; + +private: + QGV::GeoRect mActiveGeoRect; + QRect mActiveTileRect; + QColor mColor; +}; diff --git a/demo/samples/placemark.cpp b/demo/samples/placemark.cpp index 97594a3..afcddbc 100644 --- a/demo/samples/placemark.cpp +++ b/demo/samples/placemark.cpp @@ -1,42 +1,42 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "placemark.h" - -Placemark::Placemark(const QGV::GeoPos& geoPos) -{ - setFlag(QGV::ItemFlag::IgnoreScale); - setFlag(QGV::ItemFlag::IgnoreAzimuth); - setFlag(QGV::ItemFlag::Highlightable); - setFlag(QGV::ItemFlag::HighlightCustom); - setFlag(QGV::ItemFlag::Highlightable); - setFlag(QGV::ItemFlag::Transformed); - setGeometry(geoPos, QSize(32, 32), QPoint(16, 32)); - const QString url = "http://maps.google.com/mapfiles/kml/paddle/blu-circle.png"; - load(url); -} - -QTransform Placemark::projTransform() const -{ - return isFlag(QGV::ItemFlag::Highlighted) ? QGV::createTransfromScale(projAnchor(), 1.2) : QTransform(); -} - -void Placemark::projOnFlags() -{ - setOpacity(isFlag(QGV::ItemFlag::Highlighted) ? 0.3 : 1.0); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "placemark.h" + +Placemark::Placemark(const QGV::GeoPos& geoPos) +{ + setFlag(QGV::ItemFlag::IgnoreScale); + setFlag(QGV::ItemFlag::IgnoreAzimuth); + setFlag(QGV::ItemFlag::Highlightable); + setFlag(QGV::ItemFlag::HighlightCustom); + setFlag(QGV::ItemFlag::Highlightable); + setFlag(QGV::ItemFlag::Transformed); + setGeometry(geoPos, QSize(32, 32), QPoint(16, 32)); + const QString url = "http://maps.google.com/mapfiles/kml/paddle/blu-circle.png"; + load(url); +} + +QTransform Placemark::projTransform() const +{ + return isFlag(QGV::ItemFlag::Highlighted) ? QGV::createTransfromScale(projAnchor(), 1.2) : QTransform(); +} + +void Placemark::projOnFlags() +{ + setOpacity(isFlag(QGV::ItemFlag::Highlighted) ? 0.3 : 1.0); +} diff --git a/demo/samples/placemark.h b/demo/samples/placemark.h index 0508d44..f04e7e6 100644 --- a/demo/samples/placemark.h +++ b/demo/samples/placemark.h @@ -1,33 +1,33 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -class Placemark : public QGVImage -{ - Q_OBJECT - -public: - explicit Placemark(const QGV::GeoPos& geoPos); - -private: - QTransform projTransform() const override; - void projOnFlags() override; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +class Placemark : public QGVImage +{ + Q_OBJECT + +public: + explicit Placemark(const QGV::GeoPos& geoPos); + +private: + QTransform projTransform() const override; + void projOnFlags() override; +}; diff --git a/demo/samples/rectangle.cpp b/demo/samples/rectangle.cpp index 6b6e2e7..defb5bb 100644 --- a/demo/samples/rectangle.cpp +++ b/demo/samples/rectangle.cpp @@ -1,95 +1,95 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "rectangle.h" - -#include -#include -#include - -Rectangle::Rectangle(const QGV::GeoRect& geoRect, QGV::ItemFlags flags, QColor color) - : mGeoRect(geoRect) - , mColor(color) -{ - setFlags(flags); - setSelectable(true); -} - -void Rectangle::onProjection(QGVMap* geoMap) -{ - QGVDrawItem::onProjection(geoMap); - mProjRect = geoMap->getProjection()->geoToProj(mGeoRect); -} - -void Rectangle::onUpdate() -{ - QGVDrawItem::onUpdate(); -} - -QPainterPath Rectangle::projShape() const -{ - QPainterPath path; - path.addRect(mProjRect); - return path; -} - -void Rectangle::projPaint(QPainter* painter) -{ - QPen pen; - if (isFlag(QGV::ItemFlag::Highlighted) && isFlag(QGV::ItemFlag::HighlightCustom)) { - pen = QPen(QBrush(Qt::black), 5); - } else { - pen = QPen(QBrush(Qt::black), 1); - } - pen.setCosmetic(true); - painter->setPen(pen); - painter->setBrush(QBrush(mColor)); - painter->drawRect(mProjRect); - if (isSelected() && isFlag(QGV::ItemFlag::SelectCustom)) { - painter->drawLine(mProjRect.topLeft(), mProjRect.bottomRight()); - painter->drawLine(mProjRect.topRight(), mProjRect.bottomLeft()); - } -} - -QPointF Rectangle::projAnchor() const -{ - return mProjRect.center(); -} - -QTransform Rectangle::projTransform() const -{ - return QGV::createTransfromAzimuth(projAnchor(), 45); -} - -QString Rectangle::projTooltip(const QPointF& projPos) const -{ - auto geo = getMap()->getProjection()->projToGeo(projPos); - return "Rectangle with color " + mColor.name() + "\nPosition " + geo.latToString() + " " + geo.lonToString(); -} - -void Rectangle::projOnMouseClick(const QPointF& projPos) -{ - setOpacity(qMax(0.2, getOpacity() - 0.2)); - qInfo() << "single click" << projPos; -} - -void Rectangle::projOnMouseDoubleClick(const QPointF& projPos) -{ - setOpacity(1.0); - qInfo() << "double click" << projPos; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "rectangle.h" + +#include +#include +#include + +Rectangle::Rectangle(const QGV::GeoRect& geoRect, QGV::ItemFlags flags, QColor color) + : mGeoRect(geoRect) + , mColor(color) +{ + setFlags(flags); + setSelectable(true); +} + +void Rectangle::onProjection(QGVMap* geoMap) +{ + QGVDrawItem::onProjection(geoMap); + mProjRect = geoMap->getProjection()->geoToProj(mGeoRect); +} + +void Rectangle::onUpdate() +{ + QGVDrawItem::onUpdate(); +} + +QPainterPath Rectangle::projShape() const +{ + QPainterPath path; + path.addRect(mProjRect); + return path; +} + +void Rectangle::projPaint(QPainter* painter) +{ + QPen pen; + if (isFlag(QGV::ItemFlag::Highlighted) && isFlag(QGV::ItemFlag::HighlightCustom)) { + pen = QPen(QBrush(Qt::black), 5); + } else { + pen = QPen(QBrush(Qt::black), 1); + } + pen.setCosmetic(true); + painter->setPen(pen); + painter->setBrush(QBrush(mColor)); + painter->drawRect(mProjRect); + if (isSelected() && isFlag(QGV::ItemFlag::SelectCustom)) { + painter->drawLine(mProjRect.topLeft(), mProjRect.bottomRight()); + painter->drawLine(mProjRect.topRight(), mProjRect.bottomLeft()); + } +} + +QPointF Rectangle::projAnchor() const +{ + return mProjRect.center(); +} + +QTransform Rectangle::projTransform() const +{ + return QGV::createTransfromAzimuth(projAnchor(), 45); +} + +QString Rectangle::projTooltip(const QPointF& projPos) const +{ + auto geo = getMap()->getProjection()->projToGeo(projPos); + return "Rectangle with color " + mColor.name() + "\nPosition " + geo.latToString() + " " + geo.lonToString(); +} + +void Rectangle::projOnMouseClick(const QPointF& projPos) +{ + setOpacity(qMax(0.2, getOpacity() - 0.2)); + qInfo() << "single click" << projPos; +} + +void Rectangle::projOnMouseDoubleClick(const QPointF& projPos) +{ + setOpacity(1.0); + qInfo() << "double click" << projPos; +} diff --git a/demo/samples/rectangle.h b/demo/samples/rectangle.h index 5df10b6..5972ab9 100644 --- a/demo/samples/rectangle.h +++ b/demo/samples/rectangle.h @@ -1,48 +1,48 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -#include -#include - -class Rectangle : public QGVDrawItem -{ - Q_OBJECT - -public: - explicit Rectangle(const QGV::GeoRect& geoRect, QGV::ItemFlags flags, QColor color); - -private: - void onProjection(QGVMap* geoMap) override; - void onUpdate() override; - QPainterPath projShape() const override; - void projPaint(QPainter* painter) override; - QPointF projAnchor() const override; - QTransform projTransform() const override; - QString projTooltip(const QPointF& projPos) const override; - void projOnMouseClick(const QPointF& projPos) override; - void projOnMouseDoubleClick(const QPointF& projPos) override; - -private: - QGV::GeoRect mGeoRect; - QRectF mProjRect; - QColor mColor; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +#include +#include + +class Rectangle : public QGVDrawItem +{ + Q_OBJECT + +public: + explicit Rectangle(const QGV::GeoRect& geoRect, QGV::ItemFlags flags, QColor color); + +private: + void onProjection(QGVMap* geoMap) override; + void onUpdate() override; + QPainterPath projShape() const override; + void projPaint(QPainter* painter) override; + QPointF projAnchor() const override; + QTransform projTransform() const override; + QString projTooltip(const QPointF& projPos) const override; + void projOnMouseClick(const QPointF& projPos) override; + void projOnMouseDoubleClick(const QPointF& projPos) override; + +private: + QGV::GeoRect mGeoRect; + QRectF mProjRect; + QColor mColor; +}; diff --git a/demo/samples/utilities.cpp b/demo/samples/utilities.cpp index aae1d23..b5e55b1 100644 --- a/demo/samples/utilities.cpp +++ b/demo/samples/utilities.cpp @@ -1,190 +1,189 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "utilities.h" -#include "ellipse.h" -#include "placemark.h" -#include "waveanimation.h" - -#include - -UtilitiesDemo::UtilitiesDemo(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Multi, parent) -{ -} - -QString UtilitiesDemo::label() const -{ - return "Utilities"; -} - -QString UtilitiesDemo::comment() const -{ - return "A set of additional features and demos."; -} - -void UtilitiesDemo::onInit() -{ - /* - * Layers owned by map. - */ - mQGV = createQGVLayer(); - m10000 = create10000Layer(); - mQGVAnimation.reset(createQGVAnimation()); - - selector()->addItem("QGV", std::bind(&UtilitiesDemo::showQGV, this, std::placeholders::_1)); - selector()->addItem("QGV animation", std::bind(&UtilitiesDemo::animationQGV, this, std::placeholders::_1)); - selector()->addItem("10000 elements", std::bind(&UtilitiesDemo::show10000, this, std::placeholders::_1)); - selector()->addItem("Draw debug", std::bind(&UtilitiesDemo::drawDebug, this, std::placeholders::_1)); - selector()->addItem("Print debug(log)", std::bind(&UtilitiesDemo::printDebug, this, std::placeholders::_1)); -} - -void UtilitiesDemo::onStart() -{ - selector()->show(); -} - -void UtilitiesDemo::onEnd() -{ - selector()->hide(); -} - -QGV::GeoRect UtilitiesDemo::targetQGVArea() const -{ - return QGV::GeoRect(QGV::GeoPos(55.096754, 82.682533), QGV::GeoPos(54.862608, 83.138179)); -} - -QPixmap UtilitiesDemo::createQGVImage() -{ - const auto target = QSize(150, 150); - const auto path = QGV::createTextPath(QRect(QPoint(0, 0), target), "QGeoView", QFont(), 1); - QImage image(target, QImage::Format_ARGB32_Premultiplied); - image.fill(qRgba(0, 0, 0, 0)); - QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); - QPainter painter(&pixmap); - QPen pen = QPen(Qt::black); - pen.setWidth(1); - pen.setCosmetic(true); - painter.setPen(pen); - QBrush brush = QBrush(Qt::black); - painter.setBrush(brush); - painter.drawPath(path); - return pixmap; -} - -QGVLayer* UtilitiesDemo::createQGVLayer() -{ - const auto target = targetQGVArea(); - const auto sizeLon = target.lonLeft() - target.lonRigth(); - const auto sizeLat = target.latTop() - target.latBottom(); - /* - * Layers owned by map. - */ - auto layer = new QGVLayer(); - layer->setName("QGV"); - layer->setDescription("Demo for QGV"); - geoMap()->addItem(layer); - /* - * Items will be owned by layer. - */ - QImage image = createQGVImage().toImage(); - for (int x = 0; x < image.width(); x++) { - for (int y = 0; y < image.height(); y++) { - if (image.pixelColor(x, y) != Qt::black) - continue; - double xScale = (double)x / image.width(); - double yScale = (double)y / image.height(); - QGV::GeoPos geoPos = QGV::GeoPos(target.latTop() - sizeLat * yScale, target.lonLeft() - sizeLon * xScale); - auto image = new Placemark(geoPos); - layer->addItem(image); - } - } - - qInfo() << layer->countItems() << "items in QGV demo layer"; - return layer; -} - -QAbstractAnimation* UtilitiesDemo::createQGVAnimation() -{ - const double w = geoMap()->getProjection()->geoToProj(targetQGVArea()).width(); - auto animation = new WaveAnimation(mQGV, w / 20, 3000); - animation->setLoopCount(-1); - return animation; -} - -QGV::GeoRect UtilitiesDemo::target10000Area() const -{ - return geoMap()->getProjection()->boundaryGeoRect(); -} - -QGVLayer* UtilitiesDemo::create10000Layer() -{ - /* - * Layers will be owned by map. - */ - auto target = target10000Area(); - auto layer = new QGVLayer(); - layer->setName("10000 elements"); - layer->setDescription("Demo for 10000 elements"); - geoMap()->addItem(layer); - /* - * Items will be owned by layer. - */ - const int radius = 30000; - for (int i = 0; i < 10000; i++) { - auto ellipse = new Ellipse(randRect(target, QSizeF(radius, radius)), Qt::red); - layer->addItem(ellipse); - } - return layer; -} - -void UtilitiesDemo::showQGV(bool selected) -{ - mQGV->setVisible(selected); - if (selected) { - geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetQGVArea())); - } -} - -void UtilitiesDemo::animationQGV(bool selected) -{ - if (selected) { - mQGVAnimation->start(); - } else { - mQGVAnimation->stop(); - } -} - -void UtilitiesDemo::show10000(bool selected) -{ - m10000->setVisible(selected); - if (selected) { - geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(target10000Area())); - } -} - -void UtilitiesDemo::drawDebug(bool selected) -{ - QGV::setDrawDebug(selected); - geoMap()->refreshMap(); -} - -void UtilitiesDemo::printDebug(bool selected) -{ - QGV::setPrintDebug(selected); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "utilities.h" +#include "ellipse.h" +#include "placemark.h" +#include "waveanimation.h" + +#include + +UtilitiesDemo::UtilitiesDemo(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Multi, parent) +{} + +QString UtilitiesDemo::label() const +{ + return "Utilities"; +} + +QString UtilitiesDemo::comment() const +{ + return "A set of additional features and demos."; +} + +void UtilitiesDemo::onInit() +{ + /* + * Layers owned by map. + */ + mQGV = createQGVLayer(); + m10000 = create10000Layer(); + mQGVAnimation.reset(createQGVAnimation()); + + selector()->addItem("QGV", std::bind(&UtilitiesDemo::showQGV, this, std::placeholders::_1)); + selector()->addItem("QGV animation", std::bind(&UtilitiesDemo::animationQGV, this, std::placeholders::_1)); + selector()->addItem("10000 elements", std::bind(&UtilitiesDemo::show10000, this, std::placeholders::_1)); + selector()->addItem("Draw debug", std::bind(&UtilitiesDemo::drawDebug, this, std::placeholders::_1)); + selector()->addItem("Print debug(log)", std::bind(&UtilitiesDemo::printDebug, this, std::placeholders::_1)); +} + +void UtilitiesDemo::onStart() +{ + selector()->show(); +} + +void UtilitiesDemo::onEnd() +{ + selector()->hide(); +} + +QGV::GeoRect UtilitiesDemo::targetQGVArea() const +{ + return QGV::GeoRect(QGV::GeoPos(55.096754, 82.682533), QGV::GeoPos(54.862608, 83.138179)); +} + +QPixmap UtilitiesDemo::createQGVImage() +{ + const auto target = QSize(150, 150); + const auto path = QGV::createTextPath(QRect(QPoint(0, 0), target), "QGeoView", QFont(), 1); + QImage image(target, QImage::Format_ARGB32_Premultiplied); + image.fill(qRgba(0, 0, 0, 0)); + QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); + QPainter painter(&pixmap); + QPen pen = QPen(Qt::black); + pen.setWidth(1); + pen.setCosmetic(true); + painter.setPen(pen); + QBrush brush = QBrush(Qt::black); + painter.setBrush(brush); + painter.drawPath(path); + return pixmap; +} + +QGVLayer* UtilitiesDemo::createQGVLayer() +{ + const auto target = targetQGVArea(); + const auto sizeLon = target.lonLeft() - target.lonRigth(); + const auto sizeLat = target.latTop() - target.latBottom(); + /* + * Layers owned by map. + */ + auto layer = new QGVLayer(); + layer->setName("QGV"); + layer->setDescription("Demo for QGV"); + geoMap()->addItem(layer); + /* + * Items will be owned by layer. + */ + QImage image = createQGVImage().toImage(); + for (int x = 0; x < image.width(); x++) { + for (int y = 0; y < image.height(); y++) { + if (image.pixelColor(x, y) != Qt::black) + continue; + double xScale = (double)x / image.width(); + double yScale = (double)y / image.height(); + QGV::GeoPos geoPos = QGV::GeoPos(target.latTop() - sizeLat * yScale, target.lonLeft() - sizeLon * xScale); + auto image = new Placemark(geoPos); + layer->addItem(image); + } + } + + qInfo() << layer->countItems() << "items in QGV demo layer"; + return layer; +} + +QAbstractAnimation* UtilitiesDemo::createQGVAnimation() +{ + const double w = geoMap()->getProjection()->geoToProj(targetQGVArea()).width(); + auto animation = new WaveAnimation(mQGV, w / 20, 3000); + animation->setLoopCount(-1); + return animation; +} + +QGV::GeoRect UtilitiesDemo::target10000Area() const +{ + return geoMap()->getProjection()->boundaryGeoRect(); +} + +QGVLayer* UtilitiesDemo::create10000Layer() +{ + /* + * Layers will be owned by map. + */ + auto target = target10000Area(); + auto layer = new QGVLayer(); + layer->setName("10000 elements"); + layer->setDescription("Demo for 10000 elements"); + geoMap()->addItem(layer); + /* + * Items will be owned by layer. + */ + const int radius = 30000; + for (int i = 0; i < 10000; i++) { + auto ellipse = new Ellipse(randRect(target, QSizeF(radius, radius)), Qt::red); + layer->addItem(ellipse); + } + return layer; +} + +void UtilitiesDemo::showQGV(bool selected) +{ + mQGV->setVisible(selected); + if (selected) { + geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(targetQGVArea())); + } +} + +void UtilitiesDemo::animationQGV(bool selected) +{ + if (selected) { + mQGVAnimation->start(); + } else { + mQGVAnimation->stop(); + } +} + +void UtilitiesDemo::show10000(bool selected) +{ + m10000->setVisible(selected); + if (selected) { + geoMap()->flyTo(QGVCameraActions(geoMap()).scaleTo(target10000Area())); + } +} + +void UtilitiesDemo::drawDebug(bool selected) +{ + QGV::setDrawDebug(selected); + geoMap()->refreshMap(); +} + +void UtilitiesDemo::printDebug(bool selected) +{ + QGV::setPrintDebug(selected); +} diff --git a/demo/samples/utilities.h b/demo/samples/utilities.h index c30fd51..c46af47 100644 --- a/demo/samples/utilities.h +++ b/demo/samples/utilities.h @@ -1,58 +1,58 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -#include -#include - -class UtilitiesDemo : public DemoItem -{ - Q_OBJECT - -public: - explicit UtilitiesDemo(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - - QGV::GeoRect targetQGVArea() const; - QPixmap createQGVImage(); - QGVLayer* createQGVLayer(); - QAbstractAnimation* createQGVAnimation(); - QGV::GeoRect target10000Area() const; - QGVLayer* create10000Layer(); - - void showQGV(bool selected); - void animationQGV(bool selected); - void show10000(bool selected); - void drawDebug(bool selected); - void printDebug(bool selected); - -private: - QGVLayer* mQGV; - QGVLayer* m10000; - QScopedPointer mQGVAnimation; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +#include +#include + +class UtilitiesDemo : public DemoItem +{ + Q_OBJECT + +public: + explicit UtilitiesDemo(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + + QGV::GeoRect targetQGVArea() const; + QPixmap createQGVImage(); + QGVLayer* createQGVLayer(); + QAbstractAnimation* createQGVAnimation(); + QGV::GeoRect target10000Area() const; + QGVLayer* create10000Layer(); + + void showQGV(bool selected); + void animationQGV(bool selected); + void show10000(bool selected); + void drawDebug(bool selected); + void printDebug(bool selected); + +private: + QGVLayer* mQGV; + QGVLayer* m10000; + QScopedPointer mQGVAnimation; +}; diff --git a/demo/samples/waveanimation.cpp b/demo/samples/waveanimation.cpp index 0777ec1..cb3784c 100644 --- a/demo/samples/waveanimation.cpp +++ b/demo/samples/waveanimation.cpp @@ -1,83 +1,83 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "waveanimation.h" - -WaveAnimation::WaveAnimation(QGVLayer* layer, double waveWidth, int msecs) - : mLayer(layer) - , mWaveWidth(waveWidth) - , mDuration(msecs) -{ - prepareWaves(); -} - -int WaveAnimation::duration() const -{ - return mDuration; -} - -void WaveAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) -{ - if (newState == QAbstractAnimation::Running && oldState == QAbstractAnimation::Stopped) { - mCurrentWave = 0; - } - if (newState == QAbstractAnimation::Stopped && oldState != QAbstractAnimation::Stopped) { - showWave(mCurrentWave, false); - } -} - -void WaveAnimation::updateCurrentTime(int currentTime) -{ - double progress = static_cast(currentTime) / duration(); - if (direction() == Direction::Backward) { - progress = 1.0 - progress; - } - const int newWave = static_cast(progress * mWaves.length()); - if (newWave == mCurrentWave) { - return; - } - showWave(mCurrentWave, false); - mCurrentWave = newWave; - showWave(mCurrentWave, true); -} - -void WaveAnimation::prepareWaves() -{ - QMap> waves; - for (int index = 0; index < mLayer->countItems(); index++) { - auto* drawItem = dynamic_cast(mLayer->getItem(index)); - if (drawItem == nullptr) { - continue; - } - const double x = drawItem->projShape().boundingRect().center().x(); - const int wave = static_cast(x / mWaveWidth); - waves[wave].append(drawItem); - } - mWaves = waves.values(); - mCurrentWave = 0; -} - -void WaveAnimation::showWave(int num, bool show) -{ - if (num >= mWaves.size()) { - return; - } - for (QGVDrawItem* drawItem : mWaves[num]) { - drawItem->setFlag(QGV::ItemFlag::Highlighted, show); - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "waveanimation.h" + +WaveAnimation::WaveAnimation(QGVLayer* layer, double waveWidth, int msecs) + : mLayer(layer) + , mWaveWidth(waveWidth) + , mDuration(msecs) +{ + prepareWaves(); +} + +int WaveAnimation::duration() const +{ + return mDuration; +} + +void WaveAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + if (newState == QAbstractAnimation::Running && oldState == QAbstractAnimation::Stopped) { + mCurrentWave = 0; + } + if (newState == QAbstractAnimation::Stopped && oldState != QAbstractAnimation::Stopped) { + showWave(mCurrentWave, false); + } +} + +void WaveAnimation::updateCurrentTime(int currentTime) +{ + double progress = static_cast(currentTime) / duration(); + if (direction() == Direction::Backward) { + progress = 1.0 - progress; + } + const int newWave = static_cast(progress * mWaves.length()); + if (newWave == mCurrentWave) { + return; + } + showWave(mCurrentWave, false); + mCurrentWave = newWave; + showWave(mCurrentWave, true); +} + +void WaveAnimation::prepareWaves() +{ + QMap> waves; + for (int index = 0; index < mLayer->countItems(); index++) { + auto* drawItem = dynamic_cast(mLayer->getItem(index)); + if (drawItem == nullptr) { + continue; + } + const double x = drawItem->projShape().boundingRect().center().x(); + const int wave = static_cast(x / mWaveWidth); + waves[wave].append(drawItem); + } + mWaves = waves.values(); + mCurrentWave = 0; +} + +void WaveAnimation::showWave(int num, bool show) +{ + if (num >= mWaves.size()) { + return; + } + for (QGVDrawItem* drawItem : mWaves[num]) { + drawItem->setFlag(QGV::ItemFlag::Highlighted, show); + } +} diff --git a/demo/samples/waveanimation.h b/demo/samples/waveanimation.h index a644e24..7c67afb 100644 --- a/demo/samples/waveanimation.h +++ b/demo/samples/waveanimation.h @@ -1,43 +1,43 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include -#include -#include - -class WaveAnimation : public QAbstractAnimation -{ -public: - explicit WaveAnimation(QGVLayer* layer, double waveWidth, int msecs); - -private: - int duration() const override; - void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) override; - void updateCurrentTime(int currentTime) override; - void prepareWaves(); - void showWave(int num, bool show); - -private: - QGVLayer* mLayer; - double mWaveWidth; - int mDuration; - QList> mWaves; - int mCurrentWave; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include +#include +#include + +class WaveAnimation : public QAbstractAnimation +{ +public: + explicit WaveAnimation(QGVLayer* layer, double waveWidth, int msecs); + +private: + int duration() const override; + void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) override; + void updateCurrentTime(int currentTime) override; + void prepareWaves(); + void showWave(int num, bool show); + +private: + QGVLayer* mLayer; + double mWaveWidth; + int mDuration; + QList> mWaves; + int mCurrentWave; +}; diff --git a/demo/samples/widgets.cpp b/demo/samples/widgets.cpp index f757dd7..d611d05 100644 --- a/demo/samples/widgets.cpp +++ b/demo/samples/widgets.cpp @@ -1,83 +1,82 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "widgets.h" - -#include -#include -#include -#include - -WidgetsDemo::WidgetsDemo(QGVMap* geoMap, QObject* parent) - : DemoItem(geoMap, SelectorDialog::Multi, parent) -{ -} - -QString WidgetsDemo::label() const -{ - return "Widgets"; -} - -QString WidgetsDemo::comment() const -{ - return "QGV supports standard map widgets. This includes:
" - "- Compass
" - "- Zoom buttons
" - "- Scale metrics
"; -} - -void WidgetsDemo::onInit() -{ - /* - * List of available widgets. - */ - QList> widgets = { - { "Compass", new QGVWidgetCompass() }, - { "ZoomButtons", new QGVWidgetZoom() }, - { "ScaleHorizontal", new QGVWidgetScale(Qt::Horizontal) }, - { "ScaleVertical", new QGVWidgetScale(Qt::Vertical) }, - }; - /* - * Widgets will be owned by map. - */ - for (auto pair : widgets) { - auto name = pair.first; - auto widget = pair.second; - geoMap()->addWidget(widget); - selector()->addItem(name, std::bind(&WidgetsDemo::setSelected, this, widget, std::placeholders::_1)); - } - selector()->selectAll(); -} - -void WidgetsDemo::onStart() -{ - selector()->show(); -} - -void WidgetsDemo::onEnd() -{ - selector()->hide(); -} - -void WidgetsDemo::setSelected(QGVWidget* widget, bool selected) -{ - if (widget == nullptr) { - return; - } - widget->setVisible(selected); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "widgets.h" + +#include +#include +#include +#include + +WidgetsDemo::WidgetsDemo(QGVMap* geoMap, QObject* parent) + : DemoItem(geoMap, SelectorDialog::Multi, parent) +{} + +QString WidgetsDemo::label() const +{ + return "Widgets"; +} + +QString WidgetsDemo::comment() const +{ + return "QGV supports standard map widgets. This includes:
" + "- Compass
" + "- Zoom buttons
" + "- Scale metrics
"; +} + +void WidgetsDemo::onInit() +{ + /* + * List of available widgets. + */ + QList> widgets = { + { "Compass", new QGVWidgetCompass() }, + { "ZoomButtons", new QGVWidgetZoom() }, + { "ScaleHorizontal", new QGVWidgetScale(Qt::Horizontal) }, + { "ScaleVertical", new QGVWidgetScale(Qt::Vertical) }, + }; + /* + * Widgets will be owned by map. + */ + for (auto pair : widgets) { + auto name = pair.first; + auto widget = pair.second; + geoMap()->addWidget(widget); + selector()->addItem(name, std::bind(&WidgetsDemo::setSelected, this, widget, std::placeholders::_1)); + } + selector()->selectAll(); +} + +void WidgetsDemo::onStart() +{ + selector()->show(); +} + +void WidgetsDemo::onEnd() +{ + selector()->hide(); +} + +void WidgetsDemo::setSelected(QGVWidget* widget, bool selected) +{ + if (widget == nullptr) { + return; + } + widget->setVisible(selected); +} diff --git a/demo/samples/widgets.h b/demo/samples/widgets.h index 9012dad..615c75e 100644 --- a/demo/samples/widgets.h +++ b/demo/samples/widgets.h @@ -1,38 +1,38 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "demoitem.h" - -class WidgetsDemo : public DemoItem -{ - Q_OBJECT - -public: - explicit WidgetsDemo(QGVMap* geoMap, QObject* parent = 0); - - QString label() const override; - QString comment() const override; - -private: - void onInit() override; - void onStart() override; - void onEnd() override; - void setSelected(QGVWidget* widget, bool selected); -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "demoitem.h" + +class WidgetsDemo : public DemoItem +{ + Q_OBJECT + +public: + explicit WidgetsDemo(QGVMap* geoMap, QObject* parent = 0); + + QString label() const override; + QString comment() const override; + +private: + void onInit() override; + void onStart() override; + void onEnd() override; + void setSelected(QGVWidget* widget, bool selected); +}; diff --git a/demo/selectordialog.cpp b/demo/selectordialog.cpp index ce2f05b..e67c81a 100644 --- a/demo/selectordialog.cpp +++ b/demo/selectordialog.cpp @@ -1,99 +1,99 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "selectordialog.h" - -SelectorDialog::SelectorDialog(Type type, QObject* parent) - : QObject(parent) -{ - mSelector.reset(new QListWidget()); - mType = type; - connect(mSelector.data(), &QListWidget::itemChanged, this, &SelectorDialog::onItemChanged); -} - -int SelectorDialog::addItem(const QString& name, FeatureFunc func) -{ - QListWidgetItem* item = new QListWidgetItem(mSelector.data()); - item->setText(name); - item->setToolTip(name); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(Qt::Unchecked); - item->setData(Qt::UserRole, QVariant::fromValue(func)); - return mSelector->row(item); -} - -QString SelectorDialog::name(int idx) const -{ - return mSelector->item(idx)->text(); -} - -void SelectorDialog::select(int idx) -{ - QListWidgetItem* target = mSelector->item(idx); - if (mType == Single) { - for (int i = 0; i < mSelector->count(); i++) { - auto item = mSelector->item(i); - if (i != idx) { - item->setCheckState(Qt::Unchecked); - } - } - } - target->setCheckState(Qt::Checked); -} - -void SelectorDialog::selectAll() -{ - for (int i = 0; i < mSelector->count(); i++) { - select(i); - } -} - -void SelectorDialog::unselect(int idx) -{ - QListWidgetItem* target = mSelector->item(idx); - target->setCheckState(Qt::Unchecked); -} - -void SelectorDialog::unselectAll() -{ - for (int i = 0; i < mSelector->count(); i++) { - unselect(i); - } -} - -void SelectorDialog::show() -{ - mSelector->show(); -} - -void SelectorDialog::hide() -{ - mSelector->hide(); -} - -void SelectorDialog::onItemChanged(QListWidgetItem* item) -{ - int idx = mSelector->row(item); - if (item->checkState() == Qt::Checked) { - select(idx); - } - auto func = item->data(Qt::UserRole).value(); - if (func) { - func(item->checkState() == Qt::Checked); - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "selectordialog.h" + +SelectorDialog::SelectorDialog(Type type, QObject* parent) + : QObject(parent) +{ + mSelector.reset(new QListWidget()); + mType = type; + connect(mSelector.data(), &QListWidget::itemChanged, this, &SelectorDialog::onItemChanged); +} + +int SelectorDialog::addItem(const QString& name, FeatureFunc func) +{ + QListWidgetItem* item = new QListWidgetItem(mSelector.data()); + item->setText(name); + item->setToolTip(name); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(Qt::Unchecked); + item->setData(Qt::UserRole, QVariant::fromValue(func)); + return mSelector->row(item); +} + +QString SelectorDialog::name(int idx) const +{ + return mSelector->item(idx)->text(); +} + +void SelectorDialog::select(int idx) +{ + QListWidgetItem* target = mSelector->item(idx); + if (mType == Single) { + for (int i = 0; i < mSelector->count(); i++) { + auto item = mSelector->item(i); + if (i != idx) { + item->setCheckState(Qt::Unchecked); + } + } + } + target->setCheckState(Qt::Checked); +} + +void SelectorDialog::selectAll() +{ + for (int i = 0; i < mSelector->count(); i++) { + select(i); + } +} + +void SelectorDialog::unselect(int idx) +{ + QListWidgetItem* target = mSelector->item(idx); + target->setCheckState(Qt::Unchecked); +} + +void SelectorDialog::unselectAll() +{ + for (int i = 0; i < mSelector->count(); i++) { + unselect(i); + } +} + +void SelectorDialog::show() +{ + mSelector->show(); +} + +void SelectorDialog::hide() +{ + mSelector->hide(); +} + +void SelectorDialog::onItemChanged(QListWidgetItem* item) +{ + int idx = mSelector->row(item); + if (item->checkState() == Qt::Checked) { + select(idx); + } + auto func = item->data(Qt::UserRole).value(); + if (func) { + func(item->checkState() == Qt::Checked); + } +} diff --git a/demo/selectordialog.h b/demo/selectordialog.h index 24233cb..fb10d1c 100644 --- a/demo/selectordialog.h +++ b/demo/selectordialog.h @@ -1,57 +1,57 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include -#include -#include - -using FeatureFunc = std::function; -Q_DECLARE_METATYPE(FeatureFunc); - -class SelectorDialog : public QObject -{ - Q_OBJECT - -public: - enum Type - { - Single, - Multi - }; - explicit SelectorDialog(Type type, QObject* parent = 0); - - int addItem(const QString& name, FeatureFunc func); - QString name(int idx) const; - - void select(int idx); - void selectAll(); - void unselect(int idx); - void unselectAll(); - - void show(); - void hide(); - -private Q_SLOTS: - void onItemChanged(QListWidgetItem* item); - -private: - QScopedPointer mSelector; - Type mType; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include +#include +#include + +using FeatureFunc = std::function; +Q_DECLARE_METATYPE(FeatureFunc); + +class SelectorDialog : public QObject +{ + Q_OBJECT + +public: + enum Type + { + Single, + Multi + }; + explicit SelectorDialog(Type type, QObject* parent = 0); + + int addItem(const QString& name, FeatureFunc func); + QString name(int idx) const; + + void select(int idx); + void selectAll(); + void unselect(int idx); + void unselectAll(); + + void show(); + void hide(); + +private Q_SLOTS: + void onItemChanged(QListWidgetItem* item); + +private: + QScopedPointer mSelector; + Type mType; +}; diff --git a/lib/include/QGeoView/QGVCamera.h b/lib/include/QGeoView/QGVCamera.h index c4c3a4e..bd00e74 100644 --- a/lib/include/QGeoView/QGVCamera.h +++ b/lib/include/QGeoView/QGVCamera.h @@ -1,143 +1,143 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVGlobal.h" - -#include -#include - -class QGVMap; -class QGVProjection; - -class QGV_LIB_DECL QGVCameraState -{ -public: - explicit QGVCameraState(QGVMap* geoMap, double azimuth, double scale, const QRectF& projRect, bool animation); - QGVCameraState(const QGVCameraState& other); - QGVCameraState(const QGVCameraState&& other); - QGVCameraState& operator=(const QGVCameraState& other); - QGVCameraState& operator=(const QGVCameraState&& other); - - QGVMap* getMap() const; - QGVProjection* getProjection() const; - - double scale() const; - double azimuth() const; - QRectF projRect() const; - QPointF projCenter() const; - bool animation() const; - - bool operator==(const QGVCameraState& other) const; - bool operator!=(const QGVCameraState& other) const; - -private: - QGVMap* mGeoMap; - double mScale; - double mAzimuth; - QRectF mProjRect; - bool mAnimation; -}; - -class QGV_LIB_DECL QGVCameraActions -{ -public: - explicit QGVCameraActions(QGVMap* geoMap); - explicit QGVCameraActions(const QGVCameraActions& other); - - const QGVCameraState& origin() const; - - QGVCameraActions& rebase(const QGVCameraState& origin); - QGVCameraActions& reset(); - QGVCameraActions& reset(const QGVCameraState& origin); - QGVCameraActions& scaleBy(double factor); - QGVCameraActions& scaleTo(double scale); - QGVCameraActions& scaleTo(const QRectF& projRect); - QGVCameraActions& scaleTo(const QGV::GeoRect& geoRect); - QGVCameraActions& rotateBy(double angle); - QGVCameraActions& rotateTo(double azimuth); - QGVCameraActions& moveTo(const QPointF& projPos); - QGVCameraActions& moveTo(const QGV::GeoPos& geoPos); - - double scale() const; - double azimuth() const; - QPointF projCenter() const; - -private: - QGVCameraState mOrigin; - double mScale; - double mAzimuth; - QPointF mProjCenter; -}; - -class QGV_LIB_DECL QGVCameraAnimation : public QAbstractAnimation -{ -public: - explicit QGVCameraAnimation(const QGVCameraActions& actions, QObject* parent = nullptr); - - void setDuration(int msecs); - int duration() const override; - QGVCameraActions& actions(); - -protected: - virtual void onStart(); - virtual void onStop(); - virtual void onProgress(double progress, QGVCameraActions& target) = 0; - - static double interpolateScale(double from, double to, double progress); - static double interpolateAzimuth(double from, double to, double progress); - static QPointF interpolatePos(QPointF from, QPointF to, double progress); - -private: - void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) override; - void updateCurrentTime(int currentTime) override; - void onStateChanged(QGV::MapState state); - -private: - int mDuration; - QGVCameraActions mActions; -}; - -class QGV_LIB_DECL QGVCameraSimpleAnimation : public QGVCameraAnimation -{ -public: - explicit QGVCameraSimpleAnimation(const QGVCameraActions& actions, QObject* parent = nullptr); - - void setEasingCurve(const QEasingCurve& easing); - -private: - void onProgress(double progress, QGVCameraActions& target) override; - -private: - QEasingCurve mEasing; -}; - -class QGV_LIB_DECL QGVCameraFlyAnimation : public QGVCameraAnimation -{ -public: - explicit QGVCameraFlyAnimation(const QGVCameraActions& actions, QObject* parent = nullptr); - -private: - void onStart() override; - void onProgress(double progress, QGVCameraActions& target) override; - -private: - double mFlyScale; - QPointF mFlyAnchor; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVGlobal.h" + +#include +#include + +class QGVMap; +class QGVProjection; + +class QGV_LIB_DECL QGVCameraState +{ +public: + explicit QGVCameraState(QGVMap* geoMap, double azimuth, double scale, const QRectF& projRect, bool animation); + QGVCameraState(const QGVCameraState& other); + QGVCameraState(const QGVCameraState&& other); + QGVCameraState& operator=(const QGVCameraState& other); + QGVCameraState& operator=(const QGVCameraState&& other); + + QGVMap* getMap() const; + QGVProjection* getProjection() const; + + double scale() const; + double azimuth() const; + QRectF projRect() const; + QPointF projCenter() const; + bool animation() const; + + bool operator==(const QGVCameraState& other) const; + bool operator!=(const QGVCameraState& other) const; + +private: + QGVMap* mGeoMap; + double mScale; + double mAzimuth; + QRectF mProjRect; + bool mAnimation; +}; + +class QGV_LIB_DECL QGVCameraActions +{ +public: + explicit QGVCameraActions(QGVMap* geoMap); + explicit QGVCameraActions(const QGVCameraActions& other); + + const QGVCameraState& origin() const; + + QGVCameraActions& rebase(const QGVCameraState& origin); + QGVCameraActions& reset(); + QGVCameraActions& reset(const QGVCameraState& origin); + QGVCameraActions& scaleBy(double factor); + QGVCameraActions& scaleTo(double scale); + QGVCameraActions& scaleTo(const QRectF& projRect); + QGVCameraActions& scaleTo(const QGV::GeoRect& geoRect); + QGVCameraActions& rotateBy(double angle); + QGVCameraActions& rotateTo(double azimuth); + QGVCameraActions& moveTo(const QPointF& projPos); + QGVCameraActions& moveTo(const QGV::GeoPos& geoPos); + + double scale() const; + double azimuth() const; + QPointF projCenter() const; + +private: + QGVCameraState mOrigin; + double mScale; + double mAzimuth; + QPointF mProjCenter; +}; + +class QGV_LIB_DECL QGVCameraAnimation : public QAbstractAnimation +{ +public: + explicit QGVCameraAnimation(const QGVCameraActions& actions, QObject* parent = nullptr); + + void setDuration(int msecs); + int duration() const override; + QGVCameraActions& actions(); + +protected: + virtual void onStart(); + virtual void onStop(); + virtual void onProgress(double progress, QGVCameraActions& target) = 0; + + static double interpolateScale(double from, double to, double progress); + static double interpolateAzimuth(double from, double to, double progress); + static QPointF interpolatePos(QPointF from, QPointF to, double progress); + +private: + void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) override; + void updateCurrentTime(int currentTime) override; + void onStateChanged(QGV::MapState state); + +private: + int mDuration; + QGVCameraActions mActions; +}; + +class QGV_LIB_DECL QGVCameraSimpleAnimation : public QGVCameraAnimation +{ +public: + explicit QGVCameraSimpleAnimation(const QGVCameraActions& actions, QObject* parent = nullptr); + + void setEasingCurve(const QEasingCurve& easing); + +private: + void onProgress(double progress, QGVCameraActions& target) override; + +private: + QEasingCurve mEasing; +}; + +class QGV_LIB_DECL QGVCameraFlyAnimation : public QGVCameraAnimation +{ +public: + explicit QGVCameraFlyAnimation(const QGVCameraActions& actions, QObject* parent = nullptr); + +private: + void onStart() override; + void onProgress(double progress, QGVCameraActions& target) override; + +private: + double mFlyScale; + QPointF mFlyAnchor; +}; diff --git a/lib/include/QGeoView/QGVDrawItem.h b/lib/include/QGeoView/QGVDrawItem.h index 752f76c..8740c66 100644 --- a/lib/include/QGeoView/QGVDrawItem.h +++ b/lib/include/QGeoView/QGVDrawItem.h @@ -1,63 +1,63 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVGlobal.h" -#include "QGVItem.h" -#include "QGVMap.h" -#include "QGVMapQGItem.h" - -class QGV_LIB_DECL QGVDrawItem : public QGVItem -{ - Q_OBJECT - Q_PROPERTY(QGV::ItemFlags flags READ getFlags WRITE setFlags) - -public: - QGVDrawItem(); - - void setFlags(QGV::ItemFlags flags); - void setFlag(QGV::ItemFlag flag, bool enabled = true); - QGV::ItemFlags getFlags() const; - bool isFlag(QGV::ItemFlag flag) const; - - void refresh(); - void repaint(); - void resetBoundary(); - QTransform effectiveTransform() const; - - virtual QPainterPath projShape() const = 0; - virtual void projPaint(QPainter* painter) = 0; - virtual QPointF projAnchor() const; - virtual QTransform projTransform() const; - virtual QString projTooltip(const QPointF& projPos) const; - virtual QString projDebug(); - virtual void projOnFlags(); - virtual void projOnMouseClick(const QPointF& projPos); - virtual void projOnMouseDoubleClick(const QPointF& projPos); - -protected: - void onProjection(QGVMap* geoMap) override; - void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; - void onUpdate() override; - void onClean() override; - -private: - QGV::ItemFlags mFlags; - QScopedPointer mQGDrawItem; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVGlobal.h" +#include "QGVItem.h" +#include "QGVMap.h" +#include "QGVMapQGItem.h" + +class QGV_LIB_DECL QGVDrawItem : public QGVItem +{ + Q_OBJECT + Q_PROPERTY(QGV::ItemFlags flags READ getFlags WRITE setFlags) + +public: + QGVDrawItem(); + + void setFlags(QGV::ItemFlags flags); + void setFlag(QGV::ItemFlag flag, bool enabled = true); + QGV::ItemFlags getFlags() const; + bool isFlag(QGV::ItemFlag flag) const; + + void refresh(); + void repaint(); + void resetBoundary(); + QTransform effectiveTransform() const; + + virtual QPainterPath projShape() const = 0; + virtual void projPaint(QPainter* painter) = 0; + virtual QPointF projAnchor() const; + virtual QTransform projTransform() const; + virtual QString projTooltip(const QPointF& projPos) const; + virtual QString projDebug(); + virtual void projOnFlags(); + virtual void projOnMouseClick(const QPointF& projPos); + virtual void projOnMouseDoubleClick(const QPointF& projPos); + +protected: + void onProjection(QGVMap* geoMap) override; + void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; + void onUpdate() override; + void onClean() override; + +private: + QGV::ItemFlags mFlags; + QScopedPointer mQGDrawItem; +}; diff --git a/lib/include/QGeoView/QGVGlobal.h b/lib/include/QGeoView/QGVGlobal.h index 59fdfc0..fea18ba 100644 --- a/lib/include/QGeoView/QGVGlobal.h +++ b/lib/include/QGeoView/QGVGlobal.h @@ -1,199 +1,199 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include - -#if defined(QGV_EXPORT) -#define QGV_LIB_DECL Q_DECL_EXPORT -#else -#define QGV_LIB_DECL Q_DECL_IMPORT -#endif - -namespace QGV { - -enum class Projection -{ - EPSG3857, -}; - -enum class TilesType -{ - Satellite, - Schema, - Hybrid, -}; - -enum class MapState -{ - Idle, - Animation, - Wheel, - Moving, - SelectionRect, -}; - -enum class MouseAction : int -{ - Move = 0x1, - ZoomWheel = 0x2, - ZoomRect = 0x4, - Selection = 0x8, - Tooltip = 0x10, - ContextMenu = 0x20, - All = 0xFF, -}; -Q_DECLARE_FLAGS(MouseActions, MouseAction) - -enum class ItemFlag : int -{ - IgnoreScale = 0x1, - IgnoreAzimuth = 0x2, - Highlightable = 0x4, - Highlighted = 0x8, - HighlightCustom = 0x10, - SelectCustom = 0x20, - Transformed = 0x40, - Clickable = 0x80, -}; -Q_DECLARE_FLAGS(ItemFlags, ItemFlag) - -class QGV_LIB_DECL GeoPos -{ -public: - GeoPos(); - GeoPos(double lat, double lon); - GeoPos(const GeoPos& other); - GeoPos(const GeoPos&& other); - GeoPos& operator=(const GeoPos& other); - GeoPos& operator=(const GeoPos&& other); - - double latitude() const; - double longitude() const; - - void setLat(double late); - void setLon(double lon); - - QString lonToString(const QString& format = "[+-]d") const; - QString latToString(const QString& format = "[+-]d") const; - - static QString lonToString(double lon, const QString& format = "[+-]d"); - static QString latToString(double lat, const QString& format = "[+-]d"); - -private: - double mLat; - double mLon; -}; - -class QGV_LIB_DECL GeoRect -{ -public: - GeoRect(); - GeoRect(double lat1, double lon1, double lat2, double lon2); - GeoRect(GeoPos const& pos1, GeoPos const& pos2); - GeoRect(const GeoRect& other); - GeoRect(const GeoRect&& other); - GeoRect& operator=(const GeoRect& other); - GeoRect& operator=(const GeoRect&& other); - - GeoPos topLeft() const; - GeoPos topRight() const; - GeoPos bottomLeft() const; - GeoPos bottomRight() const; - double lonLeft() const; - double lonRigth() const; - double latBottom() const; - double latTop() const; - - bool contains(GeoPos const& pos) const; - bool contains(GeoRect const& rect) const; - bool intersects(GeoRect const& rect) const; - -private: - GeoPos mTopLeft; - GeoPos mBottomRight; -}; - -class QGV_LIB_DECL GeoTilePos -{ -public: - GeoTilePos(); - GeoTilePos(int zoom, const QPoint& pos); - GeoTilePos(const GeoTilePos& other); - GeoTilePos(const GeoTilePos&& other); - GeoTilePos& operator=(const GeoTilePos& other); - GeoTilePos& operator=(const GeoTilePos&& other); - - bool operator<(const GeoTilePos& other) const; - - int zoom() const; - QPoint pos() const; - - bool contains(const GeoTilePos& other) const; - GeoTilePos parent(int parentZoom) const; - - GeoRect toGeoRect() const; - QString toQuadKey() const; - - static GeoTilePos geoToTilePos(int zoom, const GeoPos& geoPos); - -private: - int mZoom; - QPoint mPos; -}; - -void setNetworkManager(QNetworkAccessManager* manager); -QNetworkAccessManager* getNetworkManager(); - -QTransform createTransfrom(QPointF const& projAnchor, double scale, double azimuth); -QTransform createTransfromScale(QPointF const& projAnchor, double scale); -QTransform createTransfromAzimuth(QPointF const& projAnchor, double azimuth); -QPainterPath createTextPath(const QRect& rect, const QString& text, const QFont& font, int penWidth); - -void setDrawDebug(bool enabled); -bool isDrawDebug(); -void setPrintDebug(bool enabled); -bool isPrintDebug(); - -} // namespace QGV - -QDebug operator<<(QDebug debug, const QGV::GeoPos& value); -QDebug operator<<(QDebug debug, const QGV::GeoRect& value); -QDebug operator<<(QDebug debug, const QGV::GeoTilePos& value); - -Q_DECLARE_METATYPE(QGV::GeoPos) -Q_DECLARE_METATYPE(QGV::GeoRect) -Q_DECLARE_METATYPE(QGV::GeoTilePos) - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGV::ItemFlags) - -#define qgvDebug \ - if (QGV::isPrintDebug()) \ - qDebug -#define qgvInfo \ - if (QGV::isPrintDebug()) \ - qInfo -#define qgvWarning \ - if (QGV::isPrintDebug()) \ - qWarning -#define qgvCritical qCritical +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include + +#if defined(QGV_EXPORT) +#define QGV_LIB_DECL Q_DECL_EXPORT +#else +#define QGV_LIB_DECL Q_DECL_IMPORT +#endif + +namespace QGV { + +enum class Projection +{ + EPSG3857, +}; + +enum class TilesType +{ + Satellite, + Schema, + Hybrid, +}; + +enum class MapState +{ + Idle, + Animation, + Wheel, + Moving, + SelectionRect, +}; + +enum class MouseAction : int +{ + Move = 0x1, + ZoomWheel = 0x2, + ZoomRect = 0x4, + Selection = 0x8, + Tooltip = 0x10, + ContextMenu = 0x20, + All = 0xFF, +}; +Q_DECLARE_FLAGS(MouseActions, MouseAction) + +enum class ItemFlag : int +{ + IgnoreScale = 0x1, + IgnoreAzimuth = 0x2, + Highlightable = 0x4, + Highlighted = 0x8, + HighlightCustom = 0x10, + SelectCustom = 0x20, + Transformed = 0x40, + Clickable = 0x80, +}; +Q_DECLARE_FLAGS(ItemFlags, ItemFlag) + +class QGV_LIB_DECL GeoPos +{ +public: + GeoPos(); + GeoPos(double lat, double lon); + GeoPos(const GeoPos& other); + GeoPos(const GeoPos&& other); + GeoPos& operator=(const GeoPos& other); + GeoPos& operator=(const GeoPos&& other); + + double latitude() const; + double longitude() const; + + void setLat(double late); + void setLon(double lon); + + QString lonToString(const QString& format = "[+-]d") const; + QString latToString(const QString& format = "[+-]d") const; + + static QString lonToString(double lon, const QString& format = "[+-]d"); + static QString latToString(double lat, const QString& format = "[+-]d"); + +private: + double mLat; + double mLon; +}; + +class QGV_LIB_DECL GeoRect +{ +public: + GeoRect(); + GeoRect(double lat1, double lon1, double lat2, double lon2); + GeoRect(GeoPos const& pos1, GeoPos const& pos2); + GeoRect(const GeoRect& other); + GeoRect(const GeoRect&& other); + GeoRect& operator=(const GeoRect& other); + GeoRect& operator=(const GeoRect&& other); + + GeoPos topLeft() const; + GeoPos topRight() const; + GeoPos bottomLeft() const; + GeoPos bottomRight() const; + double lonLeft() const; + double lonRigth() const; + double latBottom() const; + double latTop() const; + + bool contains(GeoPos const& pos) const; + bool contains(GeoRect const& rect) const; + bool intersects(GeoRect const& rect) const; + +private: + GeoPos mTopLeft; + GeoPos mBottomRight; +}; + +class QGV_LIB_DECL GeoTilePos +{ +public: + GeoTilePos(); + GeoTilePos(int zoom, const QPoint& pos); + GeoTilePos(const GeoTilePos& other); + GeoTilePos(const GeoTilePos&& other); + GeoTilePos& operator=(const GeoTilePos& other); + GeoTilePos& operator=(const GeoTilePos&& other); + + bool operator<(const GeoTilePos& other) const; + + int zoom() const; + QPoint pos() const; + + bool contains(const GeoTilePos& other) const; + GeoTilePos parent(int parentZoom) const; + + GeoRect toGeoRect() const; + QString toQuadKey() const; + + static GeoTilePos geoToTilePos(int zoom, const GeoPos& geoPos); + +private: + int mZoom; + QPoint mPos; +}; + +void setNetworkManager(QNetworkAccessManager* manager); +QNetworkAccessManager* getNetworkManager(); + +QTransform createTransfrom(QPointF const& projAnchor, double scale, double azimuth); +QTransform createTransfromScale(QPointF const& projAnchor, double scale); +QTransform createTransfromAzimuth(QPointF const& projAnchor, double azimuth); +QPainterPath createTextPath(const QRect& rect, const QString& text, const QFont& font, int penWidth); + +void setDrawDebug(bool enabled); +bool isDrawDebug(); +void setPrintDebug(bool enabled); +bool isPrintDebug(); + +} // namespace QGV + +QDebug operator<<(QDebug debug, const QGV::GeoPos& value); +QDebug operator<<(QDebug debug, const QGV::GeoRect& value); +QDebug operator<<(QDebug debug, const QGV::GeoTilePos& value); + +Q_DECLARE_METATYPE(QGV::GeoPos) +Q_DECLARE_METATYPE(QGV::GeoRect) +Q_DECLARE_METATYPE(QGV::GeoTilePos) + +Q_DECLARE_OPERATORS_FOR_FLAGS(QGV::ItemFlags) + +#define qgvDebug \ + if (QGV::isPrintDebug()) \ + qDebug +#define qgvInfo \ + if (QGV::isPrintDebug()) \ + qInfo +#define qgvWarning \ + if (QGV::isPrintDebug()) \ + qWarning +#define qgvCritical qCritical diff --git a/lib/include/QGeoView/QGVImage.h b/lib/include/QGeoView/QGVImage.h index ad346ca..89339b5 100644 --- a/lib/include/QGeoView/QGVImage.h +++ b/lib/include/QGeoView/QGVImage.h @@ -1,67 +1,67 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVDrawItem.h" -#include - -class QGV_LIB_DECL QGVImage : public QGVDrawItem -{ - Q_OBJECT - -public: - QGVImage(); - - void setGeometry(const QGV::GeoRect& geoRect); - void setGeometry(const QGV::GeoPos& geoPos, const QSize& imageSize = QSize(), const QPoint& imageAnchor = QPoint()); - - QImage getImage() const; - bool isImage() const; - - void load(const QString& url); - void loadImage(const QByteArray& rawData); - void loadImage(const QImage& image); - -protected: - void onProjection(QGVMap* geoMap) override; - QPainterPath projShape() const override; - QPointF projAnchor() const override; - void projPaint(QPainter* painter) override; - -private: - void onReplyFinished(); - void calculateGeometry(); - -private: - enum class GeometryType - { - None, - ByRect, - ByPos, - } mGeometryType; - QGV::GeoRect mGeoRect; - QGV::GeoPos mGeoPos; - QSize mImageSize; - QPoint mImageAnchor; - QRectF mProjRect; - QPointF mProjAnchor; - QString mUrl; - QImage mImage; - QScopedPointer mReply; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVDrawItem.h" +#include + +class QGV_LIB_DECL QGVImage : public QGVDrawItem +{ + Q_OBJECT + +public: + QGVImage(); + + void setGeometry(const QGV::GeoRect& geoRect); + void setGeometry(const QGV::GeoPos& geoPos, const QSize& imageSize = QSize(), const QPoint& imageAnchor = QPoint()); + + QImage getImage() const; + bool isImage() const; + + void load(const QString& url); + void loadImage(const QByteArray& rawData); + void loadImage(const QImage& image); + +protected: + void onProjection(QGVMap* geoMap) override; + QPainterPath projShape() const override; + QPointF projAnchor() const override; + void projPaint(QPainter* painter) override; + +private: + void onReplyFinished(); + void calculateGeometry(); + +private: + enum class GeometryType + { + None, + ByRect, + ByPos, + } mGeometryType; + QGV::GeoRect mGeoRect; + QGV::GeoPos mGeoPos; + QSize mImageSize; + QPoint mImageAnchor; + QRectF mProjRect; + QPointF mProjAnchor; + QString mUrl; + QImage mImage; + QScopedPointer mReply; +}; diff --git a/lib/include/QGeoView/QGVItem.h b/lib/include/QGeoView/QGVItem.h index 233c076..724ce8e 100644 --- a/lib/include/QGeoView/QGVItem.h +++ b/lib/include/QGeoView/QGVItem.h @@ -1,88 +1,88 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVGlobal.h" -#include "QGVMap.h" - -class QGV_LIB_DECL QGVItem : public QObject -{ - Q_OBJECT - Q_PROPERTY(quint16 zValue READ getZValue WRITE setZValue) - Q_PROPERTY(double opacity READ getOpacity WRITE setOpacity) - Q_PROPERTY(bool selected READ isSelected WRITE setSelected) - Q_PROPERTY(bool visible READ isVisible WRITE setVisible) - -public: - explicit QGVItem(QGVItem* parent = nullptr); - virtual ~QGVItem(); - - void setParent(QGVItem* item); - QGVItem* getParent() const; - - virtual QGVMap* getMap() const; - - void addItem(QGVItem* item); - void removeItem(QGVItem* item); - void deleteItems(); - int countItems() const; - QGVItem* getItem(int index) const; - - void setZValue(qint16 zValue); - qint16 getZValue() const; - void bringToFront(); - void sendToBack(); - - void setOpacity(double value); - double getOpacity() const; - - void setSelectable(bool allowed); - bool isSelectable() const; - void setSelected(bool selected); - bool isSelected() const; - void select(); - void unselect(); - - void setVisible(bool visible); - bool isVisible() const; - - void show(); - void hide(); - - double effectiveZValue() const; - double effectiveOpacity() const; - bool effectivelyVisible() const; - - void update(); - - virtual void onProjection(QGVMap* geoMap); - virtual void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState); - virtual void onUpdate(); - virtual void onClean(); - -private: - Q_DISABLE_COPY(QGVItem) - QGVItem* mParent; - qint16 mZValue; - double mOpacity; - bool mVisible; - bool mSelectable; - bool mSelected; - QList mChildrens; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVGlobal.h" +#include "QGVMap.h" + +class QGV_LIB_DECL QGVItem : public QObject +{ + Q_OBJECT + Q_PROPERTY(quint16 zValue READ getZValue WRITE setZValue) + Q_PROPERTY(double opacity READ getOpacity WRITE setOpacity) + Q_PROPERTY(bool selected READ isSelected WRITE setSelected) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible) + +public: + explicit QGVItem(QGVItem* parent = nullptr); + virtual ~QGVItem(); + + void setParent(QGVItem* item); + QGVItem* getParent() const; + + virtual QGVMap* getMap() const; + + void addItem(QGVItem* item); + void removeItem(QGVItem* item); + void deleteItems(); + int countItems() const; + QGVItem* getItem(int index) const; + + void setZValue(qint16 zValue); + qint16 getZValue() const; + void bringToFront(); + void sendToBack(); + + void setOpacity(double value); + double getOpacity() const; + + void setSelectable(bool allowed); + bool isSelectable() const; + void setSelected(bool selected); + bool isSelected() const; + void select(); + void unselect(); + + void setVisible(bool visible); + bool isVisible() const; + + void show(); + void hide(); + + double effectiveZValue() const; + double effectiveOpacity() const; + bool effectivelyVisible() const; + + void update(); + + virtual void onProjection(QGVMap* geoMap); + virtual void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState); + virtual void onUpdate(); + virtual void onClean(); + +private: + Q_DISABLE_COPY(QGVItem) + QGVItem* mParent; + qint16 mZValue; + double mOpacity; + bool mVisible; + bool mSelectable; + bool mSelected; + QList mChildrens; +}; diff --git a/lib/include/QGeoView/QGVLayer.h b/lib/include/QGeoView/QGVLayer.h index aa83097..fe42cd8 100644 --- a/lib/include/QGeoView/QGVLayer.h +++ b/lib/include/QGeoView/QGVLayer.h @@ -1,39 +1,39 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVItem.h" - -class QGV_LIB_DECL QGVLayer : public QGVItem -{ - Q_OBJECT - Q_PROPERTY(QString name READ getName WRITE setName) - Q_PROPERTY(QString description READ getDescription WRITE setDescription) - -public: - void setName(const QString& name); - QString getName() const; - - void setDescription(const QString& description); - QString getDescription() const; - -private: - QString mName; - QString mDescription; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVItem.h" + +class QGV_LIB_DECL QGVLayer : public QGVItem +{ + Q_OBJECT + Q_PROPERTY(QString name READ getName WRITE setName) + Q_PROPERTY(QString description READ getDescription WRITE setDescription) + +public: + void setName(const QString& name); + QString getName() const; + + void setDescription(const QString& description); + QString getDescription() const; + +private: + QString mName; + QString mDescription; +}; diff --git a/lib/include/QGeoView/QGVLayerBing.h b/lib/include/QGeoView/QGVLayerBing.h index f39675e..e32e702 100644 --- a/lib/include/QGeoView/QGVLayerBing.h +++ b/lib/include/QGeoView/QGVLayerBing.h @@ -1,48 +1,48 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVLayerTilesOnline.h" - -class QGV_LIB_DECL QGVLayerBing : public QGVLayerTilesOnline -{ - Q_OBJECT - -public: - explicit QGVLayerBing(QGV::TilesType type = QGV::TilesType::Schema, - QLocale locale = QLocale(), - int serverNumber = 0); - - void setType(QGV::TilesType type); - void setLocale(const QLocale& locale); - - QGV::TilesType getType() const; - QLocale getLocale() const; - -private: - void createName(); - int minZoomlevel() const override; - int maxZoomlevel() const override; - QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const override; - -private: - QGV::TilesType mType; - QLocale mLocale; - int mServerNumber; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVLayerTilesOnline.h" + +class QGV_LIB_DECL QGVLayerBing : public QGVLayerTilesOnline +{ + Q_OBJECT + +public: + explicit QGVLayerBing(QGV::TilesType type = QGV::TilesType::Schema, + QLocale locale = QLocale(), + int serverNumber = 0); + + void setType(QGV::TilesType type); + void setLocale(const QLocale& locale); + + QGV::TilesType getType() const; + QLocale getLocale() const; + +private: + void createName(); + int minZoomlevel() const override; + int maxZoomlevel() const override; + QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const override; + +private: + QGV::TilesType mType; + QLocale mLocale; + int mServerNumber; +}; diff --git a/lib/include/QGeoView/QGVLayerGoogle.h b/lib/include/QGeoView/QGVLayerGoogle.h index 1f6dd20..17a1415 100644 --- a/lib/include/QGeoView/QGVLayerGoogle.h +++ b/lib/include/QGeoView/QGVLayerGoogle.h @@ -1,48 +1,48 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVLayerTilesOnline.h" - -class QGV_LIB_DECL QGVLayerGoogle : public QGVLayerTilesOnline -{ - Q_OBJECT - -public: - explicit QGVLayerGoogle(QGV::TilesType type = QGV::TilesType::Schema, - QLocale locale = QLocale(), - int serverNumber = 0); - - void setType(QGV::TilesType type); - void setLocale(const QLocale& locale); - - QGV::TilesType getType() const; - QLocale getLocale() const; - -private: - void createName(); - int minZoomlevel() const override; - int maxZoomlevel() const override; - QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const override; - -private: - QGV::TilesType mType; - QLocale mLocale; - int mServerNumber; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVLayerTilesOnline.h" + +class QGV_LIB_DECL QGVLayerGoogle : public QGVLayerTilesOnline +{ + Q_OBJECT + +public: + explicit QGVLayerGoogle(QGV::TilesType type = QGV::TilesType::Schema, + QLocale locale = QLocale(), + int serverNumber = 0); + + void setType(QGV::TilesType type); + void setLocale(const QLocale& locale); + + QGV::TilesType getType() const; + QLocale getLocale() const; + +private: + void createName(); + int minZoomlevel() const override; + int maxZoomlevel() const override; + QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const override; + +private: + QGV::TilesType mType; + QLocale mLocale; + int mServerNumber; +}; diff --git a/lib/include/QGeoView/QGVLayerOSM.h b/lib/include/QGeoView/QGVLayerOSM.h index befc3db..989b025 100644 --- a/lib/include/QGeoView/QGVLayerOSM.h +++ b/lib/include/QGeoView/QGVLayerOSM.h @@ -1,41 +1,41 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVLayerTilesOnline.h" - -class QGV_LIB_DECL QGVLayerOSM : public QGVLayerTilesOnline -{ - Q_OBJECT - -public: - explicit QGVLayerOSM(int serverNumber = 0); - explicit QGVLayerOSM(const QString& url); - - void setUrl(const QString& url); - QString getUrl() const; - -private: - int minZoomlevel() const override; - int maxZoomlevel() const override; - QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const override; - -private: - QString mUrl; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVLayerTilesOnline.h" + +class QGV_LIB_DECL QGVLayerOSM : public QGVLayerTilesOnline +{ + Q_OBJECT + +public: + explicit QGVLayerOSM(int serverNumber = 0); + explicit QGVLayerOSM(const QString& url); + + void setUrl(const QString& url); + QString getUrl() const; + +private: + int minZoomlevel() const override; + int maxZoomlevel() const override; + QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const override; + +private: + QString mUrl; +}; diff --git a/lib/include/QGeoView/QGVLayerTiles.h b/lib/include/QGeoView/QGVLayerTiles.h index 58325e9..270fd83 100644 --- a/lib/include/QGeoView/QGVLayerTiles.h +++ b/lib/include/QGeoView/QGVLayerTiles.h @@ -1,60 +1,60 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVLayer.h" - -#include - -class QGV_LIB_DECL QGVLayerTiles : public QGVLayer -{ - Q_OBJECT - -public: - QGVLayerTiles(); - -protected: - void onProjection(QGVMap* geoMap) override; - void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; - void onUpdate() override; - void onClean() override; - void onTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj); - - virtual int minZoomlevel() const = 0; - virtual int maxZoomlevel() const = 0; - virtual int scaleToZoom(double scale) const; - virtual void request(const QGV::GeoTilePos& tilePos) = 0; - virtual void cancel(const QGV::GeoTilePos& tilePos) = 0; - -private: - void processCamera(); - void removeAllAbove(const QGV::GeoTilePos& tilePos); - void removeWhenCovered(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; - bool isTileFinished(const QGV::GeoTilePos& tilePos) const; - QList existingTiles(int zoom) const; - -private: - int mCurZoom; - QRect mCurRect; - QMap> mIndex; - QElapsedTimer mLastAnimation; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVLayer.h" + +#include + +class QGV_LIB_DECL QGVLayerTiles : public QGVLayer +{ + Q_OBJECT + +public: + QGVLayerTiles(); + +protected: + void onProjection(QGVMap* geoMap) override; + void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; + void onUpdate() override; + void onClean() override; + void onTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj); + + virtual int minZoomlevel() const = 0; + virtual int maxZoomlevel() const = 0; + virtual int scaleToZoom(double scale) const; + virtual void request(const QGV::GeoTilePos& tilePos) = 0; + virtual void cancel(const QGV::GeoTilePos& tilePos) = 0; + +private: + void processCamera(); + void removeAllAbove(const QGV::GeoTilePos& tilePos); + void removeWhenCovered(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; + bool isTileFinished(const QGV::GeoTilePos& tilePos) const; + QList existingTiles(int zoom) const; + +private: + int mCurZoom; + QRect mCurRect; + QMap> mIndex; + QElapsedTimer mLastAnimation; +}; diff --git a/lib/include/QGeoView/QGVLayerTilesOnline.h b/lib/include/QGeoView/QGVLayerTilesOnline.h index d1c3d15..4f8a495 100644 --- a/lib/include/QGeoView/QGVLayerTilesOnline.h +++ b/lib/include/QGeoView/QGVLayerTilesOnline.h @@ -1,45 +1,45 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVLayerTiles.h" - -#include - -class QGV_LIB_DECL QGVLayerTilesOnline : public QGVLayerTiles -{ - Q_OBJECT - -public: - ~QGVLayerTilesOnline(); - -protected: - virtual QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const = 0; - -private: - void onProjection(QGVMap* geoMap) override; - void onClean() override; - void request(const QGV::GeoTilePos& tilePos) override; - void cancel(const QGV::GeoTilePos& tilePos) override; - void onReplyFinished(QNetworkReply* reply); - void removeReply(const QGV::GeoTilePos& tilePos); - -private: - QMap mRequest; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVLayerTiles.h" + +#include + +class QGV_LIB_DECL QGVLayerTilesOnline : public QGVLayerTiles +{ + Q_OBJECT + +public: + ~QGVLayerTilesOnline(); + +protected: + virtual QString tilePosToUrl(const QGV::GeoTilePos& tilePos) const = 0; + +private: + void onProjection(QGVMap* geoMap) override; + void onClean() override; + void request(const QGV::GeoTilePos& tilePos) override; + void cancel(const QGV::GeoTilePos& tilePos) override; + void onReplyFinished(QNetworkReply* reply); + void removeReply(const QGV::GeoTilePos& tilePos); + +private: + QMap mRequest; +}; diff --git a/lib/include/QGeoView/QGVMap.h b/lib/include/QGeoView/QGVMap.h index 5a4c354..076ffcb 100644 --- a/lib/include/QGeoView/QGVMap.h +++ b/lib/include/QGeoView/QGVMap.h @@ -1,108 +1,108 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -#include "QGVCamera.h" -#include "QGVGlobal.h" -#include "QGVProjection.h" - -class QGVItem; -class QGVDrawItem; -class QGVWidget; -class QGVMapQGScene; -class QGVMapQGView; - -class QGV_LIB_DECL QGVMap : public QWidget -{ - Q_OBJECT - -public: - explicit QGVMap(QWidget* parent = 0); - ~QGVMap(); - - const QGVCameraState getCamera() const; - void cameraTo(const QGVCameraActions& actions, bool animation = false); - void flyTo(const QGVCameraActions& actions); - - void setProjection(QGV::Projection id); - void setProjection(QGVProjection* projection); - QGVProjection* getProjection() const; - - void setMouseActions(QGV::MouseActions actions); - void setMouseAction(QGV::MouseAction action, bool enabled = true); - QGV::MouseActions getMouseActions() const; - bool isMouseAction(QGV::MouseAction action) const; - - QGVItem* rootItem() const; - QGVMapQGView* geoView() const; - - void addItem(QGVItem* item); - void removeItem(QGVItem* item); - void deleteItems(); - int countItems() const; - QGVItem* getItem(int index) const; - - void addWidget(QGVWidget* widget); - void removeWidget(QGVWidget* widget); - void deleteWidgets(); - int countWidgets() const; - QGVWidget* getWigdet(int index) const; - - void select(QGVItem* item); - void unselect(QGVItem* item); - void unselectAll(); - QSet getSelections() const; - - QList search(const QPointF& projPos, Qt::ItemSelectionMode mode = Qt::ContainsItemShape) const; - QList search(const QRectF& projRect, Qt::ItemSelectionMode mode = Qt::ContainsItemShape) const; - QPixmap grabMapView(bool includeWidgets = true) const; - - QPointF mapToProj(QPoint pos); - QPoint mapFromProj(QPointF projPos); - - void refreshMap(); - void refreshProjection(); - void anchoreWidgets(); - - virtual void onMapState(QGV::MapState state); - virtual void onMapCamera(const QGVCameraState& oldState, const QGVCameraState& newState); - -protected: - void mouseMoveEvent(QMouseEvent* event) override; - -Q_SIGNALS: - void projectionChanged(); - void scaleChanged(); - void azimuthChanged(); - void areaChanged(); - void itemsChanged(QGVItem* parent); - void stateChanged(QGV::MapState state); - void itemClicked(QGVItem* item, QPointF projPos); - void itemDoubleClicked(QGVItem* item, QPointF projPos); - void mapMouseMove(QPointF projPos); - -private: - QScopedPointer mProjection; - QScopedPointer mQGView; - QScopedPointer mRootItem; - QList mWidgets; - QSet mSelections; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +#include "QGVCamera.h" +#include "QGVGlobal.h" +#include "QGVProjection.h" + +class QGVItem; +class QGVDrawItem; +class QGVWidget; +class QGVMapQGScene; +class QGVMapQGView; + +class QGV_LIB_DECL QGVMap : public QWidget +{ + Q_OBJECT + +public: + explicit QGVMap(QWidget* parent = 0); + ~QGVMap(); + + const QGVCameraState getCamera() const; + void cameraTo(const QGVCameraActions& actions, bool animation = false); + void flyTo(const QGVCameraActions& actions); + + void setProjection(QGV::Projection id); + void setProjection(QGVProjection* projection); + QGVProjection* getProjection() const; + + void setMouseActions(QGV::MouseActions actions); + void setMouseAction(QGV::MouseAction action, bool enabled = true); + QGV::MouseActions getMouseActions() const; + bool isMouseAction(QGV::MouseAction action) const; + + QGVItem* rootItem() const; + QGVMapQGView* geoView() const; + + void addItem(QGVItem* item); + void removeItem(QGVItem* item); + void deleteItems(); + int countItems() const; + QGVItem* getItem(int index) const; + + void addWidget(QGVWidget* widget); + void removeWidget(QGVWidget* widget); + void deleteWidgets(); + int countWidgets() const; + QGVWidget* getWigdet(int index) const; + + void select(QGVItem* item); + void unselect(QGVItem* item); + void unselectAll(); + QSet getSelections() const; + + QList search(const QPointF& projPos, Qt::ItemSelectionMode mode = Qt::ContainsItemShape) const; + QList search(const QRectF& projRect, Qt::ItemSelectionMode mode = Qt::ContainsItemShape) const; + QPixmap grabMapView(bool includeWidgets = true) const; + + QPointF mapToProj(QPoint pos); + QPoint mapFromProj(QPointF projPos); + + void refreshMap(); + void refreshProjection(); + void anchoreWidgets(); + + virtual void onMapState(QGV::MapState state); + virtual void onMapCamera(const QGVCameraState& oldState, const QGVCameraState& newState); + +protected: + void mouseMoveEvent(QMouseEvent* event) override; + +Q_SIGNALS: + void projectionChanged(); + void scaleChanged(); + void azimuthChanged(); + void areaChanged(); + void itemsChanged(QGVItem* parent); + void stateChanged(QGV::MapState state); + void itemClicked(QGVItem* item, QPointF projPos); + void itemDoubleClicked(QGVItem* item, QPointF projPos); + void mapMouseMove(QPointF projPos); + +private: + QScopedPointer mProjection; + QScopedPointer mQGView; + QScopedPointer mRootItem; + QList mWidgets; + QSet mSelections; +}; diff --git a/lib/include/QGeoView/QGVMapQGItem.h b/lib/include/QGeoView/QGVMapQGItem.h index 5787c8e..20d2d74 100644 --- a/lib/include/QGeoView/QGVMapQGItem.h +++ b/lib/include/QGeoView/QGVMapQGItem.h @@ -1,45 +1,45 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVGlobal.h" - -#include - -class QGVDrawItem; - -class QGV_LIB_DECL QGVMapQGItem : public QGraphicsItem -{ -public: - explicit QGVMapQGItem(QGVDrawItem* geoObject); - - static QGVDrawItem* geoObjectFromQGItem(QGraphicsItem* item); - - void resetGeometry(); - -private: - QRectF boundingRect() const override final; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0) override final; - QPainterPath shape() const override final; - void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override final; - void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override final; - -private: - QGVDrawItem* mGeoObject; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVGlobal.h" + +#include + +class QGVDrawItem; + +class QGV_LIB_DECL QGVMapQGItem : public QGraphicsItem +{ +public: + explicit QGVMapQGItem(QGVDrawItem* geoObject); + + static QGVDrawItem* geoObjectFromQGItem(QGraphicsItem* item); + + void resetGeometry(); + +private: + QRectF boundingRect() const override final; + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0) override final; + QPainterPath shape() const override final; + void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override final; + void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override final; + +private: + QGVDrawItem* mGeoObject; +}; diff --git a/lib/include/QGeoView/QGVMapQGView.h b/lib/include/QGeoView/QGVMapQGView.h index 75781d1..9cb456a 100644 --- a/lib/include/QGeoView/QGVMapQGView.h +++ b/lib/include/QGeoView/QGVMapQGView.h @@ -1,100 +1,100 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVCamera.h" -#include "QGVGlobal.h" -#include "QGVMapRubberBand.h" - -#include -#include - -class QGVMap; - -class QGV_LIB_DECL QGVMapQGView : public QGraphicsView -{ - Q_OBJECT - -public: - explicit QGVMapQGView(QGVMap* geoMap); - - void setMouseActions(QGV::MouseActions actions); - QGV::MouseActions getMouseActions() const; - - QGVCameraState getCamera() const; - void cameraTo(const QGVCameraActions& actions, bool animation); - double getMinScale() const; - double getMaxScale() const; - void setScaleLimits(double minScale, double maxScale); - void cleanState(); - -private: - QRectF viewRect() const; - void changeState(QGV::MapState state); - void cameraScale(double scale); - void cameraScale(const QRectF& projRect); - void cameraRotate(double azimuth); - void cameraMove(const QPointF& projPos); - void blockCameraUpdate(); - void unblockCameraUpdate(); - void applyCameraUpdate(const QGVCameraState& oldState); - - void showTooltip(QHelpEvent* helpEvent); - void zoomByWheel(QWheelEvent* event); - void startMoving(QMouseEvent* event); - void startSelectionRect(QMouseEvent* event); - void stopSelectionRect(QMouseEvent* event); - void zoomArea(QMouseEvent* event, QRect areaRect); - void selectObjectsByRect(QMouseEvent* event, QRect selRect); - void objectClick(QMouseEvent* event); - void objectDoubleClick(QMouseEvent* event); - void moveForWheel(QMouseEvent* event); - void moveForRect(QMouseEvent* event); - void moveMap(QMouseEvent* event); - void unselectAll(QMouseEvent* event); - void showMenu(QMouseEvent* event); - - bool event(QEvent* event) override final; - void wheelEvent(QWheelEvent* event) override final; - void mousePressEvent(QMouseEvent* event) override final; - void mouseReleaseEvent(QMouseEvent* event) override final; - void mouseMoveEvent(QMouseEvent* event) override final; - void mouseDoubleClickEvent(QMouseEvent* event) override final; - void resizeEvent(QResizeEvent* event) override final; - void showEvent(QShowEvent* event) override final; - void keyPressEvent(QKeyEvent* event) override final; - -private: - QGVMap* mGeoMap; - unsigned int mBlockUpdateCount; - double mMinScale; - double mMaxScale; - double mScale; - double mAzimuth; - QGV::MouseActions mMouseActions; - QRect mViewRect; - QGV::MapState mState; - QRect mWheelMouseArea; - QPointF mWheelProjAnchor; - double mWheelBestFactor; - QPointF mMoveProjAnchor; - QScopedPointer mQGScene; - QScopedPointer mSelectionRect; - QScopedPointer mContextMenu; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVCamera.h" +#include "QGVGlobal.h" +#include "QGVMapRubberBand.h" + +#include +#include + +class QGVMap; + +class QGV_LIB_DECL QGVMapQGView : public QGraphicsView +{ + Q_OBJECT + +public: + explicit QGVMapQGView(QGVMap* geoMap); + + void setMouseActions(QGV::MouseActions actions); + QGV::MouseActions getMouseActions() const; + + QGVCameraState getCamera() const; + void cameraTo(const QGVCameraActions& actions, bool animation); + double getMinScale() const; + double getMaxScale() const; + void setScaleLimits(double minScale, double maxScale); + void cleanState(); + +private: + QRectF viewRect() const; + void changeState(QGV::MapState state); + void cameraScale(double scale); + void cameraScale(const QRectF& projRect); + void cameraRotate(double azimuth); + void cameraMove(const QPointF& projPos); + void blockCameraUpdate(); + void unblockCameraUpdate(); + void applyCameraUpdate(const QGVCameraState& oldState); + + void showTooltip(QHelpEvent* helpEvent); + void zoomByWheel(QWheelEvent* event); + void startMoving(QMouseEvent* event); + void startSelectionRect(QMouseEvent* event); + void stopSelectionRect(QMouseEvent* event); + void zoomArea(QMouseEvent* event, QRect areaRect); + void selectObjectsByRect(QMouseEvent* event, QRect selRect); + void objectClick(QMouseEvent* event); + void objectDoubleClick(QMouseEvent* event); + void moveForWheel(QMouseEvent* event); + void moveForRect(QMouseEvent* event); + void moveMap(QMouseEvent* event); + void unselectAll(QMouseEvent* event); + void showMenu(QMouseEvent* event); + + bool event(QEvent* event) override final; + void wheelEvent(QWheelEvent* event) override final; + void mousePressEvent(QMouseEvent* event) override final; + void mouseReleaseEvent(QMouseEvent* event) override final; + void mouseMoveEvent(QMouseEvent* event) override final; + void mouseDoubleClickEvent(QMouseEvent* event) override final; + void resizeEvent(QResizeEvent* event) override final; + void showEvent(QShowEvent* event) override final; + void keyPressEvent(QKeyEvent* event) override final; + +private: + QGVMap* mGeoMap; + unsigned int mBlockUpdateCount; + double mMinScale; + double mMaxScale; + double mScale; + double mAzimuth; + QGV::MouseActions mMouseActions; + QRect mViewRect; + QGV::MapState mState; + QRect mWheelMouseArea; + QPointF mWheelProjAnchor; + double mWheelBestFactor; + QPointF mMoveProjAnchor; + QScopedPointer mQGScene; + QScopedPointer mSelectionRect; + QScopedPointer mContextMenu; +}; diff --git a/lib/include/QGeoView/QGVMapRubberBand.h b/lib/include/QGeoView/QGVMapRubberBand.h index 6363d01..931f197 100644 --- a/lib/include/QGeoView/QGVMapRubberBand.h +++ b/lib/include/QGeoView/QGVMapRubberBand.h @@ -1,52 +1,52 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVGlobal.h" - -#include -#include - -class QGV_LIB_DECL QGVMapRubberBand : public QObject -{ - Q_OBJECT - -public: - explicit QGVMapRubberBand(QWidget* parent); - - void setMinSelection(QSize const& min); - void setStartPoint(QPoint const& point); - void setEndPoint(QPoint const& point); - bool isActive() const; - bool isSelection() const; - QRect getRect() const; - - void showRect(); - void hideRect(); - -private: - void updateRect(); - -private: - Q_DISABLE_COPY(QGVMapRubberBand) - QSize mMin; - QPoint mStartPoint; - QPoint mEndPoint; - QScopedPointer mRubberBand; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVGlobal.h" + +#include +#include + +class QGV_LIB_DECL QGVMapRubberBand : public QObject +{ + Q_OBJECT + +public: + explicit QGVMapRubberBand(QWidget* parent); + + void setMinSelection(QSize const& min); + void setStartPoint(QPoint const& point); + void setEndPoint(QPoint const& point); + bool isActive() const; + bool isSelection() const; + QRect getRect() const; + + void showRect(); + void hideRect(); + +private: + void updateRect(); + +private: + Q_DISABLE_COPY(QGVMapRubberBand) + QSize mMin; + QPoint mStartPoint; + QPoint mEndPoint; + QScopedPointer mRubberBand; +}; diff --git a/lib/include/QGeoView/QGVProjection.h b/lib/include/QGeoView/QGVProjection.h index 699d01b..ef5cd19 100644 --- a/lib/include/QGeoView/QGVProjection.h +++ b/lib/include/QGeoView/QGVProjection.h @@ -1,47 +1,47 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVGlobal.h" - -class QGV_LIB_DECL QGVProjection -{ -public: - explicit QGVProjection(const QString& id, const QString& name, const QString& description); - virtual ~QGVProjection() = default; - - QString getID() const; - QString getName() const; - QString getDescription() const; - - virtual QGV::GeoRect boundaryGeoRect() const = 0; - virtual QRectF boundaryProjRect() const = 0; - - virtual QPointF geoToProj(QGV::GeoPos const& geoPos) const = 0; - virtual QGV::GeoPos projToGeo(QPointF const& projPos) const = 0; - virtual QRectF geoToProj(QGV::GeoRect const& geoRect) const = 0; - virtual QGV::GeoRect projToGeo(QRectF const& projRect) const = 0; - virtual double geodesicMeters(QPointF const& projPos1, QPointF const& projPos2) const = 0; - -private: - Q_DISABLE_COPY(QGVProjection) - QString mID; - QString mName; - QString mDescription; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVGlobal.h" + +class QGV_LIB_DECL QGVProjection +{ +public: + explicit QGVProjection(const QString& id, const QString& name, const QString& description); + virtual ~QGVProjection() = default; + + QString getID() const; + QString getName() const; + QString getDescription() const; + + virtual QGV::GeoRect boundaryGeoRect() const = 0; + virtual QRectF boundaryProjRect() const = 0; + + virtual QPointF geoToProj(QGV::GeoPos const& geoPos) const = 0; + virtual QGV::GeoPos projToGeo(QPointF const& projPos) const = 0; + virtual QRectF geoToProj(QGV::GeoRect const& geoRect) const = 0; + virtual QGV::GeoRect projToGeo(QRectF const& projRect) const = 0; + virtual double geodesicMeters(QPointF const& projPos1, QPointF const& projPos2) const = 0; + +private: + Q_DISABLE_COPY(QGVProjection) + QString mID; + QString mName; + QString mDescription; +}; diff --git a/lib/include/QGeoView/QGVProjectionEPSG3857.h b/lib/include/QGeoView/QGVProjectionEPSG3857.h index e3ae83c..3daebbd 100644 --- a/lib/include/QGeoView/QGVProjectionEPSG3857.h +++ b/lib/include/QGeoView/QGVProjectionEPSG3857.h @@ -1,45 +1,45 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVProjection.h" - -class QGV_LIB_DECL QGVProjectionEPSG3857 : public QGVProjection -{ -public: - QGVProjectionEPSG3857(); - virtual ~QGVProjectionEPSG3857() = default; - -private: - QGV::GeoRect boundaryGeoRect() const override final; - QRectF boundaryProjRect() const override final; - - QPointF geoToProj(QGV::GeoPos const& geoPos) const override final; - QGV::GeoPos projToGeo(QPointF const& projPos) const override final; - QRectF geoToProj(QGV::GeoRect const& geoRect) const override final; - QGV::GeoRect projToGeo(QRectF const& projRect) const override final; - - double geodesicMeters(QPointF const& projPos1, QPointF const& projPos2) const override final; - -private: - double mEarthRadius; - double mOriginShift; - QGV::GeoRect mGeoBoundary; - QRectF mProjBoundary; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVProjection.h" + +class QGV_LIB_DECL QGVProjectionEPSG3857 : public QGVProjection +{ +public: + QGVProjectionEPSG3857(); + virtual ~QGVProjectionEPSG3857() = default; + +private: + QGV::GeoRect boundaryGeoRect() const override final; + QRectF boundaryProjRect() const override final; + + QPointF geoToProj(QGV::GeoPos const& geoPos) const override final; + QGV::GeoPos projToGeo(QPointF const& projPos) const override final; + QRectF geoToProj(QGV::GeoRect const& geoRect) const override final; + QGV::GeoRect projToGeo(QRectF const& projRect) const override final; + + double geodesicMeters(QPointF const& projPos1, QPointF const& projPos2) const override final; + +private: + double mEarthRadius; + double mOriginShift; + QGV::GeoRect mGeoBoundary; + QRectF mProjBoundary; +}; diff --git a/lib/include/QGeoView/QGVWidget.h b/lib/include/QGeoView/QGVWidget.h index b157da3..069b951 100644 --- a/lib/include/QGeoView/QGVWidget.h +++ b/lib/include/QGeoView/QGVWidget.h @@ -1,62 +1,62 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include -#include - -#include "QGVGlobal.h" -#include "QGVMap.h" - -class QGV_LIB_DECL QGVWidget : public QWidget -{ - Q_OBJECT - -public: - QGVWidget(); - virtual ~QGVWidget(); - - void setMap(QGVMap* geoMap); - QGVMap* getMap() const; - - void setAnchor(QPoint anchor, QSet edge); - QPointF getAnchor() const; - QSet getEdge() const; - - bool isAnchorLeft() const; - bool isAnchorRight() const; - bool isAnchorHCenter() const; - - bool isAnchorTop() const; - bool isAnchorBottom() const; - bool isAnchorVCenter() const; - - void anchoreWidget(); - - virtual void onProjection(QGVMap* geoMap); - virtual void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState); - -protected: - void resizeEvent(QResizeEvent* event) override; - -private: - QGVMap* mGeoMap; - QPoint mAnchor; - QSet mEdge; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include +#include + +#include "QGVGlobal.h" +#include "QGVMap.h" + +class QGV_LIB_DECL QGVWidget : public QWidget +{ + Q_OBJECT + +public: + QGVWidget(); + virtual ~QGVWidget(); + + void setMap(QGVMap* geoMap); + QGVMap* getMap() const; + + void setAnchor(QPoint anchor, QSet edge); + QPointF getAnchor() const; + QSet getEdge() const; + + bool isAnchorLeft() const; + bool isAnchorRight() const; + bool isAnchorHCenter() const; + + bool isAnchorTop() const; + bool isAnchorBottom() const; + bool isAnchorVCenter() const; + + void anchoreWidget(); + + virtual void onProjection(QGVMap* geoMap); + virtual void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState); + +protected: + void resizeEvent(QResizeEvent* event) override; + +private: + QGVMap* mGeoMap; + QPoint mAnchor; + QSet mEdge; +}; diff --git a/lib/include/QGeoView/QGVWidgetCompass.h b/lib/include/QGeoView/QGVWidgetCompass.h index fc5e6f7..40d8aa5 100644 --- a/lib/include/QGeoView/QGVWidgetCompass.h +++ b/lib/include/QGeoView/QGVWidgetCompass.h @@ -1,47 +1,47 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVWidget.h" - -class QGV_LIB_DECL QGVWidgetCompass : public QGVWidget -{ - Q_OBJECT - -public: - QGVWidgetCompass(); - - void setPixmap(QPixmap pixmap); - -private: - QPixmap createPixmap(); - double mouseToAzimuth(const QPoint& pos, double offset) const; - void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; - void paintEvent(QPaintEvent* event) override; - void mouseMoveEvent(QMouseEvent* event) override; - void mousePressEvent(QMouseEvent* event) override; - void mouseReleaseEvent(QMouseEvent* event) override; - void mouseDoubleClickEvent(QMouseEvent* event) override; - -private: - QPixmap mPixmap; - bool mTracking; - double mOffset; - QTransform mTransfrom; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVWidget.h" + +class QGV_LIB_DECL QGVWidgetCompass : public QGVWidget +{ + Q_OBJECT + +public: + QGVWidgetCompass(); + + void setPixmap(QPixmap pixmap); + +private: + QPixmap createPixmap(); + double mouseToAzimuth(const QPoint& pos, double offset) const; + void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; + void paintEvent(QPaintEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; + +private: + QPixmap mPixmap; + bool mTracking; + double mOffset; + QTransform mTransfrom; +}; diff --git a/lib/include/QGeoView/QGVWidgetScale.h b/lib/include/QGeoView/QGVWidgetScale.h index 0856fb9..a7336d5 100644 --- a/lib/include/QGeoView/QGVWidgetScale.h +++ b/lib/include/QGeoView/QGVWidgetScale.h @@ -1,47 +1,47 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVWidget.h" - -class QGV_LIB_DECL QGVWidgetScale : public QGVWidget -{ - Q_OBJECT - -public: - QGVWidgetScale(Qt::Orientation orientation = Qt::Horizontal); - - void setAutoAdjust(bool autoAdjust); - bool getAutoAdjust() const; - - void setOrientation(Qt::Orientation orientation); - Qt::Orientation getOrientation() const; - - QString getDistanceLabel(int meters, int accuracy = 0) const; - -private: - void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; - void paintEvent(QPaintEvent* event) override; - -private: - Qt::Orientation mOrientation; - bool mAutoAdjust; - int mScaleMeters; - int mScalePixels; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVWidget.h" + +class QGV_LIB_DECL QGVWidgetScale : public QGVWidget +{ + Q_OBJECT + +public: + QGVWidgetScale(Qt::Orientation orientation = Qt::Horizontal); + + void setAutoAdjust(bool autoAdjust); + bool getAutoAdjust() const; + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation getOrientation() const; + + QString getDistanceLabel(int meters, int accuracy = 0) const; + +private: + void onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) override; + void paintEvent(QPaintEvent* event) override; + +private: + Qt::Orientation mOrientation; + bool mAutoAdjust; + int mScaleMeters; + int mScalePixels; +}; diff --git a/lib/include/QGeoView/QGVWidgetText.h b/lib/include/QGeoView/QGVWidgetText.h index aeeff99..c54f14f 100644 --- a/lib/include/QGeoView/QGVWidgetText.h +++ b/lib/include/QGeoView/QGVWidgetText.h @@ -1,39 +1,39 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include "QGVWidget.h" - -#include - -class QGV_LIB_DECL QGVWidgetText : public QGVWidget -{ - Q_OBJECT - -public: - QGVWidgetText(); - - void setText(const QString& text); - QString getText() const; - - QLabel* label(); - -private: - QScopedPointer mLabel; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include "QGVWidget.h" + +#include + +class QGV_LIB_DECL QGVWidgetText : public QGVWidget +{ + Q_OBJECT + +public: + QGVWidgetText(); + + void setText(const QString& text); + QString getText() const; + + QLabel* label(); + +private: + QScopedPointer mLabel; +}; diff --git a/lib/include/QGeoView/QGVWidgetZoom.h b/lib/include/QGeoView/QGVWidgetZoom.h index fe05b18..5956a37 100644 --- a/lib/include/QGeoView/QGVWidgetZoom.h +++ b/lib/include/QGeoView/QGVWidgetZoom.h @@ -1,47 +1,47 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ - -#pragma once - -#include - -#include "QGVWidget.h" - -class QGV_LIB_DECL QGVWidgetZoom : public QGVWidget -{ - Q_OBJECT - -public: - QGVWidgetZoom(); - - void setOrientation(Qt::Orientation orientation); - Qt::Orientation getOrientation() const; - - QToolButton* plus(); - QToolButton* minus(); - -private: - QPixmap createPixmap(const QSize& size, const QString& text); - void zoomPlus(); - void zoomMinus(); - -private: - Qt::Orientation mOrientation; - QScopedPointer mButtonPlus; - QScopedPointer mButtonMinus; -}; +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/ + +#pragma once + +#include + +#include "QGVWidget.h" + +class QGV_LIB_DECL QGVWidgetZoom : public QGVWidget +{ + Q_OBJECT + +public: + QGVWidgetZoom(); + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation getOrientation() const; + + QToolButton* plus(); + QToolButton* minus(); + +private: + QPixmap createPixmap(const QSize& size, const QString& text); + void zoomPlus(); + void zoomMinus(); + +private: + Qt::Orientation mOrientation; + QScopedPointer mButtonPlus; + QScopedPointer mButtonMinus; +}; diff --git a/lib/src/QGVCamera.cpp b/lib/src/QGVCamera.cpp index 5b275ca..581621d 100644 --- a/lib/src/QGVCamera.cpp +++ b/lib/src/QGVCamera.cpp @@ -1,376 +1,369 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVCamera.h" -#include "QGVMap.h" - -#include - -QGVCameraState::QGVCameraState(QGVMap* geoMap, double azimuth, double scale, const QRectF& projRect, bool animation) - : mGeoMap(geoMap) - , mScale(scale) - , mAzimuth(azimuth) - , mProjRect(projRect) - , mAnimation(animation) -{ - Q_ASSERT(geoMap); -} - -QGVCameraState::QGVCameraState(const QGVCameraState& other) - : mGeoMap(other.mGeoMap) - , mScale(other.mScale) - , mAzimuth(other.mAzimuth) - , mProjRect(other.mProjRect) - , mAnimation(other.mAnimation) -{ -} - -QGVCameraState::QGVCameraState(const QGVCameraState&& other) - : mGeoMap(std::move(other.mGeoMap)) - , mScale(std::move(other.mScale)) - , mAzimuth(std::move(other.mAzimuth)) - , mProjRect(std::move(other.mProjRect)) - , mAnimation(std::move(other.mAnimation)) -{ -} - -QGVCameraState& QGVCameraState::operator=(const QGVCameraState& other) -{ - mGeoMap = other.mGeoMap; - mScale = other.mScale; - mAzimuth = other.mAzimuth; - mProjRect = other.mProjRect; - mAnimation = other.mAnimation; - return *this; -} - -QGVCameraState& QGVCameraState::operator=(const QGVCameraState&& other) -{ - mGeoMap = std::move(other.mGeoMap); - mScale = std::move(other.mScale); - mAzimuth = std::move(other.mAzimuth); - mProjRect = std::move(other.mProjRect); - mAnimation = std::move(other.mAnimation); - return *this; -} - -QGVMap* QGVCameraState::getMap() const -{ - return mGeoMap; -} - -QGVProjection* QGVCameraState::getProjection() const -{ - return mGeoMap->getProjection(); -} - -double QGVCameraState::azimuth() const -{ - return mAzimuth; -} - -double QGVCameraState::scale() const -{ - return mScale; -} - -QRectF QGVCameraState::projRect() const -{ - return mProjRect; -} - -QPointF QGVCameraState::projCenter() const -{ - return mProjRect.center(); -} - -bool QGVCameraState::animation() const -{ - return mAnimation; -} - -bool QGVCameraState::operator==(const QGVCameraState& other) const -{ - return mGeoMap == other.mGeoMap && qFuzzyCompare(mScale, other.mScale) && qFuzzyCompare(mAzimuth, other.mAzimuth) && - mProjRect == other.mProjRect && mAnimation == other.mAnimation; -} - -bool QGVCameraState::operator!=(const QGVCameraState& other) const -{ - return !(*this == other); -} - -QGVCameraActions::QGVCameraActions(QGVMap* geoMap) - : mOrigin(geoMap->getCamera()) -{ - reset(); -} - -QGVCameraActions::QGVCameraActions(const QGVCameraActions& other) - : mOrigin(other.mOrigin) - , mScale(other.mScale) - , mAzimuth(other.mAzimuth) - , mProjCenter(other.mProjCenter) -{ -} - -const QGVCameraState& QGVCameraActions::origin() const -{ - return mOrigin; -} - -QGVCameraActions& QGVCameraActions::rebase(const QGVCameraState& origin) -{ - mOrigin = origin; - return *this; -} - -QGVCameraActions& QGVCameraActions::reset() -{ - return reset(mOrigin); -} - -QGVCameraActions& QGVCameraActions::reset(const QGVCameraState& origin) -{ - mOrigin = origin; - mScale = mOrigin.scale(); - mAzimuth = mOrigin.azimuth(); - mProjCenter = mOrigin.projCenter(); - return *this; -} - -QGVCameraActions& QGVCameraActions::scaleBy(double factor) -{ - return scaleTo(mOrigin.scale() * factor); -} - -QGVCameraActions& QGVCameraActions::scaleTo(double scale) -{ - mScale = scale; - return *this; -} - -QGVCameraActions& QGVCameraActions::scaleTo(const QRectF& projRect) -{ - const QRectF oldProjRect = mOrigin.projRect(); - const double scaleFactor = - qMin(qAbs(oldProjRect.width() / projRect.width()), qAbs(oldProjRect.height() / projRect.height())); - mScale = mOrigin.scale() * scaleFactor; - mProjCenter = projRect.center(); - return *this; -} - -QGVCameraActions& QGVCameraActions::scaleTo(const QGV::GeoRect& geoRect) -{ - const QRectF projRect = mOrigin.getMap()->getProjection()->geoToProj(geoRect); - return scaleTo(projRect); -} - -QGVCameraActions& QGVCameraActions::rotateBy(double angle) -{ - rotateTo(mOrigin.azimuth() + angle); - return *this; -} - -QGVCameraActions& QGVCameraActions::rotateTo(double azimuth) -{ - mAzimuth = azimuth; - return *this; -} - -QGVCameraActions& QGVCameraActions::moveTo(const QPointF& projPos) -{ - mProjCenter = projPos; - return *this; -} - -QGVCameraActions& QGVCameraActions::moveTo(const QGV::GeoPos& geoPos) -{ - const QPointF projPos = mOrigin.getMap()->getProjection()->geoToProj(geoPos); - return moveTo(projPos); -} - -double QGVCameraActions::scale() const -{ - return mScale; -} - -double QGVCameraActions::azimuth() const -{ - return mAzimuth; -} - -QPointF QGVCameraActions::projCenter() const -{ - return mProjCenter; -} - -QGVCameraAnimation::QGVCameraAnimation(const QGVCameraActions& actions, QObject* parent) - : QAbstractAnimation(parent) - , mDuration(1000) - , mActions(actions) -{ -} - -void QGVCameraAnimation::setDuration(int msecs) -{ - mDuration = msecs; -} - -int QGVCameraAnimation::duration() const -{ - return mDuration; -} - -QGVCameraActions& QGVCameraAnimation::actions() -{ - return mActions; -} - -void QGVCameraAnimation::onStart() -{ -} - -void QGVCameraAnimation::onStop() -{ -} - -double QGVCameraAnimation::interpolateScale(double from, double to, double progress) -{ - if (qFuzzyCompare(from, to)) { - return from; - } - const double expFrom = qLn(from) * M_LOG2E; - const double expTo = qLn(to) * M_LOG2E; - const double delta = expTo - expFrom; - return qPow(2, expFrom + delta * progress); -} - -double QGVCameraAnimation::interpolateAzimuth(double from, double to, double progress) -{ - if (qFuzzyCompare(from, to)) { - return from; - } - const double delta = to - from; - return from + delta * progress; -} - -QPointF QGVCameraAnimation::interpolatePos(QPointF from, QPointF to, double progress) -{ - if (from == to) { - return from; - } - const QPointF delta = to - from; - return from + delta * progress; -} - -void QGVCameraAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) -{ - auto geoMap = mActions.origin().getMap(); - if (newState == QAbstractAnimation::Running && oldState == QAbstractAnimation::Stopped) { - mActions.rebase(geoMap->getCamera()); - connect(geoMap, &QGVMap::stateChanged, this, &QGVCameraAnimation::onStateChanged); - onStart(); - } - if (newState == QAbstractAnimation::Stopped && oldState != QAbstractAnimation::Stopped) { - disconnect(geoMap, nullptr, this, nullptr); - geoMap->cameraTo(QGVCameraActions(geoMap), false); - onStop(); - } -} - -void QGVCameraAnimation::updateCurrentTime(int currentTime) -{ - double progress = static_cast(currentTime) / duration(); - if (direction() == Direction::Backward) { - progress = 1.0 - progress; - } - QGVCameraActions target(mActions); - target.reset(); - onProgress(progress, target); - mActions.origin().getMap()->cameraTo(target, true); -} - -void QGVCameraAnimation::onStateChanged(QGV::MapState state) -{ - if (state != QGV::MapState::Animation) { - stop(); - } -} - -QGVCameraSimpleAnimation::QGVCameraSimpleAnimation(const QGVCameraActions& actions, QObject* parent) - : QGVCameraAnimation(actions, parent) - , mEasing(QEasingCurve::Linear) -{ -} - -void QGVCameraSimpleAnimation::setEasingCurve(const QEasingCurve& easing) -{ - mEasing = easing; -} - -void QGVCameraSimpleAnimation::onProgress(double progress, QGVCameraActions& target) -{ - progress = mEasing.valueForProgress(progress); - target.scaleTo(interpolateScale(actions().origin().scale(), actions().scale(), progress)); - target.rotateTo(interpolateAzimuth(actions().origin().azimuth(), actions().azimuth(), progress)); - target.moveTo(interpolatePos(actions().origin().projCenter(), actions().projCenter(), progress)); -} - -QGVCameraFlyAnimation::QGVCameraFlyAnimation(const QGVCameraActions& actions, QObject* parent) - : QGVCameraAnimation(actions, parent) -{ - setDuration(3000); -} - -void QGVCameraFlyAnimation::onStart() -{ - const QLineF line(actions().projCenter(), actions().origin().projCenter()); - const double scaledDistance0 = line.length(); - const double scaledDistance1 = scaledDistance0 * actions().origin().scale(); - const double scaledDistance2 = scaledDistance0 * actions().scale(); - const double projSpeed0 = scaledDistance0 / (duration() / 1000); - const double projSpeed1 = scaledDistance1 / (duration() / 1000); - const double projSpeed2 = scaledDistance2 / (duration() / 1000); - const double expectedSpeed = 300; - if (projSpeed1 < expectedSpeed && projSpeed2 < expectedSpeed) { - setDuration(static_cast(1000.0 * qMax(scaledDistance1, scaledDistance2) / expectedSpeed)); - } - mFlyScale = qMin(actions().scale(), expectedSpeed / projSpeed0); - mFlyAnchor = interpolatePos(actions().origin().projCenter(), actions().projCenter(), 0.5); -} - -void QGVCameraFlyAnimation::onProgress(double progress, QGVCameraActions& target) -{ - const auto moveCurve = QEasingCurve(QEasingCurve::InQuint); - const double switchThr = 0.5; - if (progress <= switchThr) { - const double flyInter = progress / switchThr; - target.scaleTo(interpolateScale(actions().origin().scale(), mFlyScale, flyInter)); - const double moveInter = moveCurve.valueForProgress(flyInter); - target.moveTo(interpolatePos(actions().origin().projCenter(), mFlyAnchor, moveInter)); - - } else { - const double flyInter = (progress - switchThr) / (1.0 - switchThr); - target.scaleTo(interpolateScale(mFlyScale, actions().scale(), flyInter)); - const double moveInter = 1.0 - moveCurve.valueForProgress(1.0 - flyInter); - target.moveTo(interpolatePos(mFlyAnchor, actions().projCenter(), moveInter)); - } - - target.rotateTo(interpolateAzimuth(actions().origin().azimuth(), actions().azimuth(), progress)); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVCamera.h" +#include "QGVMap.h" + +#include + +QGVCameraState::QGVCameraState(QGVMap* geoMap, double azimuth, double scale, const QRectF& projRect, bool animation) + : mGeoMap(geoMap) + , mScale(scale) + , mAzimuth(azimuth) + , mProjRect(projRect) + , mAnimation(animation) +{ + Q_ASSERT(geoMap); +} + +QGVCameraState::QGVCameraState(const QGVCameraState& other) + : mGeoMap(other.mGeoMap) + , mScale(other.mScale) + , mAzimuth(other.mAzimuth) + , mProjRect(other.mProjRect) + , mAnimation(other.mAnimation) +{} + +QGVCameraState::QGVCameraState(const QGVCameraState&& other) + : mGeoMap(std::move(other.mGeoMap)) + , mScale(std::move(other.mScale)) + , mAzimuth(std::move(other.mAzimuth)) + , mProjRect(std::move(other.mProjRect)) + , mAnimation(std::move(other.mAnimation)) +{} + +QGVCameraState& QGVCameraState::operator=(const QGVCameraState& other) +{ + mGeoMap = other.mGeoMap; + mScale = other.mScale; + mAzimuth = other.mAzimuth; + mProjRect = other.mProjRect; + mAnimation = other.mAnimation; + return *this; +} + +QGVCameraState& QGVCameraState::operator=(const QGVCameraState&& other) +{ + mGeoMap = std::move(other.mGeoMap); + mScale = std::move(other.mScale); + mAzimuth = std::move(other.mAzimuth); + mProjRect = std::move(other.mProjRect); + mAnimation = std::move(other.mAnimation); + return *this; +} + +QGVMap* QGVCameraState::getMap() const +{ + return mGeoMap; +} + +QGVProjection* QGVCameraState::getProjection() const +{ + return mGeoMap->getProjection(); +} + +double QGVCameraState::azimuth() const +{ + return mAzimuth; +} + +double QGVCameraState::scale() const +{ + return mScale; +} + +QRectF QGVCameraState::projRect() const +{ + return mProjRect; +} + +QPointF QGVCameraState::projCenter() const +{ + return mProjRect.center(); +} + +bool QGVCameraState::animation() const +{ + return mAnimation; +} + +bool QGVCameraState::operator==(const QGVCameraState& other) const +{ + return mGeoMap == other.mGeoMap && qFuzzyCompare(mScale, other.mScale) && qFuzzyCompare(mAzimuth, other.mAzimuth) && + mProjRect == other.mProjRect && mAnimation == other.mAnimation; +} + +bool QGVCameraState::operator!=(const QGVCameraState& other) const +{ + return !(*this == other); +} + +QGVCameraActions::QGVCameraActions(QGVMap* geoMap) + : mOrigin(geoMap->getCamera()) +{ + reset(); +} + +QGVCameraActions::QGVCameraActions(const QGVCameraActions& other) + : mOrigin(other.mOrigin) + , mScale(other.mScale) + , mAzimuth(other.mAzimuth) + , mProjCenter(other.mProjCenter) +{} + +const QGVCameraState& QGVCameraActions::origin() const +{ + return mOrigin; +} + +QGVCameraActions& QGVCameraActions::rebase(const QGVCameraState& origin) +{ + mOrigin = origin; + return *this; +} + +QGVCameraActions& QGVCameraActions::reset() +{ + return reset(mOrigin); +} + +QGVCameraActions& QGVCameraActions::reset(const QGVCameraState& origin) +{ + mOrigin = origin; + mScale = mOrigin.scale(); + mAzimuth = mOrigin.azimuth(); + mProjCenter = mOrigin.projCenter(); + return *this; +} + +QGVCameraActions& QGVCameraActions::scaleBy(double factor) +{ + return scaleTo(mOrigin.scale() * factor); +} + +QGVCameraActions& QGVCameraActions::scaleTo(double scale) +{ + mScale = scale; + return *this; +} + +QGVCameraActions& QGVCameraActions::scaleTo(const QRectF& projRect) +{ + const QRectF oldProjRect = mOrigin.projRect(); + const double scaleFactor = + qMin(qAbs(oldProjRect.width() / projRect.width()), qAbs(oldProjRect.height() / projRect.height())); + mScale = mOrigin.scale() * scaleFactor; + mProjCenter = projRect.center(); + return *this; +} + +QGVCameraActions& QGVCameraActions::scaleTo(const QGV::GeoRect& geoRect) +{ + const QRectF projRect = mOrigin.getMap()->getProjection()->geoToProj(geoRect); + return scaleTo(projRect); +} + +QGVCameraActions& QGVCameraActions::rotateBy(double angle) +{ + rotateTo(mOrigin.azimuth() + angle); + return *this; +} + +QGVCameraActions& QGVCameraActions::rotateTo(double azimuth) +{ + mAzimuth = azimuth; + return *this; +} + +QGVCameraActions& QGVCameraActions::moveTo(const QPointF& projPos) +{ + mProjCenter = projPos; + return *this; +} + +QGVCameraActions& QGVCameraActions::moveTo(const QGV::GeoPos& geoPos) +{ + const QPointF projPos = mOrigin.getMap()->getProjection()->geoToProj(geoPos); + return moveTo(projPos); +} + +double QGVCameraActions::scale() const +{ + return mScale; +} + +double QGVCameraActions::azimuth() const +{ + return mAzimuth; +} + +QPointF QGVCameraActions::projCenter() const +{ + return mProjCenter; +} + +QGVCameraAnimation::QGVCameraAnimation(const QGVCameraActions& actions, QObject* parent) + : QAbstractAnimation(parent) + , mDuration(1000) + , mActions(actions) +{} + +void QGVCameraAnimation::setDuration(int msecs) +{ + mDuration = msecs; +} + +int QGVCameraAnimation::duration() const +{ + return mDuration; +} + +QGVCameraActions& QGVCameraAnimation::actions() +{ + return mActions; +} + +void QGVCameraAnimation::onStart() +{} + +void QGVCameraAnimation::onStop() +{} + +double QGVCameraAnimation::interpolateScale(double from, double to, double progress) +{ + if (qFuzzyCompare(from, to)) { + return from; + } + const double expFrom = qLn(from) * M_LOG2E; + const double expTo = qLn(to) * M_LOG2E; + const double delta = expTo - expFrom; + return qPow(2, expFrom + delta * progress); +} + +double QGVCameraAnimation::interpolateAzimuth(double from, double to, double progress) +{ + if (qFuzzyCompare(from, to)) { + return from; + } + const double delta = to - from; + return from + delta * progress; +} + +QPointF QGVCameraAnimation::interpolatePos(QPointF from, QPointF to, double progress) +{ + if (from == to) { + return from; + } + const QPointF delta = to - from; + return from + delta * progress; +} + +void QGVCameraAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + auto geoMap = mActions.origin().getMap(); + if (newState == QAbstractAnimation::Running && oldState == QAbstractAnimation::Stopped) { + mActions.rebase(geoMap->getCamera()); + connect(geoMap, &QGVMap::stateChanged, this, &QGVCameraAnimation::onStateChanged); + onStart(); + } + if (newState == QAbstractAnimation::Stopped && oldState != QAbstractAnimation::Stopped) { + disconnect(geoMap, nullptr, this, nullptr); + geoMap->cameraTo(QGVCameraActions(geoMap), false); + onStop(); + } +} + +void QGVCameraAnimation::updateCurrentTime(int currentTime) +{ + double progress = static_cast(currentTime) / duration(); + if (direction() == Direction::Backward) { + progress = 1.0 - progress; + } + QGVCameraActions target(mActions); + target.reset(); + onProgress(progress, target); + mActions.origin().getMap()->cameraTo(target, true); +} + +void QGVCameraAnimation::onStateChanged(QGV::MapState state) +{ + if (state != QGV::MapState::Animation) { + stop(); + } +} + +QGVCameraSimpleAnimation::QGVCameraSimpleAnimation(const QGVCameraActions& actions, QObject* parent) + : QGVCameraAnimation(actions, parent) + , mEasing(QEasingCurve::Linear) +{} + +void QGVCameraSimpleAnimation::setEasingCurve(const QEasingCurve& easing) +{ + mEasing = easing; +} + +void QGVCameraSimpleAnimation::onProgress(double progress, QGVCameraActions& target) +{ + progress = mEasing.valueForProgress(progress); + target.scaleTo(interpolateScale(actions().origin().scale(), actions().scale(), progress)); + target.rotateTo(interpolateAzimuth(actions().origin().azimuth(), actions().azimuth(), progress)); + target.moveTo(interpolatePos(actions().origin().projCenter(), actions().projCenter(), progress)); +} + +QGVCameraFlyAnimation::QGVCameraFlyAnimation(const QGVCameraActions& actions, QObject* parent) + : QGVCameraAnimation(actions, parent) +{ + setDuration(3000); +} + +void QGVCameraFlyAnimation::onStart() +{ + const QLineF line(actions().projCenter(), actions().origin().projCenter()); + const double scaledDistance0 = line.length(); + const double scaledDistance1 = scaledDistance0 * actions().origin().scale(); + const double scaledDistance2 = scaledDistance0 * actions().scale(); + const double projSpeed0 = scaledDistance0 / (duration() / 1000); + const double projSpeed1 = scaledDistance1 / (duration() / 1000); + const double projSpeed2 = scaledDistance2 / (duration() / 1000); + const double expectedSpeed = 300; + if (projSpeed1 < expectedSpeed && projSpeed2 < expectedSpeed) { + setDuration(static_cast(1000.0 * qMax(scaledDistance1, scaledDistance2) / expectedSpeed)); + } + mFlyScale = qMin(actions().scale(), expectedSpeed / projSpeed0); + mFlyAnchor = interpolatePos(actions().origin().projCenter(), actions().projCenter(), 0.5); +} + +void QGVCameraFlyAnimation::onProgress(double progress, QGVCameraActions& target) +{ + const auto moveCurve = QEasingCurve(QEasingCurve::InQuint); + const double switchThr = 0.5; + if (progress <= switchThr) { + const double flyInter = progress / switchThr; + target.scaleTo(interpolateScale(actions().origin().scale(), mFlyScale, flyInter)); + const double moveInter = moveCurve.valueForProgress(flyInter); + target.moveTo(interpolatePos(actions().origin().projCenter(), mFlyAnchor, moveInter)); + + } else { + const double flyInter = (progress - switchThr) / (1.0 - switchThr); + target.scaleTo(interpolateScale(mFlyScale, actions().scale(), flyInter)); + const double moveInter = 1.0 - moveCurve.valueForProgress(1.0 - flyInter); + target.moveTo(interpolatePos(mFlyAnchor, actions().projCenter(), moveInter)); + } + + target.rotateTo(interpolateAzimuth(actions().origin().azimuth(), actions().azimuth(), progress)); +} diff --git a/lib/src/QGVDrawItem.cpp b/lib/src/QGVDrawItem.cpp index f351c47..a065f2e 100644 --- a/lib/src/QGVDrawItem.cpp +++ b/lib/src/QGVDrawItem.cpp @@ -1,207 +1,205 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVDrawItem.h" -#include "QGVMapQGItem.h" -#include "QGVMapQGView.h" - -namespace { -double highlightScale = 1.15; -} - -QGVDrawItem::QGVDrawItem() -{ -} - -void QGVDrawItem::setFlags(QGV::ItemFlags flags) -{ - if (mFlags != flags) { - mFlags = flags; - projOnFlags(); - refresh(); - repaint(); - } -} - -void QGVDrawItem::setFlag(QGV::ItemFlag flag, bool enabled) -{ - QGV::ItemFlags newFlags = getFlags(); - if (enabled) - newFlags |= flag; - else - newFlags &= ~static_cast(flag); - setFlags(newFlags); -} - -QGV::ItemFlags QGVDrawItem::getFlags() const -{ - return mFlags; -} - -bool QGVDrawItem::isFlag(QGV::ItemFlag flag) const -{ - return getFlags().testFlag(flag); -} - -void QGVDrawItem::refresh() -{ - if (mQGDrawItem.isNull()) { - return; - } - if (!isVisible()) { - mQGDrawItem->hide(); - return; - } - - QTransform userTransform; - if (isFlag(QGV::ItemFlag::Transformed)) { - userTransform = projTransform(); - } - QTransform itemTransform; - if (isFlag(QGV::ItemFlag::Highlighted) || isFlag(QGV::ItemFlag::IgnoreScale) || - isFlag(QGV::ItemFlag::IgnoreAzimuth)) { - double scale = 1.0; - double azimuth = 0.0; - if (isFlag(QGV::ItemFlag::Highlighted) && !isFlag(QGV::ItemFlag::HighlightCustom)) { - scale *= highlightScale; - } - if (isFlag(QGV::ItemFlag::IgnoreScale)) { - scale *= 1.0 / getMap()->getCamera().scale(); - } - if (isFlag(QGV::ItemFlag::IgnoreAzimuth)) { - azimuth += -getMap()->getCamera().azimuth(); - } - itemTransform = QGV::createTransfrom(projAnchor(), scale, azimuth); - } - mQGDrawItem->resetTransform(); - mQGDrawItem->setTransform(userTransform, true); - mQGDrawItem->setTransform(itemTransform, true); - mQGDrawItem->setVisible(effectivelyVisible()); - mQGDrawItem->setOpacity(effectiveOpacity()); - mQGDrawItem->setZValue(effectiveZValue()); - mQGDrawItem->setAcceptHoverEvents(isFlag(QGV::ItemFlag::Highlightable)); - if (QGV::isDrawDebug()) { - setProperty("updateCount", property("updateCount").toInt() + 1); - } -} - -void QGVDrawItem::repaint() -{ - if (!mQGDrawItem.isNull()) { - mQGDrawItem->update(); - } -} - -void QGVDrawItem::resetBoundary() -{ - if (!mQGDrawItem.isNull()) { - mQGDrawItem->resetGeometry(); - } -} - -QTransform QGVDrawItem::effectiveTransform() const -{ - if (mQGDrawItem.isNull()) { - return {}; - } - return mQGDrawItem->transform(); -} - -QPointF QGVDrawItem::projAnchor() const -{ - return projShape().boundingRect().center(); -} - -QTransform QGVDrawItem::projTransform() const -{ - return {}; -} - -QString QGVDrawItem::projTooltip(const QPointF& /*projPos*/) const -{ - return {}; -} - -QString QGVDrawItem::projDebug() -{ - return QString("%1\nupdate(%2,%3)") - .arg(property("drawDebug").toString()) - .arg(property("updateCount").toInt()) - .arg(property("paintCount").toInt()) - .trimmed(); -} - -void QGVDrawItem::projOnFlags() -{ -} - -void QGVDrawItem::projOnMouseClick(const QPointF& projPos) -{ - auto geoMap = getMap(); - if (geoMap != nullptr) { - Q_EMIT geoMap->itemClicked(this, projPos); - } -} - -void QGVDrawItem::projOnMouseDoubleClick(const QPointF& projPos) -{ - auto geoMap = getMap(); - if (geoMap != nullptr) { - Q_EMIT geoMap->itemDoubleClicked(this, projPos); - } -} - -void QGVDrawItem::onProjection(QGVMap* geoMap) -{ - QGVItem::onProjection(geoMap); - if (!mQGDrawItem.isNull()) { - if (mQGDrawItem->scene() != geoMap->geoView()->scene()) { - onClean(); - } - } - if (mQGDrawItem.isNull()) { - mQGDrawItem.reset(new QGVMapQGItem(this)); - geoMap->geoView()->scene()->addItem(mQGDrawItem.data()); - } -} - -void QGVDrawItem::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) -{ - QGVItem::onCamera(oldState, newState); - bool neededUpdate = - (mFlags.testFlag(QGV::ItemFlag::IgnoreAzimuth) && !qFuzzyCompare(oldState.azimuth(), newState.azimuth())) || - (mFlags.testFlag(QGV::ItemFlag::IgnoreScale) && !qFuzzyCompare(oldState.scale(), newState.scale())); - if (!neededUpdate) { - return; - } - refresh(); - repaint(); -} - -void QGVDrawItem::onUpdate() -{ - QGVItem::onUpdate(); - refresh(); - repaint(); -} - -void QGVDrawItem::onClean() -{ - QGVItem::onClean(); - mQGDrawItem.reset(nullptr); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVDrawItem.h" +#include "QGVMapQGItem.h" +#include "QGVMapQGView.h" + +namespace { +double highlightScale = 1.15; +} + +QGVDrawItem::QGVDrawItem() +{} + +void QGVDrawItem::setFlags(QGV::ItemFlags flags) +{ + if (mFlags != flags) { + mFlags = flags; + projOnFlags(); + refresh(); + repaint(); + } +} + +void QGVDrawItem::setFlag(QGV::ItemFlag flag, bool enabled) +{ + QGV::ItemFlags newFlags = getFlags(); + if (enabled) + newFlags |= flag; + else + newFlags &= ~static_cast(flag); + setFlags(newFlags); +} + +QGV::ItemFlags QGVDrawItem::getFlags() const +{ + return mFlags; +} + +bool QGVDrawItem::isFlag(QGV::ItemFlag flag) const +{ + return getFlags().testFlag(flag); +} + +void QGVDrawItem::refresh() +{ + if (mQGDrawItem.isNull()) { + return; + } + if (!isVisible()) { + mQGDrawItem->hide(); + return; + } + + QTransform userTransform; + if (isFlag(QGV::ItemFlag::Transformed)) { + userTransform = projTransform(); + } + QTransform itemTransform; + if (isFlag(QGV::ItemFlag::Highlighted) || isFlag(QGV::ItemFlag::IgnoreScale) || + isFlag(QGV::ItemFlag::IgnoreAzimuth)) { + double scale = 1.0; + double azimuth = 0.0; + if (isFlag(QGV::ItemFlag::Highlighted) && !isFlag(QGV::ItemFlag::HighlightCustom)) { + scale *= highlightScale; + } + if (isFlag(QGV::ItemFlag::IgnoreScale)) { + scale *= 1.0 / getMap()->getCamera().scale(); + } + if (isFlag(QGV::ItemFlag::IgnoreAzimuth)) { + azimuth += -getMap()->getCamera().azimuth(); + } + itemTransform = QGV::createTransfrom(projAnchor(), scale, azimuth); + } + mQGDrawItem->resetTransform(); + mQGDrawItem->setTransform(userTransform, true); + mQGDrawItem->setTransform(itemTransform, true); + mQGDrawItem->setVisible(effectivelyVisible()); + mQGDrawItem->setOpacity(effectiveOpacity()); + mQGDrawItem->setZValue(effectiveZValue()); + mQGDrawItem->setAcceptHoverEvents(isFlag(QGV::ItemFlag::Highlightable)); + if (QGV::isDrawDebug()) { + setProperty("updateCount", property("updateCount").toInt() + 1); + } +} + +void QGVDrawItem::repaint() +{ + if (!mQGDrawItem.isNull()) { + mQGDrawItem->update(); + } +} + +void QGVDrawItem::resetBoundary() +{ + if (!mQGDrawItem.isNull()) { + mQGDrawItem->resetGeometry(); + } +} + +QTransform QGVDrawItem::effectiveTransform() const +{ + if (mQGDrawItem.isNull()) { + return {}; + } + return mQGDrawItem->transform(); +} + +QPointF QGVDrawItem::projAnchor() const +{ + return projShape().boundingRect().center(); +} + +QTransform QGVDrawItem::projTransform() const +{ + return {}; +} + +QString QGVDrawItem::projTooltip(const QPointF& /*projPos*/) const +{ + return {}; +} + +QString QGVDrawItem::projDebug() +{ + return QString("%1\nupdate(%2,%3)") + .arg(property("drawDebug").toString()) + .arg(property("updateCount").toInt()) + .arg(property("paintCount").toInt()) + .trimmed(); +} + +void QGVDrawItem::projOnFlags() +{} + +void QGVDrawItem::projOnMouseClick(const QPointF& projPos) +{ + auto geoMap = getMap(); + if (geoMap != nullptr) { + Q_EMIT geoMap->itemClicked(this, projPos); + } +} + +void QGVDrawItem::projOnMouseDoubleClick(const QPointF& projPos) +{ + auto geoMap = getMap(); + if (geoMap != nullptr) { + Q_EMIT geoMap->itemDoubleClicked(this, projPos); + } +} + +void QGVDrawItem::onProjection(QGVMap* geoMap) +{ + QGVItem::onProjection(geoMap); + if (!mQGDrawItem.isNull()) { + if (mQGDrawItem->scene() != geoMap->geoView()->scene()) { + onClean(); + } + } + if (mQGDrawItem.isNull()) { + mQGDrawItem.reset(new QGVMapQGItem(this)); + geoMap->geoView()->scene()->addItem(mQGDrawItem.data()); + } +} + +void QGVDrawItem::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) +{ + QGVItem::onCamera(oldState, newState); + bool neededUpdate = + (mFlags.testFlag(QGV::ItemFlag::IgnoreAzimuth) && !qFuzzyCompare(oldState.azimuth(), newState.azimuth())) || + (mFlags.testFlag(QGV::ItemFlag::IgnoreScale) && !qFuzzyCompare(oldState.scale(), newState.scale())); + if (!neededUpdate) { + return; + } + refresh(); + repaint(); +} + +void QGVDrawItem::onUpdate() +{ + QGVItem::onUpdate(); + refresh(); + repaint(); +} + +void QGVDrawItem::onClean() +{ + QGVItem::onClean(); + mQGDrawItem.reset(nullptr); +} diff --git a/lib/src/QGVGlobal.cpp b/lib/src/QGVGlobal.cpp index a832e72..3e683d7 100644 --- a/lib/src/QGVGlobal.cpp +++ b/lib/src/QGVGlobal.cpp @@ -1,505 +1,495 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVGlobal.h" -#include "QGVMap.h" - -#include -#include -#include - -namespace { -bool drawDebugEnabled = false; -bool printDebugEnabled = false; -QNetworkAccessManager* networkManager = nullptr; -} - -namespace QGV { - -GeoPos::GeoPos() - : mLat(0) - , mLon(0) -{ -} - -GeoPos::GeoPos(double lat, double lon) -{ - setLat(lat); - setLon(lon); -} - -GeoPos::GeoPos(const GeoPos& other) - : mLat(other.latitude()) - , mLon(other.longitude()) -{ -} - -GeoPos::GeoPos(const GeoPos&& other) - : mLat(std::move(other.latitude())) - , mLon(std::move(other.longitude())) -{ -} - -GeoPos& GeoPos::operator=(const GeoPos& other) -{ - mLat = other.latitude(); - mLon = other.longitude(); - return *this; -} - -GeoPos& GeoPos::operator=(const GeoPos&& other) -{ - mLat = std::move(other.latitude()); - mLon = std::move(other.longitude()); - return *this; -} - -double GeoPos::latitude() const -{ - return mLat; -} -double GeoPos::longitude() const -{ - return mLon; -} - -void GeoPos::setLat(double lat) -{ - mLat = qMax(-90.0, lat); - mLat = qMin(90.0, lat); -} - -void GeoPos::setLon(double lon) -{ - if (lon > 180.000001) { - lon = fmod((180.0 + lon), 360.0) - 180.0; - } else { - if (lon < -180.000001) { - lon = 180.0 - fmod((180.0 - lon), 360.0); - } - } - mLon = lon; -} - -QString GeoPos::lonToString(const QString& format) const -{ - return lonToString(longitude(), format); -} - -QString GeoPos::latToString(const QString& format) const -{ - return latToString(latitude(), format); -} - -/*! - * Longitude to string - * Format: - * [+-] - sign - * d - degree (unsigned) - * di - degree integer part only(unsigned) - * m - minute only(unsigned) - * mi - minute integer part only(unsigned) - * s - second (unsigned) - * si - second integer part only(unsigned) - * \brief lonToString - * \param lon - * \param aFormat - * \return - */ -QString GeoPos::lonToString(double lon, const QString& format) -{ - QString result = format; - - const QString signSymb = (lon < 0) ? "-" : QString(); - const double degreePart = qAbs(lon); - const double minPart = (degreePart - static_cast(degreePart)) * 60.0; - const double secPart = (minPart - static_cast(minPart)) * 60.0; - - result.replace("[+-]", signSymb); - result.replace("di", QString::number(static_cast(degreePart))); - result.replace("d", QString::number(degreePart, 'f', 6)); - result.replace("mi", QString::number(static_cast(minPart))); - result.replace("m", QString::number(minPart, 'f', 4)); - result.replace("si", QString::number(static_cast(secPart))); - result.replace("s", QString::number(secPart, 'f', 3)); - - return result; -} - -/*! - * Latitude to string - * Format: - * [+-] - sign - * [NS] - North or South - * d - degree (unsigned) - * di - degree integer part only(unsigned) - * m - minute only(unsigned) - * mi - minute integer part only(unsigned) - * s - second (unsigned) - * si - second integer part only(unsigned) - */ -QString GeoPos::latToString(double lat, const QString& format) -{ - QString result = format; - - const QString signSymb = (lat < 0) ? "-" : QString(); - const QString northSouth = (lat < 0) ? "N" : "S"; - const double degreePart = qAbs(lat); - const double minPart = (degreePart - static_cast(degreePart)) * 60.0; - const double secPart = (minPart - static_cast(minPart)) * 60.0; - - result.replace("[+-]", signSymb); - result.replace("[NS]", northSouth); - result.replace("di", QString::number(static_cast(degreePart))); - result.replace("d", QString::number(degreePart, 'f', 6)); - result.replace("mi", QString::number(static_cast(minPart))); - result.replace("m", QString::number(minPart, 'f', 4)); - result.replace("si", QString::number(static_cast(secPart))); - result.replace("s", QString::number(secPart, 'f', 3)); - - return result; -} - -GeoRect::GeoRect() -{ -} - -GeoRect::GeoRect(double lat1, double lon1, double lat2, double lon2) -{ - mTopLeft = GeoPos(qMax(lat1, lat2), qMin(lon1, lon2)); - mBottomRight = GeoPos(qMin(lat1, lat2), qMax(lon1, lon2)); -} - -GeoRect::GeoRect(GeoPos const& pos1, GeoPos const& pos2) -{ - mTopLeft = GeoPos(qMax(pos1.latitude(), pos2.latitude()), qMin(pos1.longitude(), pos2.longitude())); - mBottomRight = GeoPos(qMin(pos1.latitude(), pos2.latitude()), qMax(pos1.longitude(), pos2.longitude())); -} - -GeoRect::GeoRect(const GeoRect& other) - : mTopLeft(other.mTopLeft) - , mBottomRight(other.mBottomRight) -{ -} - -GeoRect::GeoRect(const GeoRect&& other) - : mTopLeft(std::move(other.mTopLeft)) - , mBottomRight(std::move(other.mBottomRight)) -{ -} - -GeoRect& GeoRect::operator=(const GeoRect& other) -{ - mTopLeft = other.mTopLeft; - mBottomRight = other.mBottomRight; - return *this; -} - -GeoRect& GeoRect::operator=(const GeoRect&& other) -{ - mTopLeft = std::move(other.mTopLeft); - mBottomRight = std::move(other.mBottomRight); - return *this; -} - -GeoPos GeoRect::topLeft() const -{ - return mTopLeft; -} - -GeoPos GeoRect::topRight() const -{ - return GeoPos(mTopLeft.latitude(), mBottomRight.longitude()); -} - -GeoPos GeoRect::bottomLeft() const -{ - return GeoPos(mBottomRight.latitude(), mTopLeft.longitude()); -} - -GeoPos GeoRect::bottomRight() const -{ - return mBottomRight; -} - -double GeoRect::lonLeft() const -{ - return mTopLeft.longitude(); -} - -double GeoRect::lonRigth() const -{ - return mBottomRight.longitude(); -} - -double GeoRect::latBottom() const -{ - return mBottomRight.latitude(); -} - -double GeoRect::latTop() const -{ - return mTopLeft.latitude(); -} - -bool GeoRect::contains(GeoPos const& pos) const -{ - return (lonLeft() <= pos.longitude() && pos.longitude() < lonRigth() && latBottom() < pos.latitude() && - pos.latitude() <= latTop()); -} - -bool GeoRect::contains(GeoRect const& rect) const -{ - return (lonLeft() <= rect.lonLeft() && rect.lonRigth() <= lonRigth() && latBottom() <= rect.latBottom() && - rect.latTop() <= latTop()); -} - -bool GeoRect::intersects(const GeoRect& rect) const -{ - return contains(rect.topLeft()) || contains(rect.topRight()) || contains(rect.bottomLeft()) || - contains(rect.bottomRight()) || rect.contains(topLeft()) || rect.contains(topRight()) || - rect.contains(bottomLeft()) || rect.contains(bottomRight()); -} - -GeoTilePos::GeoTilePos() - : mZoom(-1) -{ -} - -GeoTilePos::GeoTilePos(int zoom, const QPoint& pos) - : mZoom(zoom) - , mPos(pos) -{ -} - -GeoTilePos::GeoTilePos(const GeoTilePos& other) - : mZoom(other.mZoom) - , mPos(other.mPos) -{ -} - -GeoTilePos::GeoTilePos(const GeoTilePos&& other) - : mZoom(std::move(other.mZoom)) - , mPos(std::move(other.mPos)) -{ -} - -GeoTilePos& GeoTilePos::operator=(const GeoTilePos& other) -{ - mZoom = other.mZoom; - mPos = other.mPos; - return *this; -} - -GeoTilePos& GeoTilePos::operator=(const GeoTilePos&& other) -{ - mZoom = std::move(other.mZoom); - mPos = std::move(other.mPos); - return *this; -} - -bool GeoTilePos::operator<(const GeoTilePos& other) const -{ - if (mZoom < other.mZoom) { - return true; - } - if (mZoom > other.mZoom) { - return false; - } - if (mPos.x() < other.mPos.x()) { - return true; - } - if (mPos.x() > other.mPos.x()) { - return false; - } - return mPos.y() < other.mPos.y(); -} - -int GeoTilePos::zoom() const -{ - return mZoom; -} - -QPoint GeoTilePos::pos() const -{ - return mPos; -} - -bool GeoTilePos::contains(const GeoTilePos& other) const -{ - if (zoom() >= other.zoom()) { - return false; - } - GeoTilePos parentTile = other.parent(zoom()); - return (pos().x() == parentTile.pos().x() && pos().y() == parentTile.pos().y()); -} - -GeoTilePos GeoTilePos::parent(int parentZoom) const -{ - if (parentZoom >= zoom()) { - return GeoTilePos(); - } - const int deltaZoom = zoom() - parentZoom; - const int factor = static_cast(qPow(2, deltaZoom)); - const int x = static_cast(qFloor(pos().x() / factor)); - const int y = static_cast(qFloor(pos().y() / factor)); - return GeoTilePos(parentZoom, QPoint(x, y)); -} - -GeoRect GeoTilePos::toGeoRect() const -{ - const auto leftTop = [](const GeoTilePos& tilePos) -> GeoPos { - const int zoom = tilePos.zoom(); - const int x = tilePos.pos().x(); - const int y = tilePos.pos().y(); - const double lon = x / pow(2.0, zoom) * 360.0 - 180; - const double n = M_PI - 2.0 * M_PI * y / pow(2.0, zoom); - const double lat = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); - return GeoPos(lat, lon); - }; - const GeoPos pos1 = leftTop(*this); - const GeoPos pos2 = leftTop(GeoTilePos(mZoom, mPos + QPoint(1, 1))); - return GeoRect(pos1, pos2); -} - -QString GeoTilePos::toQuadKey() const -{ - const int x = mPos.x(); - const int y = mPos.y(); - QString quadKey; - for (int i = mZoom; i > 0; i--) { - char cDigit = '0'; - int iMask = 1 << (i - 1); - if ((x & iMask) != 0) { - cDigit++; - } - if ((y & iMask) != 0) { - cDigit++; - cDigit++; - } - quadKey.append(cDigit); - } - return quadKey; -} - -GeoTilePos GeoTilePos::geoToTilePos(int zoom, const GeoPos& geoPos) -{ - const double lon = geoPos.longitude(); - const double lat = geoPos.latitude(); - const double x = floor((lon + 180.0) / 360.0 * pow(2.0, zoom)); - const double y = - floor((1.0 - log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0 * pow(2.0, zoom)); - return GeoTilePos(zoom, QPoint(static_cast(x), static_cast(y))); -} - -QTransform createTransfrom(const QPointF& projAnchor, double scale, double azimuth) -{ - const bool scaleChanged = !qFuzzyCompare(scale, 1.0); - const bool azimuthChanged = !qFuzzyIsNull(azimuth); - if (!scaleChanged && !azimuthChanged) { - return {}; - } - QTransform transform; - transform.translate(projAnchor.x(), projAnchor.y()); - if (scaleChanged) { - transform.scale(scale, scale); - } - if (azimuthChanged) { - transform.rotate(azimuth); - } - transform.translate(-projAnchor.x(), -projAnchor.y()); - return transform; -} - -QTransform createTransfromScale(const QPointF& projAnchor, double scale) -{ - return createTransfrom(projAnchor, scale, 0.0); -} - -QTransform createTransfromAzimuth(const QPointF& projAnchor, double azimuth) -{ - return createTransfrom(projAnchor, 1.0, azimuth); -} - -QPainterPath createTextPath(const QRect& rect, const QString& text, const QFont& font, int penWidth) -{ - const QStringList txtList = text.split("\n"); - const int lineHeight = QFontMetrics(font).height(); - QPainterPath path; - for (int i = 0; i < txtList.size(); i++) { - path.addText(QPoint(0, i * lineHeight), font, txtList[i]); - } - const QPointF centerDelta = rect.center() - path.boundingRect().center(); - const double scaleDelta = (rect.width() - penWidth) / path.boundingRect().width(); - path.translate(centerDelta + QPointF(penWidth, penWidth) / scaleDelta); - path = createTransfromScale(rect.center(), scaleDelta).map(path); - return path; -} - -void setDrawDebug(bool enabled) -{ - drawDebugEnabled = enabled; -} - -bool isDrawDebug() -{ - return drawDebugEnabled; -} - -void setPrintDebug(bool enabled) -{ - printDebugEnabled = enabled; -} - -bool isPrintDebug() -{ - return printDebugEnabled; -} - -void setNetworkManager(QNetworkAccessManager* manager) -{ - networkManager = manager; -} - -QNetworkAccessManager* getNetworkManager() -{ - return networkManager; -} - -} // namespace QGV - -QDebug operator<<(QDebug debug, const QGV::GeoPos& value) -{ - QDebugStateSaver saver(debug); - debug.nospace().noquote() << "QGV::GeoPos(" << value.latToString() << ", " << value.lonToString() << ")"; - return debug; -} - -QDebug operator<<(QDebug debug, const QGV::GeoRect& value) -{ - QDebugStateSaver saver(debug); - debug.nospace().noquote() << "QGV::GeoRect(" << value.topLeft() << ", " << value.bottomRight() << ")"; - return debug; -} - -QDebug operator<<(QDebug debug, const QGV::GeoTilePos& value) -{ - QDebugStateSaver saver(debug); - debug.nospace().noquote() << "QGV::GeoTilePos(" << value.zoom() << ", " << value.pos() << ")"; - return debug; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVGlobal.h" +#include "QGVMap.h" + +#include +#include +#include + +namespace { +bool drawDebugEnabled = false; +bool printDebugEnabled = false; +QNetworkAccessManager* networkManager = nullptr; +} + +namespace QGV { + +GeoPos::GeoPos() + : mLat(0) + , mLon(0) +{} + +GeoPos::GeoPos(double lat, double lon) +{ + setLat(lat); + setLon(lon); +} + +GeoPos::GeoPos(const GeoPos& other) + : mLat(other.latitude()) + , mLon(other.longitude()) +{} + +GeoPos::GeoPos(const GeoPos&& other) + : mLat(std::move(other.latitude())) + , mLon(std::move(other.longitude())) +{} + +GeoPos& GeoPos::operator=(const GeoPos& other) +{ + mLat = other.latitude(); + mLon = other.longitude(); + return *this; +} + +GeoPos& GeoPos::operator=(const GeoPos&& other) +{ + mLat = std::move(other.latitude()); + mLon = std::move(other.longitude()); + return *this; +} + +double GeoPos::latitude() const +{ + return mLat; +} +double GeoPos::longitude() const +{ + return mLon; +} + +void GeoPos::setLat(double lat) +{ + mLat = qMax(-90.0, lat); + mLat = qMin(90.0, lat); +} + +void GeoPos::setLon(double lon) +{ + if (lon > 180.000001) { + lon = fmod((180.0 + lon), 360.0) - 180.0; + } else { + if (lon < -180.000001) { + lon = 180.0 - fmod((180.0 - lon), 360.0); + } + } + mLon = lon; +} + +QString GeoPos::lonToString(const QString& format) const +{ + return lonToString(longitude(), format); +} + +QString GeoPos::latToString(const QString& format) const +{ + return latToString(latitude(), format); +} + +/*! + * Longitude to string + * Format: + * [+-] - sign + * d - degree (unsigned) + * di - degree integer part only(unsigned) + * m - minute only(unsigned) + * mi - minute integer part only(unsigned) + * s - second (unsigned) + * si - second integer part only(unsigned) + * \brief lonToString + * \param lon + * \param aFormat + * \return + */ +QString GeoPos::lonToString(double lon, const QString& format) +{ + QString result = format; + + const QString signSymb = (lon < 0) ? "-" : QString(); + const double degreePart = qAbs(lon); + const double minPart = (degreePart - static_cast(degreePart)) * 60.0; + const double secPart = (minPart - static_cast(minPart)) * 60.0; + + result.replace("[+-]", signSymb); + result.replace("di", QString::number(static_cast(degreePart))); + result.replace("d", QString::number(degreePart, 'f', 6)); + result.replace("mi", QString::number(static_cast(minPart))); + result.replace("m", QString::number(minPart, 'f', 4)); + result.replace("si", QString::number(static_cast(secPart))); + result.replace("s", QString::number(secPart, 'f', 3)); + + return result; +} + +/*! + * Latitude to string + * Format: + * [+-] - sign + * [NS] - North or South + * d - degree (unsigned) + * di - degree integer part only(unsigned) + * m - minute only(unsigned) + * mi - minute integer part only(unsigned) + * s - second (unsigned) + * si - second integer part only(unsigned) + */ +QString GeoPos::latToString(double lat, const QString& format) +{ + QString result = format; + + const QString signSymb = (lat < 0) ? "-" : QString(); + const QString northSouth = (lat < 0) ? "N" : "S"; + const double degreePart = qAbs(lat); + const double minPart = (degreePart - static_cast(degreePart)) * 60.0; + const double secPart = (minPart - static_cast(minPart)) * 60.0; + + result.replace("[+-]", signSymb); + result.replace("[NS]", northSouth); + result.replace("di", QString::number(static_cast(degreePart))); + result.replace("d", QString::number(degreePart, 'f', 6)); + result.replace("mi", QString::number(static_cast(minPart))); + result.replace("m", QString::number(minPart, 'f', 4)); + result.replace("si", QString::number(static_cast(secPart))); + result.replace("s", QString::number(secPart, 'f', 3)); + + return result; +} + +GeoRect::GeoRect() +{} + +GeoRect::GeoRect(double lat1, double lon1, double lat2, double lon2) +{ + mTopLeft = GeoPos(qMax(lat1, lat2), qMin(lon1, lon2)); + mBottomRight = GeoPos(qMin(lat1, lat2), qMax(lon1, lon2)); +} + +GeoRect::GeoRect(GeoPos const& pos1, GeoPos const& pos2) +{ + mTopLeft = GeoPos(qMax(pos1.latitude(), pos2.latitude()), qMin(pos1.longitude(), pos2.longitude())); + mBottomRight = GeoPos(qMin(pos1.latitude(), pos2.latitude()), qMax(pos1.longitude(), pos2.longitude())); +} + +GeoRect::GeoRect(const GeoRect& other) + : mTopLeft(other.mTopLeft) + , mBottomRight(other.mBottomRight) +{} + +GeoRect::GeoRect(const GeoRect&& other) + : mTopLeft(std::move(other.mTopLeft)) + , mBottomRight(std::move(other.mBottomRight)) +{} + +GeoRect& GeoRect::operator=(const GeoRect& other) +{ + mTopLeft = other.mTopLeft; + mBottomRight = other.mBottomRight; + return *this; +} + +GeoRect& GeoRect::operator=(const GeoRect&& other) +{ + mTopLeft = std::move(other.mTopLeft); + mBottomRight = std::move(other.mBottomRight); + return *this; +} + +GeoPos GeoRect::topLeft() const +{ + return mTopLeft; +} + +GeoPos GeoRect::topRight() const +{ + return GeoPos(mTopLeft.latitude(), mBottomRight.longitude()); +} + +GeoPos GeoRect::bottomLeft() const +{ + return GeoPos(mBottomRight.latitude(), mTopLeft.longitude()); +} + +GeoPos GeoRect::bottomRight() const +{ + return mBottomRight; +} + +double GeoRect::lonLeft() const +{ + return mTopLeft.longitude(); +} + +double GeoRect::lonRigth() const +{ + return mBottomRight.longitude(); +} + +double GeoRect::latBottom() const +{ + return mBottomRight.latitude(); +} + +double GeoRect::latTop() const +{ + return mTopLeft.latitude(); +} + +bool GeoRect::contains(GeoPos const& pos) const +{ + return (lonLeft() <= pos.longitude() && pos.longitude() < lonRigth() && latBottom() < pos.latitude() && + pos.latitude() <= latTop()); +} + +bool GeoRect::contains(GeoRect const& rect) const +{ + return (lonLeft() <= rect.lonLeft() && rect.lonRigth() <= lonRigth() && latBottom() <= rect.latBottom() && + rect.latTop() <= latTop()); +} + +bool GeoRect::intersects(const GeoRect& rect) const +{ + return contains(rect.topLeft()) || contains(rect.topRight()) || contains(rect.bottomLeft()) || + contains(rect.bottomRight()) || rect.contains(topLeft()) || rect.contains(topRight()) || + rect.contains(bottomLeft()) || rect.contains(bottomRight()); +} + +GeoTilePos::GeoTilePos() + : mZoom(-1) +{} + +GeoTilePos::GeoTilePos(int zoom, const QPoint& pos) + : mZoom(zoom) + , mPos(pos) +{} + +GeoTilePos::GeoTilePos(const GeoTilePos& other) + : mZoom(other.mZoom) + , mPos(other.mPos) +{} + +GeoTilePos::GeoTilePos(const GeoTilePos&& other) + : mZoom(std::move(other.mZoom)) + , mPos(std::move(other.mPos)) +{} + +GeoTilePos& GeoTilePos::operator=(const GeoTilePos& other) +{ + mZoom = other.mZoom; + mPos = other.mPos; + return *this; +} + +GeoTilePos& GeoTilePos::operator=(const GeoTilePos&& other) +{ + mZoom = std::move(other.mZoom); + mPos = std::move(other.mPos); + return *this; +} + +bool GeoTilePos::operator<(const GeoTilePos& other) const +{ + if (mZoom < other.mZoom) { + return true; + } + if (mZoom > other.mZoom) { + return false; + } + if (mPos.x() < other.mPos.x()) { + return true; + } + if (mPos.x() > other.mPos.x()) { + return false; + } + return mPos.y() < other.mPos.y(); +} + +int GeoTilePos::zoom() const +{ + return mZoom; +} + +QPoint GeoTilePos::pos() const +{ + return mPos; +} + +bool GeoTilePos::contains(const GeoTilePos& other) const +{ + if (zoom() >= other.zoom()) { + return false; + } + GeoTilePos parentTile = other.parent(zoom()); + return (pos().x() == parentTile.pos().x() && pos().y() == parentTile.pos().y()); +} + +GeoTilePos GeoTilePos::parent(int parentZoom) const +{ + if (parentZoom >= zoom()) { + return GeoTilePos(); + } + const int deltaZoom = zoom() - parentZoom; + const int factor = static_cast(qPow(2, deltaZoom)); + const int x = static_cast(qFloor(pos().x() / factor)); + const int y = static_cast(qFloor(pos().y() / factor)); + return GeoTilePos(parentZoom, QPoint(x, y)); +} + +GeoRect GeoTilePos::toGeoRect() const +{ + const auto leftTop = [](const GeoTilePos& tilePos) -> GeoPos { + const int zoom = tilePos.zoom(); + const int x = tilePos.pos().x(); + const int y = tilePos.pos().y(); + const double lon = x / pow(2.0, zoom) * 360.0 - 180; + const double n = M_PI - 2.0 * M_PI * y / pow(2.0, zoom); + const double lat = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); + return GeoPos(lat, lon); + }; + const GeoPos pos1 = leftTop(*this); + const GeoPos pos2 = leftTop(GeoTilePos(mZoom, mPos + QPoint(1, 1))); + return GeoRect(pos1, pos2); +} + +QString GeoTilePos::toQuadKey() const +{ + const int x = mPos.x(); + const int y = mPos.y(); + QString quadKey; + for (int i = mZoom; i > 0; i--) { + char cDigit = '0'; + int iMask = 1 << (i - 1); + if ((x & iMask) != 0) { + cDigit++; + } + if ((y & iMask) != 0) { + cDigit++; + cDigit++; + } + quadKey.append(cDigit); + } + return quadKey; +} + +GeoTilePos GeoTilePos::geoToTilePos(int zoom, const GeoPos& geoPos) +{ + const double lon = geoPos.longitude(); + const double lat = geoPos.latitude(); + const double x = floor((lon + 180.0) / 360.0 * pow(2.0, zoom)); + const double y = + floor((1.0 - log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0 * pow(2.0, zoom)); + return GeoTilePos(zoom, QPoint(static_cast(x), static_cast(y))); +} + +QTransform createTransfrom(const QPointF& projAnchor, double scale, double azimuth) +{ + const bool scaleChanged = !qFuzzyCompare(scale, 1.0); + const bool azimuthChanged = !qFuzzyIsNull(azimuth); + if (!scaleChanged && !azimuthChanged) { + return {}; + } + QTransform transform; + transform.translate(projAnchor.x(), projAnchor.y()); + if (scaleChanged) { + transform.scale(scale, scale); + } + if (azimuthChanged) { + transform.rotate(azimuth); + } + transform.translate(-projAnchor.x(), -projAnchor.y()); + return transform; +} + +QTransform createTransfromScale(const QPointF& projAnchor, double scale) +{ + return createTransfrom(projAnchor, scale, 0.0); +} + +QTransform createTransfromAzimuth(const QPointF& projAnchor, double azimuth) +{ + return createTransfrom(projAnchor, 1.0, azimuth); +} + +QPainterPath createTextPath(const QRect& rect, const QString& text, const QFont& font, int penWidth) +{ + const QStringList txtList = text.split("\n"); + const int lineHeight = QFontMetrics(font).height(); + QPainterPath path; + for (int i = 0; i < txtList.size(); i++) { + path.addText(QPoint(0, i * lineHeight), font, txtList[i]); + } + const QPointF centerDelta = rect.center() - path.boundingRect().center(); + const double scaleDelta = (rect.width() - penWidth) / path.boundingRect().width(); + path.translate(centerDelta + QPointF(penWidth, penWidth) / scaleDelta); + path = createTransfromScale(rect.center(), scaleDelta).map(path); + return path; +} + +void setDrawDebug(bool enabled) +{ + drawDebugEnabled = enabled; +} + +bool isDrawDebug() +{ + return drawDebugEnabled; +} + +void setPrintDebug(bool enabled) +{ + printDebugEnabled = enabled; +} + +bool isPrintDebug() +{ + return printDebugEnabled; +} + +void setNetworkManager(QNetworkAccessManager* manager) +{ + networkManager = manager; +} + +QNetworkAccessManager* getNetworkManager() +{ + return networkManager; +} + +} // namespace QGV + +QDebug operator<<(QDebug debug, const QGV::GeoPos& value) +{ + QDebugStateSaver saver(debug); + debug.nospace().noquote() << "QGV::GeoPos(" << value.latToString() << ", " << value.lonToString() << ")"; + return debug; +} + +QDebug operator<<(QDebug debug, const QGV::GeoRect& value) +{ + QDebugStateSaver saver(debug); + debug.nospace().noquote() << "QGV::GeoRect(" << value.topLeft() << ", " << value.bottomRight() << ")"; + return debug; +} + +QDebug operator<<(QDebug debug, const QGV::GeoTilePos& value) +{ + QDebugStateSaver saver(debug); + debug.nospace().noquote() << "QGV::GeoTilePos(" << value.zoom() << ", " << value.pos() << ")"; + return debug; +} diff --git a/lib/src/QGVImage.cpp b/lib/src/QGVImage.cpp index 29db8f3..f82f9d8 100644 --- a/lib/src/QGVImage.cpp +++ b/lib/src/QGVImage.cpp @@ -1,155 +1,155 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVImage.h" -#include "QGVMap.h" - -#include -#include -#include - -QGVImage::QGVImage() - : mGeometryType(GeometryType::ByRect) -{ -} - -void QGVImage::setGeometry(const QGV::GeoRect& geoRect) -{ - mGeometryType = GeometryType::ByRect; - mGeoRect = geoRect; - calculateGeometry(); -} - -void QGVImage::setGeometry(const QGV::GeoPos& geoPos, const QSize& imageSize, const QPoint& imageAnchor) -{ - mGeometryType = GeometryType::ByPos; - mGeoPos = geoPos; - mImageSize = imageSize; - mImageAnchor = imageAnchor; - calculateGeometry(); -} - -QImage QGVImage::getImage() const -{ - return mImage; -} - -bool QGVImage::isImage() const -{ - return !mImage.isNull(); -} - -void QGVImage::load(const QString& url) -{ - Q_ASSERT(QGV::getNetworkManager()); - QNetworkRequest request(url); - request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows; U; MSIE " - "6.0; Windows NT 5.1; SV1; .NET " - "CLR 2.0.50727)"); - request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - mReply.reset(QGV::getNetworkManager()->get(request)); - connect(mReply.data(), &QNetworkReply::finished, this, &QGVImage::onReplyFinished); - qgvDebug() << "request" << url; -} - -void QGVImage::loadImage(const QByteArray& rawData) -{ - QImage image; - image.loadFromData(rawData); - loadImage(image); -} - -void QGVImage::loadImage(const QImage& image) -{ - mImage = image; -} - -void QGVImage::onProjection(QGVMap* geoMap) -{ - QGVDrawItem::onProjection(geoMap); - calculateGeometry(); -} - -QPainterPath QGVImage::projShape() const -{ - QPainterPath path; - path.addRect(mProjRect); - return path; -} - -QPointF QGVImage::projAnchor() const -{ - if (mProjAnchor.isNull()) { - return QGVDrawItem::projAnchor(); - } - return mProjAnchor; -} - -void QGVImage::projPaint(QPainter* painter) -{ - if (mImage.isNull() || mProjRect.isEmpty()) { - return; - } - QRectF paintRect = mProjRect; - if (!isFlag(QGV::ItemFlag::IgnoreScale)) { - const double pixelFactor = 1.0 / getMap()->getCamera().scale(); - paintRect.setSize(paintRect.size() + QSizeF(pixelFactor, pixelFactor)); - } - painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->drawImage(paintRect, getImage()); -} - -void QGVImage::onReplyFinished() -{ - if (mReply.isNull()) { - return; - } - if (mReply->error() != QNetworkReply::NoError) { - qgvCritical() << "ERROR" << mReply->errorString(); - mReply.reset(nullptr); - return; - } - loadImage(mReply->readAll()); - mReply.reset(nullptr); -} - -void QGVImage::calculateGeometry() -{ - mProjRect = {}; - mProjAnchor = {}; - if (mGeometryType == GeometryType::None || getMap() == nullptr) { - return; - } - if (mGeometryType == GeometryType::ByRect) { - mProjRect = getMap()->getProjection()->geoToProj(mGeoRect); - resetBoundary(); - refresh(); - } else if (mGeometryType == GeometryType::ByPos) { - if (mImageSize.isEmpty() && mImage.isNull()) { - return; - } - const QPointF anchor = - (mImageAnchor.isNull()) ? QPointF(mImageSize.width() / 2, mImageSize.height() / 2) : mImageAnchor; - const QPointF basePos = getMap()->getProjection()->geoToProj(mGeoPos); - mProjRect = QRectF(basePos - anchor, mImageSize); - mProjAnchor = basePos; - resetBoundary(); - refresh(); - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVImage.h" +#include "QGVMap.h" + +#include +#include +#include + +QGVImage::QGVImage() + : mGeometryType(GeometryType::ByRect) +{} + +void QGVImage::setGeometry(const QGV::GeoRect& geoRect) +{ + mGeometryType = GeometryType::ByRect; + mGeoRect = geoRect; + calculateGeometry(); +} + +void QGVImage::setGeometry(const QGV::GeoPos& geoPos, const QSize& imageSize, const QPoint& imageAnchor) +{ + mGeometryType = GeometryType::ByPos; + mGeoPos = geoPos; + mImageSize = imageSize; + mImageAnchor = imageAnchor; + calculateGeometry(); +} + +QImage QGVImage::getImage() const +{ + return mImage; +} + +bool QGVImage::isImage() const +{ + return !mImage.isNull(); +} + +void QGVImage::load(const QString& url) +{ + Q_ASSERT(QGV::getNetworkManager()); + QNetworkRequest request(url); + request.setRawHeader("User-Agent", + "Mozilla/5.0 (Windows; U; MSIE " + "6.0; Windows NT 5.1; SV1; .NET " + "CLR 2.0.50727)"); + request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + mReply.reset(QGV::getNetworkManager()->get(request)); + connect(mReply.data(), &QNetworkReply::finished, this, &QGVImage::onReplyFinished); + qgvDebug() << "request" << url; +} + +void QGVImage::loadImage(const QByteArray& rawData) +{ + QImage image; + image.loadFromData(rawData); + loadImage(image); +} + +void QGVImage::loadImage(const QImage& image) +{ + mImage = image; +} + +void QGVImage::onProjection(QGVMap* geoMap) +{ + QGVDrawItem::onProjection(geoMap); + calculateGeometry(); +} + +QPainterPath QGVImage::projShape() const +{ + QPainterPath path; + path.addRect(mProjRect); + return path; +} + +QPointF QGVImage::projAnchor() const +{ + if (mProjAnchor.isNull()) { + return QGVDrawItem::projAnchor(); + } + return mProjAnchor; +} + +void QGVImage::projPaint(QPainter* painter) +{ + if (mImage.isNull() || mProjRect.isEmpty()) { + return; + } + QRectF paintRect = mProjRect; + if (!isFlag(QGV::ItemFlag::IgnoreScale)) { + const double pixelFactor = 1.0 / getMap()->getCamera().scale(); + paintRect.setSize(paintRect.size() + QSizeF(pixelFactor, pixelFactor)); + } + painter->setRenderHint(QPainter::SmoothPixmapTransform); + painter->drawImage(paintRect, getImage()); +} + +void QGVImage::onReplyFinished() +{ + if (mReply.isNull()) { + return; + } + if (mReply->error() != QNetworkReply::NoError) { + qgvCritical() << "ERROR" << mReply->errorString(); + mReply.reset(nullptr); + return; + } + loadImage(mReply->readAll()); + mReply.reset(nullptr); +} + +void QGVImage::calculateGeometry() +{ + mProjRect = {}; + mProjAnchor = {}; + if (mGeometryType == GeometryType::None || getMap() == nullptr) { + return; + } + if (mGeometryType == GeometryType::ByRect) { + mProjRect = getMap()->getProjection()->geoToProj(mGeoRect); + resetBoundary(); + refresh(); + } else if (mGeometryType == GeometryType::ByPos) { + if (mImageSize.isEmpty() && mImage.isNull()) { + return; + } + const QPointF anchor = + (mImageAnchor.isNull()) ? QPointF(mImageSize.width() / 2, mImageSize.height() / 2) : mImageAnchor; + const QPointF basePos = getMap()->getProjection()->geoToProj(mGeoPos); + mProjRect = QRectF(basePos - anchor, mImageSize); + mProjAnchor = basePos; + resetBoundary(); + refresh(); + } +} diff --git a/lib/src/QGVItem.cpp b/lib/src/QGVItem.cpp index 4a0cca7..014acb5 100644 --- a/lib/src/QGVItem.cpp +++ b/lib/src/QGVItem.cpp @@ -1,293 +1,292 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVItem.h" -#include - -QGVItem::QGVItem(QGVItem* parent) -{ - mParent = parent; - mZValue = 0; - mOpacity = 1.0; - mVisible = true; - mSelectable = false; - mSelected = false; -} - -QGVItem::~QGVItem() -{ - deleteItems(); - if (mParent != nullptr) { - mParent->mChildrens.removeAll(this); - } -} - -void QGVItem::setParent(QGVItem* item) -{ - if (mParent == item) { - return; - } - setSelected(false); - if (mParent != nullptr) { - mParent->mChildrens.removeAll(this); - } - auto oldParent = mParent; - mParent = item; - if (mParent != nullptr) { - mParent->mChildrens.append(this); - } - auto geoMap = getMap(); - if (geoMap != nullptr) { - if (oldParent != nullptr) { - Q_EMIT geoMap->itemsChanged(oldParent); - } - if (mParent != nullptr) { - Q_EMIT geoMap->itemsChanged(mParent); - } - onProjection(geoMap); - update(); - } else { - onClean(); - } -} - -QGVItem* QGVItem::getParent() const -{ - return mParent; -} - -QGVMap* QGVItem::getMap() const -{ - if (mParent != nullptr) { - return mParent->getMap(); - } - return nullptr; -} - -void QGVItem::addItem(QGVItem* item) -{ - Q_ASSERT(item); - item->setParent(this); -} - -void QGVItem::removeItem(QGVItem* item) -{ - Q_ASSERT(item); - if (item->getParent() != this) { - return; - } - item->setParent(nullptr); -} - -void QGVItem::deleteItems() -{ - auto copy = mChildrens; - qDeleteAll(copy.begin(), copy.end()); - mChildrens.clear(); -} - -int QGVItem::countItems() const -{ - return mChildrens.count(); -} - -QGVItem* QGVItem::getItem(int index) const -{ - return mChildrens.at(index); -} - -void QGVItem::setZValue(qint16 zValue) -{ - if (mZValue != zValue) { - mZValue = zValue; - update(); - } -} - -qint16 QGVItem::getZValue() const -{ - return mZValue; -} - -void QGVItem::bringToFront() -{ - mZValue = std::numeric_limits::max(); - update(); -} - -void QGVItem::sendToBack() -{ - mZValue = std::numeric_limits::min(); - update(); -} - -void QGVItem::setOpacity(double value) -{ - value = qMin(1.0, qMax(0.0, value)); - if (qFuzzyCompare(mOpacity, value)) { - return; - } - mOpacity = value; - update(); -} - -double QGVItem::getOpacity() const -{ - return mOpacity; -} - -void QGVItem::setSelectable(bool allowed) -{ - if (mSelectable == allowed) { - return; - } - mSelectable = allowed; - if (!mSelectable) { - setSelected(false); - } - onUpdate(); -} - -bool QGVItem::isSelectable() const -{ - return mSelectable; -} - -void QGVItem::setSelected(bool selected) -{ - if (mSelected == selected || !isSelectable()) { - return; - } - mSelected = selected; - auto geoMap = getMap(); - if (geoMap != nullptr) { - if (mSelected) { - geoMap->select(this); - } else { - geoMap->unselect(this); - } - } - update(); -} - -bool QGVItem::isSelected() const -{ - return mSelected; -} - -void QGVItem::select() -{ - setSelected(true); -} - -void QGVItem::unselect() -{ - setSelected(false); -} - -void QGVItem::setVisible(bool visible) -{ - if (mVisible == visible) { - return; - } - mVisible = visible; - update(); -} - -bool QGVItem::isVisible() const -{ - return mVisible; -} - -void QGVItem::show() -{ - setVisible(true); -} - -void QGVItem::hide() -{ - setVisible(false); -} - -double QGVItem::effectiveZValue() const -{ - if (mParent == nullptr) { - return mZValue; - } - const auto den = std::numeric_limits::max() - std::numeric_limits::min(); - double range = 1.0; - for (QGVItem* obj = mParent->getParent(); obj != nullptr; obj = obj->getParent()) { - range *= 1.0 / den; - } - const double efZValue = range * mZValue / den; - return mParent->effectiveZValue() + efZValue; -} - -double QGVItem::effectiveOpacity() const -{ - if (mParent == nullptr) { - return mOpacity; - } - return mOpacity * mParent->effectiveOpacity(); -} - -bool QGVItem::effectivelyVisible() const -{ - if (mParent == nullptr) { - return mVisible; - } - return mVisible && mParent->effectivelyVisible(); -} - -void QGVItem::update() -{ - if (getMap() == nullptr) { - return; - } - for (QGVItem* obj : mChildrens) { - obj->update(); - } - onUpdate(); -} - -void QGVItem::onProjection(QGVMap* geoMap) -{ - for (QGVItem* obj : mChildrens) { - obj->onProjection(geoMap); - } -} - -void QGVItem::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) -{ - for (QGVItem* obj : mChildrens) { - if (obj->isVisible()) { - obj->onCamera(oldState, newState); - } - } -} - -void QGVItem::onUpdate() -{ -} - -void QGVItem::onClean() -{ - for (QGVItem* obj : mChildrens) { - obj->onClean(); - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVItem.h" +#include + +QGVItem::QGVItem(QGVItem* parent) +{ + mParent = parent; + mZValue = 0; + mOpacity = 1.0; + mVisible = true; + mSelectable = false; + mSelected = false; +} + +QGVItem::~QGVItem() +{ + deleteItems(); + if (mParent != nullptr) { + mParent->mChildrens.removeAll(this); + } +} + +void QGVItem::setParent(QGVItem* item) +{ + if (mParent == item) { + return; + } + setSelected(false); + if (mParent != nullptr) { + mParent->mChildrens.removeAll(this); + } + auto oldParent = mParent; + mParent = item; + if (mParent != nullptr) { + mParent->mChildrens.append(this); + } + auto geoMap = getMap(); + if (geoMap != nullptr) { + if (oldParent != nullptr) { + Q_EMIT geoMap->itemsChanged(oldParent); + } + if (mParent != nullptr) { + Q_EMIT geoMap->itemsChanged(mParent); + } + onProjection(geoMap); + update(); + } else { + onClean(); + } +} + +QGVItem* QGVItem::getParent() const +{ + return mParent; +} + +QGVMap* QGVItem::getMap() const +{ + if (mParent != nullptr) { + return mParent->getMap(); + } + return nullptr; +} + +void QGVItem::addItem(QGVItem* item) +{ + Q_ASSERT(item); + item->setParent(this); +} + +void QGVItem::removeItem(QGVItem* item) +{ + Q_ASSERT(item); + if (item->getParent() != this) { + return; + } + item->setParent(nullptr); +} + +void QGVItem::deleteItems() +{ + auto copy = mChildrens; + qDeleteAll(copy.begin(), copy.end()); + mChildrens.clear(); +} + +int QGVItem::countItems() const +{ + return mChildrens.count(); +} + +QGVItem* QGVItem::getItem(int index) const +{ + return mChildrens.at(index); +} + +void QGVItem::setZValue(qint16 zValue) +{ + if (mZValue != zValue) { + mZValue = zValue; + update(); + } +} + +qint16 QGVItem::getZValue() const +{ + return mZValue; +} + +void QGVItem::bringToFront() +{ + mZValue = std::numeric_limits::max(); + update(); +} + +void QGVItem::sendToBack() +{ + mZValue = std::numeric_limits::min(); + update(); +} + +void QGVItem::setOpacity(double value) +{ + value = qMin(1.0, qMax(0.0, value)); + if (qFuzzyCompare(mOpacity, value)) { + return; + } + mOpacity = value; + update(); +} + +double QGVItem::getOpacity() const +{ + return mOpacity; +} + +void QGVItem::setSelectable(bool allowed) +{ + if (mSelectable == allowed) { + return; + } + mSelectable = allowed; + if (!mSelectable) { + setSelected(false); + } + onUpdate(); +} + +bool QGVItem::isSelectable() const +{ + return mSelectable; +} + +void QGVItem::setSelected(bool selected) +{ + if (mSelected == selected || !isSelectable()) { + return; + } + mSelected = selected; + auto geoMap = getMap(); + if (geoMap != nullptr) { + if (mSelected) { + geoMap->select(this); + } else { + geoMap->unselect(this); + } + } + update(); +} + +bool QGVItem::isSelected() const +{ + return mSelected; +} + +void QGVItem::select() +{ + setSelected(true); +} + +void QGVItem::unselect() +{ + setSelected(false); +} + +void QGVItem::setVisible(bool visible) +{ + if (mVisible == visible) { + return; + } + mVisible = visible; + update(); +} + +bool QGVItem::isVisible() const +{ + return mVisible; +} + +void QGVItem::show() +{ + setVisible(true); +} + +void QGVItem::hide() +{ + setVisible(false); +} + +double QGVItem::effectiveZValue() const +{ + if (mParent == nullptr) { + return mZValue; + } + const auto den = std::numeric_limits::max() - std::numeric_limits::min(); + double range = 1.0; + for (QGVItem* obj = mParent->getParent(); obj != nullptr; obj = obj->getParent()) { + range *= 1.0 / den; + } + const double efZValue = range * mZValue / den; + return mParent->effectiveZValue() + efZValue; +} + +double QGVItem::effectiveOpacity() const +{ + if (mParent == nullptr) { + return mOpacity; + } + return mOpacity * mParent->effectiveOpacity(); +} + +bool QGVItem::effectivelyVisible() const +{ + if (mParent == nullptr) { + return mVisible; + } + return mVisible && mParent->effectivelyVisible(); +} + +void QGVItem::update() +{ + if (getMap() == nullptr) { + return; + } + for (QGVItem* obj : mChildrens) { + obj->update(); + } + onUpdate(); +} + +void QGVItem::onProjection(QGVMap* geoMap) +{ + for (QGVItem* obj : mChildrens) { + obj->onProjection(geoMap); + } +} + +void QGVItem::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) +{ + for (QGVItem* obj : mChildrens) { + if (obj->isVisible()) { + obj->onCamera(oldState, newState); + } + } +} + +void QGVItem::onUpdate() +{} + +void QGVItem::onClean() +{ + for (QGVItem* obj : mChildrens) { + obj->onClean(); + } +} diff --git a/lib/src/QGVLayer.cpp b/lib/src/QGVLayer.cpp index 39c075e..153934e 100644 --- a/lib/src/QGVLayer.cpp +++ b/lib/src/QGVLayer.cpp @@ -1,39 +1,39 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVLayer.h" - -void QGVLayer::setName(const QString& name) -{ - mName = name; -} - -QString QGVLayer::getName() const -{ - return mName; -} - -void QGVLayer::setDescription(const QString& description) -{ - mDescription = description; -} - -QString QGVLayer::getDescription() const -{ - return mDescription; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVLayer.h" + +void QGVLayer::setName(const QString& name) +{ + mName = name; +} + +QString QGVLayer::getName() const +{ + return mName; +} + +void QGVLayer::setDescription(const QString& description) +{ + mDescription = description; +} + +QString QGVLayer::getDescription() const +{ + return mDescription; +} diff --git a/lib/src/QGVLayerBing.cpp b/lib/src/QGVLayerBing.cpp index 53172cf..df60ea2 100644 --- a/lib/src/QGVLayerBing.cpp +++ b/lib/src/QGVLayerBing.cpp @@ -1,105 +1,105 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVLayerBing.h" - -#include - -namespace { -// clang-format off -const QMap URLTemplates = { - { QGV::TilesType::Satellite, { - "http://t0.tiles.virtualearth.net/tiles/a${qk}.jpeg?g=181&mkt=${lcl}", - "http://t1.tiles.virtualearth.net/tiles/a${qk}.jpeg?g=181&mkt=${lcl}", - "http://t2.tiles.virtualearth.net/tiles/a${qk}.jpeg?g=181&mkt=${lcl}",} - }, - { QGV::TilesType::Schema, { - "http://t0.tiles.virtualearth.net/tiles/r${qk}.jpeg?g=181&mkt=${lcl}", - "http://t1.tiles.virtualearth.net/tiles/r${qk}.jpeg?g=181&mkt=${lcl}", - "http://t2.tiles.virtualearth.net/tiles/r${qk}.jpeg?g=181&mkt=${lcl}",} - }, - { QGV::TilesType::Hybrid, { - "http://t0.tiles.virtualearth.net/tiles/h${qk}.jpeg?g=181&mkt=${lcl}", - "http://t1.tiles.virtualearth.net/tiles/h${qk}.jpeg?g=181&mkt=${lcl}", - "http://t2.tiles.virtualearth.net/tiles/h${qk}.jpeg?g=181&mkt=${lcl}",} - }, -}; -// clang-format on -} - -QGVLayerBing::QGVLayerBing(QGV::TilesType type, QLocale locale, int serverNumber) - : mType(type) - , mLocale(locale) - , mServerNumber(serverNumber) -{ - createName(); - setDescription("Copyrights ©Microsoft"); -} - -void QGVLayerBing::setType(QGV::TilesType type) -{ - mType = type; - createName(); -} - -void QGVLayerBing::setLocale(const QLocale& locale) -{ - mLocale = locale; - createName(); -} - -QGV::TilesType QGVLayerBing::getType() const -{ - return mType; -} - -QLocale QGVLayerBing::getLocale() const -{ - return mLocale; -} - -void QGVLayerBing::createName() -{ - // clang-format off - const QMap adapter = { - { QGV::TilesType::Satellite, "QGV::Satellite" }, - { QGV::TilesType::Schema, "QGV::Schema" }, - { QGV::TilesType::Hybrid, "QGV::Hybrid" }, - }; - // clang-format on - setName("Bing Maps (" + adapter[mType] + " " + mLocale.name() + ")"); -} - -int QGVLayerBing::minZoomlevel() const -{ - return 1; -} - -int QGVLayerBing::maxZoomlevel() const -{ - return 19; -} - -QString QGVLayerBing::tilePosToUrl(const QGV::GeoTilePos& tilePos) const -{ - const QStringList& list = URLTemplates[mType]; - QString url = list.value(mServerNumber).toLower(); - url.replace("${lcl}", mLocale.name()); - url.replace("${qk}", tilePos.toQuadKey()); - return url; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVLayerBing.h" + +#include + +namespace { +// clang-format off +const QMap URLTemplates = { + { QGV::TilesType::Satellite, { + "http://t0.tiles.virtualearth.net/tiles/a${qk}.jpeg?g=181&mkt=${lcl}", + "http://t1.tiles.virtualearth.net/tiles/a${qk}.jpeg?g=181&mkt=${lcl}", + "http://t2.tiles.virtualearth.net/tiles/a${qk}.jpeg?g=181&mkt=${lcl}",} + }, + { QGV::TilesType::Schema, { + "http://t0.tiles.virtualearth.net/tiles/r${qk}.jpeg?g=181&mkt=${lcl}", + "http://t1.tiles.virtualearth.net/tiles/r${qk}.jpeg?g=181&mkt=${lcl}", + "http://t2.tiles.virtualearth.net/tiles/r${qk}.jpeg?g=181&mkt=${lcl}",} + }, + { QGV::TilesType::Hybrid, { + "http://t0.tiles.virtualearth.net/tiles/h${qk}.jpeg?g=181&mkt=${lcl}", + "http://t1.tiles.virtualearth.net/tiles/h${qk}.jpeg?g=181&mkt=${lcl}", + "http://t2.tiles.virtualearth.net/tiles/h${qk}.jpeg?g=181&mkt=${lcl}",} + }, +}; +// clang-format on +} + +QGVLayerBing::QGVLayerBing(QGV::TilesType type, QLocale locale, int serverNumber) + : mType(type) + , mLocale(locale) + , mServerNumber(serverNumber) +{ + createName(); + setDescription("Copyrights ©Microsoft"); +} + +void QGVLayerBing::setType(QGV::TilesType type) +{ + mType = type; + createName(); +} + +void QGVLayerBing::setLocale(const QLocale& locale) +{ + mLocale = locale; + createName(); +} + +QGV::TilesType QGVLayerBing::getType() const +{ + return mType; +} + +QLocale QGVLayerBing::getLocale() const +{ + return mLocale; +} + +void QGVLayerBing::createName() +{ + // clang-format off + const QMap adapter = { + { QGV::TilesType::Satellite, "QGV::Satellite" }, + { QGV::TilesType::Schema, "QGV::Schema" }, + { QGV::TilesType::Hybrid, "QGV::Hybrid" }, + }; + // clang-format on + setName("Bing Maps (" + adapter[mType] + " " + mLocale.name() + ")"); +} + +int QGVLayerBing::minZoomlevel() const +{ + return 1; +} + +int QGVLayerBing::maxZoomlevel() const +{ + return 19; +} + +QString QGVLayerBing::tilePosToUrl(const QGV::GeoTilePos& tilePos) const +{ + const QStringList& list = URLTemplates[mType]; + QString url = list.value(mServerNumber).toLower(); + url.replace("${lcl}", mLocale.name()); + url.replace("${qk}", tilePos.toQuadKey()); + return url; +} diff --git a/lib/src/QGVLayerGoogle.cpp b/lib/src/QGVLayerGoogle.cpp index 599a3b4..2ad7ded 100644 --- a/lib/src/QGVLayerGoogle.cpp +++ b/lib/src/QGVLayerGoogle.cpp @@ -1,110 +1,110 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVLayerGoogle.h" - -#include - -namespace { -// clang-format off -const QMap URLTemplates = { - {QGV::TilesType::Satellite, { - "https://mts0.google.com/vt/lyrs=s@186112443&hl=${lcl}&x=${x}&y=${y}&z=${z}&s=Galile", - "https://mts1.google.com/vt/lyrs=s@186112443&hl=${lcl}&x=${x}&y=${y}&z=${z}&s=Galile", - "https://mts2.google.com/vt/lyrs=s@186112443&hl=${lcl}&x=${x}&y=${y}&z=${z}&s=Galile", - } - }, - {QGV::TilesType::Schema, { - "http://mt1.google.com/vt/lyrs=m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", - "http://mt2.google.com/vt/lyrs=m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", - "http://mt3.google.com/vt/lyrs=m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", - } - }, - {QGV::TilesType::Hybrid, { - "http://mt1.google.com/vt/lyrs=s,m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", - "http://mt2.google.com/vt/lyrs=s,m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", - "http://mt3.google.com/vt/lyrs=s,m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", - } - }, -}; -// clang-format on -} - -QGVLayerGoogle::QGVLayerGoogle(QGV::TilesType type, QLocale locale, int serverNumber) - : mType(type) - , mLocale(locale) - , mServerNumber(serverNumber) -{ - createName(); - setDescription("Copyrights ©Google"); -} - -void QGVLayerGoogle::setType(QGV::TilesType type) -{ - mType = type; - createName(); -} - -void QGVLayerGoogle::setLocale(const QLocale& locale) -{ - mLocale = locale; - createName(); -} - -QGV::TilesType QGVLayerGoogle::getType() const -{ - return mType; -} - -QLocale QGVLayerGoogle::getLocale() const -{ - return mLocale; -} - -void QGVLayerGoogle::createName() -{ - // clang-format off - const QMap adapter = { - { QGV::TilesType::Satellite, "QGV::Satellite" }, - { QGV::TilesType::Schema, "QGV::Schema" }, - { QGV::TilesType::Hybrid, "QGV::Hybrid" }, - }; - // clang-format on - setName("Google Maps (" + adapter[mType] + " " + mLocale.name() + ")"); -} - -int QGVLayerGoogle::minZoomlevel() const -{ - return 0; -} - -int QGVLayerGoogle::maxZoomlevel() const -{ - return 21; -} - -QString QGVLayerGoogle::tilePosToUrl(const QGV::GeoTilePos& tilePos) const -{ - const QStringList& list = URLTemplates[mType]; - QString url = list.value(mServerNumber).toLower(); - url.replace("${lcl}", mLocale.name()); - url.replace("${z}", QString::number(tilePos.zoom())); - url.replace("${x}", QString::number(tilePos.pos().x())); - url.replace("${y}", QString::number(tilePos.pos().y())); - return url; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVLayerGoogle.h" + +#include + +namespace { +// clang-format off +const QMap URLTemplates = { + {QGV::TilesType::Satellite, { + "https://mts0.google.com/vt/lyrs=s@186112443&hl=${lcl}&x=${x}&y=${y}&z=${z}&s=Galile", + "https://mts1.google.com/vt/lyrs=s@186112443&hl=${lcl}&x=${x}&y=${y}&z=${z}&s=Galile", + "https://mts2.google.com/vt/lyrs=s@186112443&hl=${lcl}&x=${x}&y=${y}&z=${z}&s=Galile", + } + }, + {QGV::TilesType::Schema, { + "http://mt1.google.com/vt/lyrs=m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", + "http://mt2.google.com/vt/lyrs=m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", + "http://mt3.google.com/vt/lyrs=m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", + } + }, + {QGV::TilesType::Hybrid, { + "http://mt1.google.com/vt/lyrs=s,m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", + "http://mt2.google.com/vt/lyrs=s,m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", + "http://mt3.google.com/vt/lyrs=s,m@110&hl=${lcl}&x=${x}&y=${y}&z=${z}", + } + }, +}; +// clang-format on +} + +QGVLayerGoogle::QGVLayerGoogle(QGV::TilesType type, QLocale locale, int serverNumber) + : mType(type) + , mLocale(locale) + , mServerNumber(serverNumber) +{ + createName(); + setDescription("Copyrights ©Google"); +} + +void QGVLayerGoogle::setType(QGV::TilesType type) +{ + mType = type; + createName(); +} + +void QGVLayerGoogle::setLocale(const QLocale& locale) +{ + mLocale = locale; + createName(); +} + +QGV::TilesType QGVLayerGoogle::getType() const +{ + return mType; +} + +QLocale QGVLayerGoogle::getLocale() const +{ + return mLocale; +} + +void QGVLayerGoogle::createName() +{ + // clang-format off + const QMap adapter = { + { QGV::TilesType::Satellite, "QGV::Satellite" }, + { QGV::TilesType::Schema, "QGV::Schema" }, + { QGV::TilesType::Hybrid, "QGV::Hybrid" }, + }; + // clang-format on + setName("Google Maps (" + adapter[mType] + " " + mLocale.name() + ")"); +} + +int QGVLayerGoogle::minZoomlevel() const +{ + return 0; +} + +int QGVLayerGoogle::maxZoomlevel() const +{ + return 21; +} + +QString QGVLayerGoogle::tilePosToUrl(const QGV::GeoTilePos& tilePos) const +{ + const QStringList& list = URLTemplates[mType]; + QString url = list.value(mServerNumber).toLower(); + url.replace("${lcl}", mLocale.name()); + url.replace("${z}", QString::number(tilePos.zoom())); + url.replace("${x}", QString::number(tilePos.pos().x())); + url.replace("${y}", QString::number(tilePos.pos().y())); + return url; +} diff --git a/lib/src/QGVLayerOSM.cpp b/lib/src/QGVLayerOSM.cpp index ec55f62..f28a1c6 100644 --- a/lib/src/QGVLayerOSM.cpp +++ b/lib/src/QGVLayerOSM.cpp @@ -1,74 +1,74 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVLayerOSM.h" - -#include - -namespace { -// clang-format off -const QStringList URLTemplates = { - "http://a.tile.openstreetmap.org/${z}/${x}/${y}.png", - "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png", - "http://c.tile.openstreetmap.org/${z}/${x}/${y}.png", -}; -// clang-format on -} - -QGVLayerOSM::QGVLayerOSM(int serverNumber) - : mUrl(URLTemplates.value(serverNumber)) -{ - setName("OpenStreetMap"); - setDescription("Copyrights ©OpenStreetMap"); -} - -QGVLayerOSM::QGVLayerOSM(const QString& url) - : mUrl(url) -{ - setName("Custom"); - setDescription("OSM-like map"); -} - -void QGVLayerOSM::setUrl(const QString& url) -{ - mUrl = url; -} - -QString QGVLayerOSM::getUrl() const -{ - return mUrl; -} - -int QGVLayerOSM::minZoomlevel() const -{ - return 0; -} - -int QGVLayerOSM::maxZoomlevel() const -{ - return 20; -} - -QString QGVLayerOSM::tilePosToUrl(const QGV::GeoTilePos& tilePos) const -{ - QString url = mUrl.toLower(); - url.replace("${z}", QString::number(tilePos.zoom())); - url.replace("${x}", QString::number(tilePos.pos().x())); - url.replace("${y}", QString::number(tilePos.pos().y())); - return url; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVLayerOSM.h" + +#include + +namespace { +// clang-format off +const QStringList URLTemplates = { + "http://a.tile.openstreetmap.org/${z}/${x}/${y}.png", + "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png", + "http://c.tile.openstreetmap.org/${z}/${x}/${y}.png", +}; +// clang-format on +} + +QGVLayerOSM::QGVLayerOSM(int serverNumber) + : mUrl(URLTemplates.value(serverNumber)) +{ + setName("OpenStreetMap"); + setDescription("Copyrights ©OpenStreetMap"); +} + +QGVLayerOSM::QGVLayerOSM(const QString& url) + : mUrl(url) +{ + setName("Custom"); + setDescription("OSM-like map"); +} + +void QGVLayerOSM::setUrl(const QString& url) +{ + mUrl = url; +} + +QString QGVLayerOSM::getUrl() const +{ + return mUrl; +} + +int QGVLayerOSM::minZoomlevel() const +{ + return 0; +} + +int QGVLayerOSM::maxZoomlevel() const +{ + return 20; +} + +QString QGVLayerOSM::tilePosToUrl(const QGV::GeoTilePos& tilePos) const +{ + QString url = mUrl.toLower(); + url.replace("${z}", QString::number(tilePos.zoom())); + url.replace("${x}", QString::number(tilePos.pos().x())); + url.replace("${y}", QString::number(tilePos.pos().y())); + return url; +} diff --git a/lib/src/QGVLayerTiles.cpp b/lib/src/QGVLayerTiles.cpp index c42a4af..8c4efff 100644 --- a/lib/src/QGVLayerTiles.cpp +++ b/lib/src/QGVLayerTiles.cpp @@ -1,278 +1,278 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVLayerTiles.h" -#include "QGVDrawItem.h" - -#include - -namespace { -int minMargin = 1; -int maxMargin = 3; -int msAnimationUpdateDelay = 250; -} - -QGVLayerTiles::QGVLayerTiles() -{ - mCurZoom = -1; - sendToBack(); -} - -void QGVLayerTiles::onProjection(QGVMap* geoMap) -{ - QGVLayer::onProjection(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()) { - mLastAnimation.start(); - } else if (mLastAnimation.elapsed() < msAnimationUpdateDelay) { - needUpdate = false; - } else { - mLastAnimation.restart(); - } - } else { - mLastAnimation.invalidate(); - } - if (needUpdate) { - processCamera(); - } -} - -void QGVLayerTiles::onUpdate() -{ - QGVLayer::onUpdate(); - processCamera(); -} - -void QGVLayerTiles::onClean() -{ - QGVLayer::onClean(); - mCurZoom = -1; - mCurRect = {}; - mIndex.clear(); - deleteItems(); -} - -void QGVLayerTiles::onTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj) -{ - if (tilePos.zoom() != mCurZoom || !mCurRect.contains(tilePos.pos())) { - delete tileObj; - return; - } - addTile(tilePos, tileObj); - - removeAllAbove(tilePos); - - const int fromZoom = minZoomlevel(); - const int toZoom = tilePos.zoom() - 1; - for (int zoom = fromZoom; zoom <= toZoom; ++zoom) { - for (const QGV::GeoTilePos& below : existingTiles(zoom)) { - if (below.contains(tilePos)) { - removeWhenCovered(below); - } - } - } -} - -int QGVLayerTiles::scaleToZoom(double scale) const -{ - const double scaleChange = 1 / scale; - const int newZoom = qRound((17.0 - qLn(scaleChange) * M_LOG2E)); - return newZoom; -} - -void QGVLayerTiles::processCamera() -{ - if (getMap() == nullptr || !isVisible()) { - return; - } - const QGVProjection* projection = getMap()->getProjection(); - const QGVCameraState camera = getMap()->getCamera(); - const QRectF areaProjRect = camera.projRect().intersected(projection->boundaryProjRect()); - const QGV::GeoRect areaGeoRect = projection->projToGeo(areaProjRect); - - int originZoom = scaleToZoom(camera.scale()); - int newZoom = qMin(maxZoomlevel(), qMax(minZoomlevel(), originZoom)); - if (newZoom != originZoom) { - return; - } - const bool zoomChanged = (mCurZoom != newZoom); - mCurZoom = newZoom; - - const int margin = (zoomChanged) ? minMargin : maxMargin; - const int sizePerZoom = static_cast(qPow(2, mCurZoom)); - const QRect maxRect = QRect(QPoint(0, 0), QPoint(sizePerZoom, sizePerZoom)); - const QPoint topLeft = QGV::GeoTilePos::geoToTilePos(mCurZoom, areaGeoRect.topLeft()).pos(); - const QPoint bottomRight = QGV::GeoTilePos::geoToTilePos(mCurZoom, areaGeoRect.bottomRight()).pos(); - QRect activeRect = QRect(topLeft, bottomRight); - activeRect = activeRect.adjusted(-margin, -margin, margin, margin); - activeRect = activeRect.intersected(maxRect); - const bool rectChanged = (!zoomChanged && (mCurRect != activeRect)); - mCurRect = activeRect; - - if (!zoomChanged && !rectChanged) { - return; - } - - if (zoomChanged) { - qgvDebug() << "new active zoom" << mCurZoom; - const int fromZoom = minZoomlevel(); - const int toZoom = maxZoomlevel(); - for (int zoom = fromZoom; zoom <= toZoom; ++zoom) { - if (zoom == mCurZoom) { - 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; - } - } - } - } - - if (rectChanged) { - qgvDebug() << "new active rect" << mCurRect.topLeft() << mCurRect.bottomRight(); - for (const QGV::GeoTilePos& tilePos : existingTiles(mCurZoom)) { - if (!mCurRect.contains(tilePos.pos())) { - qgvDebug() << "delete out of boundary view" << tilePos; - removeTile(tilePos); - } - } - } - - QMultiMap missing; - for (int x = mCurRect.left(); x < mCurRect.right(); ++x) { - for (int y = mCurRect.top(); y < mCurRect.bottom(); ++y) { - const auto tilePos = QGV::GeoTilePos(mCurZoom, QPoint(x, y)); - if (isTileExists(tilePos)) { - continue; - } - qreal radius = qSqrt(qPow(x - mCurRect.center().x(), 2) + qPow(y - mCurRect.center().y(), 2)); - missing.insert(radius, tilePos); - } - } - for (const QGV::GeoTilePos& tilePos : missing) { - addTile(tilePos, nullptr); - } -} - -void QGVLayerTiles::removeAllAbove(const QGV::GeoTilePos& tilePos) -{ - const int fromZoom = tilePos.zoom() + 1; - const int toZoom = maxZoomlevel(); - for (int zoom = fromZoom; zoom <= toZoom; ++zoom) { - for (const QGV::GeoTilePos& target : existingTiles(zoom)) { - if (!tilePos.contains(target)) { - continue; - } - qgvDebug() << "remove" << target << "above" << tilePos; - removeTile(target); - } - } -} - -void QGVLayerTiles::removeWhenCovered(const QGV::GeoTilePos& tilePos) -{ - const int zoomDelta = mCurZoom - tilePos.zoom() + 1; - const int neededCount = static_cast(qPow(2, zoomDelta)); - int count = neededCount; - for (const QGV::GeoTilePos& current : existingTiles(mCurZoom)) { - if (!tilePos.contains(current)) { - continue; - } - if (!isTileFinished(current)) { - break; - } - count--; - if (count == 0) { - break; - } - } - if (count == 0) { - qgvDebug() << tilePos << "deleted by 100% coverage"; - removeTile(tilePos); - } else { - qgvDebug() << tilePos << "covered" << neededCount - count << "/" << neededCount; - } -} - -void QGVLayerTiles::addTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj) -{ - if (isTileFinished(tilePos)) { - delete tileObj; - return; - } - if (tileObj == nullptr) { - qgvDebug() << "request tile" << tilePos; - mIndex[tilePos.zoom()][tilePos] = nullptr; - request(tilePos); - } else { - qgvDebug() << "add tile" << tilePos; - mIndex[tilePos.zoom()][tilePos] = tileObj; - tileObj->setZValue(static_cast(tilePos.zoom())); - addItem(tileObj); - } -} - -void QGVLayerTiles::removeTile(const QGV::GeoTilePos& tilePos) -{ - const auto tile = mIndex[tilePos.zoom()].take(tilePos); - if (tile == nullptr) { - qgvDebug() << "cancel tile" << tilePos; - cancel(tilePos); - } else { - qgvDebug() << "remove tile" << tilePos; - delete tile; - } -} - -bool QGVLayerTiles::isTileExists(const QGV::GeoTilePos& tilePos) const -{ - return mIndex[tilePos.zoom()].contains(tilePos); -} - -bool QGVLayerTiles::isTileFinished(const QGV::GeoTilePos& tilePos) const -{ - if (!isTileExists(tilePos)) { - return false; - } - return mIndex[tilePos.zoom()][tilePos] != nullptr; -} - -QList QGVLayerTiles::existingTiles(int zoom) const -{ - return mIndex[zoom].keys(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVLayerTiles.h" +#include "QGVDrawItem.h" + +#include + +namespace { +int minMargin = 1; +int maxMargin = 3; +int msAnimationUpdateDelay = 250; +} + +QGVLayerTiles::QGVLayerTiles() +{ + mCurZoom = -1; + sendToBack(); +} + +void QGVLayerTiles::onProjection(QGVMap* geoMap) +{ + QGVLayer::onProjection(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()) { + mLastAnimation.start(); + } else if (mLastAnimation.elapsed() < msAnimationUpdateDelay) { + needUpdate = false; + } else { + mLastAnimation.restart(); + } + } else { + mLastAnimation.invalidate(); + } + if (needUpdate) { + processCamera(); + } +} + +void QGVLayerTiles::onUpdate() +{ + QGVLayer::onUpdate(); + processCamera(); +} + +void QGVLayerTiles::onClean() +{ + QGVLayer::onClean(); + mCurZoom = -1; + mCurRect = {}; + mIndex.clear(); + deleteItems(); +} + +void QGVLayerTiles::onTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj) +{ + if (tilePos.zoom() != mCurZoom || !mCurRect.contains(tilePos.pos())) { + delete tileObj; + return; + } + addTile(tilePos, tileObj); + + removeAllAbove(tilePos); + + const int fromZoom = minZoomlevel(); + const int toZoom = tilePos.zoom() - 1; + for (int zoom = fromZoom; zoom <= toZoom; ++zoom) { + for (const QGV::GeoTilePos& below : existingTiles(zoom)) { + if (below.contains(tilePos)) { + removeWhenCovered(below); + } + } + } +} + +int QGVLayerTiles::scaleToZoom(double scale) const +{ + const double scaleChange = 1 / scale; + const int newZoom = qRound((17.0 - qLn(scaleChange) * M_LOG2E)); + return newZoom; +} + +void QGVLayerTiles::processCamera() +{ + if (getMap() == nullptr || !isVisible()) { + return; + } + const QGVProjection* projection = getMap()->getProjection(); + const QGVCameraState camera = getMap()->getCamera(); + const QRectF areaProjRect = camera.projRect().intersected(projection->boundaryProjRect()); + const QGV::GeoRect areaGeoRect = projection->projToGeo(areaProjRect); + + int originZoom = scaleToZoom(camera.scale()); + int newZoom = qMin(maxZoomlevel(), qMax(minZoomlevel(), originZoom)); + if (newZoom != originZoom) { + return; + } + const bool zoomChanged = (mCurZoom != newZoom); + mCurZoom = newZoom; + + const int margin = (zoomChanged) ? minMargin : maxMargin; + const int sizePerZoom = static_cast(qPow(2, mCurZoom)); + const QRect maxRect = QRect(QPoint(0, 0), QPoint(sizePerZoom, sizePerZoom)); + const QPoint topLeft = QGV::GeoTilePos::geoToTilePos(mCurZoom, areaGeoRect.topLeft()).pos(); + const QPoint bottomRight = QGV::GeoTilePos::geoToTilePos(mCurZoom, areaGeoRect.bottomRight()).pos(); + QRect activeRect = QRect(topLeft, bottomRight); + activeRect = activeRect.adjusted(-margin, -margin, margin, margin); + activeRect = activeRect.intersected(maxRect); + const bool rectChanged = (!zoomChanged && (mCurRect != activeRect)); + mCurRect = activeRect; + + if (!zoomChanged && !rectChanged) { + return; + } + + if (zoomChanged) { + qgvDebug() << "new active zoom" << mCurZoom; + const int fromZoom = minZoomlevel(); + const int toZoom = maxZoomlevel(); + for (int zoom = fromZoom; zoom <= toZoom; ++zoom) { + if (zoom == mCurZoom) { + 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; + } + } + } + } + + if (rectChanged) { + qgvDebug() << "new active rect" << mCurRect.topLeft() << mCurRect.bottomRight(); + for (const QGV::GeoTilePos& tilePos : existingTiles(mCurZoom)) { + if (!mCurRect.contains(tilePos.pos())) { + qgvDebug() << "delete out of boundary view" << tilePos; + removeTile(tilePos); + } + } + } + + QMultiMap missing; + for (int x = mCurRect.left(); x < mCurRect.right(); ++x) { + for (int y = mCurRect.top(); y < mCurRect.bottom(); ++y) { + const auto tilePos = QGV::GeoTilePos(mCurZoom, QPoint(x, y)); + if (isTileExists(tilePos)) { + continue; + } + qreal radius = qSqrt(qPow(x - mCurRect.center().x(), 2) + qPow(y - mCurRect.center().y(), 2)); + missing.insert(radius, tilePos); + } + } + for (const QGV::GeoTilePos& tilePos : missing) { + addTile(tilePos, nullptr); + } +} + +void QGVLayerTiles::removeAllAbove(const QGV::GeoTilePos& tilePos) +{ + const int fromZoom = tilePos.zoom() + 1; + const int toZoom = maxZoomlevel(); + for (int zoom = fromZoom; zoom <= toZoom; ++zoom) { + for (const QGV::GeoTilePos& target : existingTiles(zoom)) { + if (!tilePos.contains(target)) { + continue; + } + qgvDebug() << "remove" << target << "above" << tilePos; + removeTile(target); + } + } +} + +void QGVLayerTiles::removeWhenCovered(const QGV::GeoTilePos& tilePos) +{ + const int zoomDelta = mCurZoom - tilePos.zoom() + 1; + const int neededCount = static_cast(qPow(2, zoomDelta)); + int count = neededCount; + for (const QGV::GeoTilePos& current : existingTiles(mCurZoom)) { + if (!tilePos.contains(current)) { + continue; + } + if (!isTileFinished(current)) { + break; + } + count--; + if (count == 0) { + break; + } + } + if (count == 0) { + qgvDebug() << tilePos << "deleted by 100% coverage"; + removeTile(tilePos); + } else { + qgvDebug() << tilePos << "covered" << neededCount - count << "/" << neededCount; + } +} + +void QGVLayerTiles::addTile(const QGV::GeoTilePos& tilePos, QGVDrawItem* tileObj) +{ + if (isTileFinished(tilePos)) { + delete tileObj; + return; + } + if (tileObj == nullptr) { + qgvDebug() << "request tile" << tilePos; + mIndex[tilePos.zoom()][tilePos] = nullptr; + request(tilePos); + } else { + qgvDebug() << "add tile" << tilePos; + mIndex[tilePos.zoom()][tilePos] = tileObj; + tileObj->setZValue(static_cast(tilePos.zoom())); + addItem(tileObj); + } +} + +void QGVLayerTiles::removeTile(const QGV::GeoTilePos& tilePos) +{ + const auto tile = mIndex[tilePos.zoom()].take(tilePos); + if (tile == nullptr) { + qgvDebug() << "cancel tile" << tilePos; + cancel(tilePos); + } else { + qgvDebug() << "remove tile" << tilePos; + delete tile; + } +} + +bool QGVLayerTiles::isTileExists(const QGV::GeoTilePos& tilePos) const +{ + return mIndex[tilePos.zoom()].contains(tilePos); +} + +bool QGVLayerTiles::isTileFinished(const QGV::GeoTilePos& tilePos) const +{ + if (!isTileExists(tilePos)) { + return false; + } + return mIndex[tilePos.zoom()][tilePos] != nullptr; +} + +QList QGVLayerTiles::existingTiles(int zoom) const +{ + return mIndex[zoom].keys(); +} diff --git a/lib/src/QGVLayerTilesOnline.cpp b/lib/src/QGVLayerTilesOnline.cpp index 6623bd5..dea28ff 100644 --- a/lib/src/QGVLayerTilesOnline.cpp +++ b/lib/src/QGVLayerTilesOnline.cpp @@ -1,104 +1,106 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVLayerTilesOnline.h" -#include "QGVImage.h" - -QGVLayerTilesOnline::~QGVLayerTilesOnline() -{ - qDeleteAll(mRequest); -} - -void QGVLayerTilesOnline::onProjection(QGVMap* geoMap) -{ - Q_ASSERT(QGV::getNetworkManager()); - QGVLayerTiles::onProjection(geoMap); - connect(QGV::getNetworkManager(), &QNetworkAccessManager::finished, this, &QGVLayerTilesOnline::onReplyFinished); -} - -void QGVLayerTilesOnline::onClean() -{ - Q_ASSERT(QGV::getNetworkManager()); - disconnect(QGV::getNetworkManager(), 0, this, 0); -} - -void QGVLayerTilesOnline::request(const QGV::GeoTilePos& tilePos) -{ - const QUrl url(tilePosToUrl(tilePos)); - QNetworkRequest request(url); - request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows; U; MSIE " - "6.0; Windows NT 5.1; SV1; .NET " - "CLR 2.0.50727)"); - request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - QNetworkReply* reply = QGV::getNetworkManager()->get(request); - reply->setProperty("TILE_OWNER", QVariant::fromValue(this)); - reply->setProperty("TILE_REQUEST", true); - reply->setProperty("TILE_POS", QVariant::fromValue(tilePos)); - mRequest[tilePos] = reply; - qgvDebug() << "request" << url; -} - -void QGVLayerTilesOnline::cancel(const QGV::GeoTilePos& tilePos) -{ - removeReply(tilePos); -} - -void QGVLayerTilesOnline::onReplyFinished(QNetworkReply* reply) -{ - const auto tileRequest = reply->property("TILE_REQUEST").toBool(); - if (!tileRequest) { - return; - } - const auto tileOwner = reply->property("TILE_OWNER").value(); - if (tileOwner != this) { - return; - } - const auto tilePos = reply->property("TILE_POS").value(); - - if (reply->error() != QNetworkReply::NoError) { - if (reply->error() != QNetworkReply::OperationCanceledError) { - qgvCritical() << "ERROR" << reply->errorString(); - } - removeReply(tilePos); - return; - } - const auto rawImage = reply->readAll(); - auto tile = new QGVImage(); - tile->setGeometry(tilePos.toGeoRect()); - tile->loadImage(rawImage); - tile->setProperty("drawDebug", QString("%1\ntile(%2,%3,%4)") - .arg(reply->url().toString()) - .arg(tilePos.zoom()) - .arg(tilePos.pos().x()) - .arg(tilePos.pos().y())); - removeReply(tilePos); - onTile(tilePos, tile); -} - -void QGVLayerTilesOnline::removeReply(const QGV::GeoTilePos& tilePos) -{ - QNetworkReply* reply = mRequest.value(tilePos, nullptr); - if (reply == nullptr) { - return; - } - mRequest.remove(tilePos); - reply->abort(); - reply->close(); - reply->deleteLater(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVLayerTilesOnline.h" +#include "QGVImage.h" + +QGVLayerTilesOnline::~QGVLayerTilesOnline() +{ + qDeleteAll(mRequest); +} + +void QGVLayerTilesOnline::onProjection(QGVMap* geoMap) +{ + Q_ASSERT(QGV::getNetworkManager()); + QGVLayerTiles::onProjection(geoMap); + connect(QGV::getNetworkManager(), &QNetworkAccessManager::finished, this, &QGVLayerTilesOnline::onReplyFinished); +} + +void QGVLayerTilesOnline::onClean() +{ + Q_ASSERT(QGV::getNetworkManager()); + disconnect(QGV::getNetworkManager(), 0, this, 0); +} + +void QGVLayerTilesOnline::request(const QGV::GeoTilePos& tilePos) +{ + const QUrl url(tilePosToUrl(tilePos)); + QNetworkRequest request(url); + request.setRawHeader("User-Agent", + "Mozilla/5.0 (Windows; U; MSIE " + "6.0; Windows NT 5.1; SV1; .NET " + "CLR 2.0.50727)"); + request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + QNetworkReply* reply = QGV::getNetworkManager()->get(request); + reply->setProperty("TILE_OWNER", QVariant::fromValue(this)); + reply->setProperty("TILE_REQUEST", true); + reply->setProperty("TILE_POS", QVariant::fromValue(tilePos)); + mRequest[tilePos] = reply; + qgvDebug() << "request" << url; +} + +void QGVLayerTilesOnline::cancel(const QGV::GeoTilePos& tilePos) +{ + removeReply(tilePos); +} + +void QGVLayerTilesOnline::onReplyFinished(QNetworkReply* reply) +{ + const auto tileRequest = reply->property("TILE_REQUEST").toBool(); + if (!tileRequest) { + return; + } + const auto tileOwner = reply->property("TILE_OWNER").value(); + if (tileOwner != this) { + return; + } + const auto tilePos = reply->property("TILE_POS").value(); + + if (reply->error() != QNetworkReply::NoError) { + if (reply->error() != QNetworkReply::OperationCanceledError) { + qgvCritical() << "ERROR" << reply->errorString(); + } + removeReply(tilePos); + return; + } + const auto rawImage = reply->readAll(); + auto tile = new QGVImage(); + tile->setGeometry(tilePos.toGeoRect()); + tile->loadImage(rawImage); + tile->setProperty("drawDebug", + QString("%1\ntile(%2,%3,%4)") + .arg(reply->url().toString()) + .arg(tilePos.zoom()) + .arg(tilePos.pos().x()) + .arg(tilePos.pos().y())); + removeReply(tilePos); + onTile(tilePos, tile); +} + +void QGVLayerTilesOnline::removeReply(const QGV::GeoTilePos& tilePos) +{ + QNetworkReply* reply = mRequest.value(tilePos, nullptr); + if (reply == nullptr) { + return; + } + mRequest.remove(tilePos); + reply->abort(); + reply->close(); + reply->deleteLater(); +} diff --git a/lib/src/QGVMap.cpp b/lib/src/QGVMap.cpp index f759165..1219094 100644 --- a/lib/src/QGVMap.cpp +++ b/lib/src/QGVMap.cpp @@ -1,359 +1,360 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVMap.h" -#include "QGVItem.h" -#include "QGVMapQGItem.h" -#include "QGVMapQGView.h" -#include "QGVProjectionEPSG3857.h" -#include "QGVWidget.h" - -#include -#include - -class RootItem : public QGVItem -{ -public: - explicit RootItem(QGVMap* geoMap) - : mGeoMap(geoMap) - { - } - virtual ~RootItem(); - - QGVMap* getMap() const override final - { - return mGeoMap; - } - -private: - QGVMap* mGeoMap; -}; -RootItem::~RootItem() = default; - -QGVMap::QGVMap(QWidget* parent) - : QWidget(parent) -{ - mProjection.reset(new QGVProjectionEPSG3857()); - mQGView.reset(new QGVMapQGView(this)); - mRootItem.reset(new RootItem(this)); - setLayout(new QVBoxLayout(this)); - layout()->addWidget(mQGView.data()); - refreshProjection(); -} - -QGVMap::~QGVMap() -{ - deleteItems(); - deleteWidgets(); -} - -const QGVCameraState QGVMap::getCamera() const -{ - return geoView()->getCamera(); -} - -void QGVMap::cameraTo(const QGVCameraActions& actions, bool animation) -{ - geoView()->cameraTo(actions, animation); -} - -void QGVMap::flyTo(const QGVCameraActions& actions) -{ - geoView()->cleanState(); - auto* fly = new QGVCameraFlyAnimation(actions); - fly->start(QAbstractAnimation::DeleteWhenStopped); -} - -void QGVMap::setProjection(QGV::Projection id) -{ - mProjection.reset(nullptr); - switch (id) { - case QGV::Projection::EPSG3857: - setProjection(new QGVProjectionEPSG3857()); - break; - } -} - -void QGVMap::setProjection(QGVProjection* projection) -{ - Q_ASSERT(projection); - mProjection.reset(projection); - refreshProjection(); - Q_EMIT projectionChanged(); -} - -QGVProjection* QGVMap::getProjection() const -{ - return mProjection.data(); -} - -void QGVMap::setMouseActions(QGV::MouseActions actions) -{ - geoView()->setMouseActions(actions); -} - -void QGVMap::setMouseAction(QGV::MouseAction action, bool enabled) -{ - QGV::MouseActions newActions = getMouseActions(); - if (enabled) - newActions |= action; - else - newActions &= ~static_cast(action); - setMouseActions(newActions); -} - -QGV::MouseActions QGVMap::getMouseActions() const -{ - return geoView()->getMouseActions(); -} - -bool QGVMap::isMouseAction(QGV::MouseAction action) const -{ - return getMouseActions().testFlag(action); -} - -QGVItem* QGVMap::rootItem() const -{ - return mRootItem.data(); -} - -QGVMapQGView* QGVMap::geoView() const -{ - return mQGView.data(); -} - -void QGVMap::addItem(QGVItem* item) -{ - Q_ASSERT(item); - mRootItem->addItem(item); -} - -void QGVMap::removeItem(QGVItem* item) -{ - Q_ASSERT(item); - mRootItem->removeItem(item); -} - -void QGVMap::deleteItems() -{ - mRootItem->deleteItems(); -} - -int QGVMap::countItems() const -{ - return mRootItem->countItems(); -} - -QGVItem* QGVMap::getItem(int index) const -{ - return mRootItem->getItem(index); -} - -void QGVMap::addWidget(QGVWidget* widget) -{ - Q_ASSERT(widget); - if (widget->getMap() != nullptr && widget->getMap() != this) { - widget->getMap()->removeWidget(widget); - } - - mWidgets.append(widget); - widget->setMap(this); - widget->show(); -} - -void QGVMap::removeWidget(QGVWidget* widget) -{ - if (!mWidgets.contains(widget)) - return; - - mWidgets.removeAll(widget); - widget->setMap(nullptr); -} - -void QGVMap::deleteWidgets() -{ - auto copy = mWidgets; - qDeleteAll(copy.begin(), copy.end()); - mWidgets.clear(); -} - -int QGVMap::countWidgets() const -{ - return mWidgets.count(); -} - -QGVWidget* QGVMap::getWigdet(int index) const -{ - return mWidgets.at(index); -} - -void QGVMap::select(QGVItem* item) -{ - item->select(); - if (item->isSelected()) { - mSelections.insert(item); - } -} - -void QGVMap::unselect(QGVItem* item) -{ - item->unselect(); - if (!item->isSelected()) { - mSelections.remove(item); - } -} - -void QGVMap::unselectAll() -{ - auto selections = mSelections; - for (QGVItem* item : selections) { - item->unselect(); - } -} - -QSet QGVMap::getSelections() const -{ - return mSelections; -} - -QList QGVMap::search(const QPointF& projPos, Qt::ItemSelectionMode mode) const -{ - QList result; - for (QGraphicsItem* item : geoView()->scene()->items(projPos, mode)) { - QGVDrawItem* geoObject = QGVMapQGItem::geoObjectFromQGItem(item); - if (geoObject) - result << geoObject; - } - return result; -} - -QList QGVMap::search(const QRectF& projRect, Qt::ItemSelectionMode mode) const -{ - QList result; - for (QGraphicsItem* item : geoView()->scene()->items(projRect, mode)) { - QGVDrawItem* geoObject = QGVMapQGItem::geoObjectFromQGItem(item); - if (geoObject) - result << geoObject; - } - return result; -} - -QPixmap QGVMap::grabMapView(bool includeWidgets) const -{ - const QPixmap pixmap = (includeWidgets) ? geoView()->grab(geoView()->rect()) - : geoView()->viewport()->grab(geoView()->viewport()->rect()); - return pixmap; -} - -QPointF QGVMap::mapToProj(QPoint pos) -{ - const auto viewPos = geoView()->mapFromParent(pos); - const auto projPos = geoView()->mapToScene(viewPos); - return projPos; -} - -QPoint QGVMap::mapFromProj(QPointF projPos) -{ - const auto viewPos = geoView()->mapFromScene(projPos); - const auto mapPos = geoView()->mapToParent(viewPos); - return mapPos; -} - -void QGVMap::refreshMap() -{ - mRootItem->update(); -} - -void QGVMap::refreshProjection() -{ - QRectF sceneRect = mProjection->boundaryProjRect(); - - const double viewXSize = 640; - const double viewYSize = 480; - - const double projXSize = sceneRect.width(); - const double projYSize = sceneRect.height(); - - const double newMinScaleFactor0 = 1.0; - const double newMinScaleFactor1 = qAbs(viewXSize / projXSize); - const double newMinScaleFactor2 = qAbs(viewYSize / projYSize); - const double minScale = qMin(newMinScaleFactor0, qMin(newMinScaleFactor1, newMinScaleFactor2)); - const double maxScale = 16.0; - geoView()->setScaleLimits(minScale, maxScale); - - const double offset = 1; - sceneRect.adjust(-sceneRect.width() * offset, -sceneRect.height() * offset, +sceneRect.width() * offset, - +sceneRect.height() * offset); - geoView()->scene()->setSceneRect(sceneRect); - - auto root = static_cast(rootItem()); - root->onProjection(this); - - for (QGVWidget* widget : mWidgets) { - widget->onProjection(this); - } -} - -void QGVMap::anchoreWidgets() -{ - for (QGVWidget* widget : mWidgets) { - widget->anchoreWidget(); - } -} - -void QGVMap::onMapState(QGV::MapState state) -{ - Q_EMIT stateChanged(state); -} - -void QGVMap::onMapCamera(const QGVCameraState& oldState, const QGVCameraState& newState) -{ - if (!qFuzzyCompare(oldState.azimuth(), newState.azimuth())) { - Q_EMIT azimuthChanged(); - } - if (!qFuzzyCompare(oldState.scale(), newState.scale())) { - Q_EMIT scaleChanged(); - } - if (oldState.projRect() != newState.projRect()) { - Q_EMIT areaChanged(); - } - - auto root = static_cast(rootItem()); - if (root->isVisible()) { - root->onCamera(oldState, newState); - } - for (QGVWidget* widget : mWidgets) { - if (widget->isVisible()) { - widget->onCamera(oldState, newState); - } - } - - if (hasMouseTracking()) { - const auto pos = mapFromGlobal(QCursor::pos()); - Q_EMIT mapMouseMove(mapToProj(pos)); - } -} - -void QGVMap::mouseMoveEvent(QMouseEvent* event) -{ - if (hasMouseTracking()) { - Q_EMIT mapMouseMove(mapToProj(event->pos())); - } - event->ignore(); - QWidget::mouseMoveEvent(event); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVMap.h" +#include "QGVItem.h" +#include "QGVMapQGItem.h" +#include "QGVMapQGView.h" +#include "QGVProjectionEPSG3857.h" +#include "QGVWidget.h" + +#include +#include + +class RootItem : public QGVItem +{ +public: + explicit RootItem(QGVMap* geoMap) + : mGeoMap(geoMap) + {} + virtual ~RootItem(); + + QGVMap* getMap() const override final + { + return mGeoMap; + } + +private: + QGVMap* mGeoMap; +}; +RootItem::~RootItem() = default; + +QGVMap::QGVMap(QWidget* parent) + : QWidget(parent) +{ + mProjection.reset(new QGVProjectionEPSG3857()); + mQGView.reset(new QGVMapQGView(this)); + mRootItem.reset(new RootItem(this)); + setLayout(new QVBoxLayout(this)); + layout()->addWidget(mQGView.data()); + refreshProjection(); +} + +QGVMap::~QGVMap() +{ + deleteItems(); + deleteWidgets(); +} + +const QGVCameraState QGVMap::getCamera() const +{ + return geoView()->getCamera(); +} + +void QGVMap::cameraTo(const QGVCameraActions& actions, bool animation) +{ + geoView()->cameraTo(actions, animation); +} + +void QGVMap::flyTo(const QGVCameraActions& actions) +{ + geoView()->cleanState(); + auto* fly = new QGVCameraFlyAnimation(actions); + fly->start(QAbstractAnimation::DeleteWhenStopped); +} + +void QGVMap::setProjection(QGV::Projection id) +{ + mProjection.reset(nullptr); + switch (id) { + case QGV::Projection::EPSG3857: + setProjection(new QGVProjectionEPSG3857()); + break; + } +} + +void QGVMap::setProjection(QGVProjection* projection) +{ + Q_ASSERT(projection); + mProjection.reset(projection); + refreshProjection(); + Q_EMIT projectionChanged(); +} + +QGVProjection* QGVMap::getProjection() const +{ + return mProjection.data(); +} + +void QGVMap::setMouseActions(QGV::MouseActions actions) +{ + geoView()->setMouseActions(actions); +} + +void QGVMap::setMouseAction(QGV::MouseAction action, bool enabled) +{ + QGV::MouseActions newActions = getMouseActions(); + if (enabled) + newActions |= action; + else + newActions &= ~static_cast(action); + setMouseActions(newActions); +} + +QGV::MouseActions QGVMap::getMouseActions() const +{ + return geoView()->getMouseActions(); +} + +bool QGVMap::isMouseAction(QGV::MouseAction action) const +{ + return getMouseActions().testFlag(action); +} + +QGVItem* QGVMap::rootItem() const +{ + return mRootItem.data(); +} + +QGVMapQGView* QGVMap::geoView() const +{ + return mQGView.data(); +} + +void QGVMap::addItem(QGVItem* item) +{ + Q_ASSERT(item); + mRootItem->addItem(item); +} + +void QGVMap::removeItem(QGVItem* item) +{ + Q_ASSERT(item); + mRootItem->removeItem(item); +} + +void QGVMap::deleteItems() +{ + mRootItem->deleteItems(); +} + +int QGVMap::countItems() const +{ + return mRootItem->countItems(); +} + +QGVItem* QGVMap::getItem(int index) const +{ + return mRootItem->getItem(index); +} + +void QGVMap::addWidget(QGVWidget* widget) +{ + Q_ASSERT(widget); + if (widget->getMap() != nullptr && widget->getMap() != this) { + widget->getMap()->removeWidget(widget); + } + + mWidgets.append(widget); + widget->setMap(this); + widget->show(); +} + +void QGVMap::removeWidget(QGVWidget* widget) +{ + if (!mWidgets.contains(widget)) + return; + + mWidgets.removeAll(widget); + widget->setMap(nullptr); +} + +void QGVMap::deleteWidgets() +{ + auto copy = mWidgets; + qDeleteAll(copy.begin(), copy.end()); + mWidgets.clear(); +} + +int QGVMap::countWidgets() const +{ + return mWidgets.count(); +} + +QGVWidget* QGVMap::getWigdet(int index) const +{ + return mWidgets.at(index); +} + +void QGVMap::select(QGVItem* item) +{ + item->select(); + if (item->isSelected()) { + mSelections.insert(item); + } +} + +void QGVMap::unselect(QGVItem* item) +{ + item->unselect(); + if (!item->isSelected()) { + mSelections.remove(item); + } +} + +void QGVMap::unselectAll() +{ + auto selections = mSelections; + for (QGVItem* item : selections) { + item->unselect(); + } +} + +QSet QGVMap::getSelections() const +{ + return mSelections; +} + +QList QGVMap::search(const QPointF& projPos, Qt::ItemSelectionMode mode) const +{ + QList result; + for (QGraphicsItem* item : geoView()->scene()->items(projPos, mode)) { + QGVDrawItem* geoObject = QGVMapQGItem::geoObjectFromQGItem(item); + if (geoObject) + result << geoObject; + } + return result; +} + +QList QGVMap::search(const QRectF& projRect, Qt::ItemSelectionMode mode) const +{ + QList result; + for (QGraphicsItem* item : geoView()->scene()->items(projRect, mode)) { + QGVDrawItem* geoObject = QGVMapQGItem::geoObjectFromQGItem(item); + if (geoObject) + result << geoObject; + } + return result; +} + +QPixmap QGVMap::grabMapView(bool includeWidgets) const +{ + const QPixmap pixmap = (includeWidgets) ? geoView()->grab(geoView()->rect()) + : geoView()->viewport()->grab(geoView()->viewport()->rect()); + return pixmap; +} + +QPointF QGVMap::mapToProj(QPoint pos) +{ + const auto viewPos = geoView()->mapFromParent(pos); + const auto projPos = geoView()->mapToScene(viewPos); + return projPos; +} + +QPoint QGVMap::mapFromProj(QPointF projPos) +{ + const auto viewPos = geoView()->mapFromScene(projPos); + const auto mapPos = geoView()->mapToParent(viewPos); + return mapPos; +} + +void QGVMap::refreshMap() +{ + mRootItem->update(); +} + +void QGVMap::refreshProjection() +{ + QRectF sceneRect = mProjection->boundaryProjRect(); + + const double viewXSize = 640; + const double viewYSize = 480; + + const double projXSize = sceneRect.width(); + const double projYSize = sceneRect.height(); + + const double newMinScaleFactor0 = 1.0; + const double newMinScaleFactor1 = qAbs(viewXSize / projXSize); + const double newMinScaleFactor2 = qAbs(viewYSize / projYSize); + const double minScale = qMin(newMinScaleFactor0, qMin(newMinScaleFactor1, newMinScaleFactor2)); + const double maxScale = 16.0; + geoView()->setScaleLimits(minScale, maxScale); + + const double offset = 1; + sceneRect.adjust(-sceneRect.width() * offset, + -sceneRect.height() * offset, + +sceneRect.width() * offset, + +sceneRect.height() * offset); + geoView()->scene()->setSceneRect(sceneRect); + + auto root = static_cast(rootItem()); + root->onProjection(this); + + for (QGVWidget* widget : mWidgets) { + widget->onProjection(this); + } +} + +void QGVMap::anchoreWidgets() +{ + for (QGVWidget* widget : mWidgets) { + widget->anchoreWidget(); + } +} + +void QGVMap::onMapState(QGV::MapState state) +{ + Q_EMIT stateChanged(state); +} + +void QGVMap::onMapCamera(const QGVCameraState& oldState, const QGVCameraState& newState) +{ + if (!qFuzzyCompare(oldState.azimuth(), newState.azimuth())) { + Q_EMIT azimuthChanged(); + } + if (!qFuzzyCompare(oldState.scale(), newState.scale())) { + Q_EMIT scaleChanged(); + } + if (oldState.projRect() != newState.projRect()) { + Q_EMIT areaChanged(); + } + + auto root = static_cast(rootItem()); + if (root->isVisible()) { + root->onCamera(oldState, newState); + } + for (QGVWidget* widget : mWidgets) { + if (widget->isVisible()) { + widget->onCamera(oldState, newState); + } + } + + if (hasMouseTracking()) { + const auto pos = mapFromGlobal(QCursor::pos()); + Q_EMIT mapMouseMove(mapToProj(pos)); + } +} + +void QGVMap::mouseMoveEvent(QMouseEvent* event) +{ + if (hasMouseTracking()) { + Q_EMIT mapMouseMove(mapToProj(event->pos())); + } + event->ignore(); + QWidget::mouseMoveEvent(event); +} diff --git a/lib/src/QGVMapQGItem.cpp b/lib/src/QGVMapQGItem.cpp index c48fc7a..794b99b 100644 --- a/lib/src/QGVMapQGItem.cpp +++ b/lib/src/QGVMapQGItem.cpp @@ -1,102 +1,102 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVMapQGItem.h" -#include "QGVDrawItem.h" - -#include -#include -#include - -QGVMapQGItem::QGVMapQGItem(QGVDrawItem* geoObject) -{ - mGeoObject = geoObject; - setCacheMode(QGraphicsItem::DeviceCoordinateCache); -} - -QGVDrawItem* QGVMapQGItem::geoObjectFromQGItem(QGraphicsItem* item) -{ - QGVMapQGItem* qGCItem = dynamic_cast(item); - return (qGCItem != nullptr) ? qGCItem->mGeoObject : nullptr; -} - -void QGVMapQGItem::resetGeometry() -{ - prepareGeometryChange(); -} - -QRectF QGVMapQGItem::boundingRect() const -{ - return mGeoObject->projShape().boundingRect(); -} - -void QGVMapQGItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) -{ - mGeoObject->projPaint(painter); - - if (mGeoObject->isSelected() && !mGeoObject->isFlag(QGV::ItemFlag::SelectCustom)) { - QPen pen = QPen(mGeoObject->getMap()->palette().highlight(), 1, Qt::DashLine); - pen.setCosmetic(true); - QBrush brush = QBrush(mGeoObject->getMap()->palette().light().color(), Qt::Dense4Pattern); - painter->setPen(pen); - painter->setBrush(brush); - painter->drawPath(mGeoObject->projShape()); - } - - if (QGV::isDrawDebug()) { - mGeoObject->setProperty("paintCount", mGeoObject->property("paintCount").toInt() + 1); - QPen pen = QPen(Qt::black); - pen.setWidth(1); - pen.setCosmetic(true); - QBrush brush = QBrush(Qt::white); - painter->setPen(pen); - painter->setBrush(brush); - auto rect = boundingRect().toRect(); - auto path = QGV::createTextPath(rect, mGeoObject->projDebug(), QFont(), pen.width()); - path = QGV::createTransfromScale(rect.center(), 0.75).map(path); - painter->drawPath(path); - - pen = QPen(Qt::black); - pen.setStyle(Qt::DashLine); - pen.setWidth(1); - pen.setCosmetic(true); - brush = QBrush(Qt::transparent); - painter->setPen(pen); - painter->setBrush(brush); - painter->drawRect(rect); - } -} - -QPainterPath QGVMapQGItem::shape() const -{ - return mGeoObject->projShape(); -} - -void QGVMapQGItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) -{ - if (mGeoObject->isFlag(QGV::ItemFlag::Highlightable)) { - mGeoObject->setFlag(QGV::ItemFlag::Highlighted); - } -} - -void QGVMapQGItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) -{ - if (mGeoObject->isFlag(QGV::ItemFlag::Highlightable)) { - mGeoObject->setFlag(QGV::ItemFlag::Highlighted, false); - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVMapQGItem.h" +#include "QGVDrawItem.h" + +#include +#include +#include + +QGVMapQGItem::QGVMapQGItem(QGVDrawItem* geoObject) +{ + mGeoObject = geoObject; + setCacheMode(QGraphicsItem::DeviceCoordinateCache); +} + +QGVDrawItem* QGVMapQGItem::geoObjectFromQGItem(QGraphicsItem* item) +{ + QGVMapQGItem* qGCItem = dynamic_cast(item); + return (qGCItem != nullptr) ? qGCItem->mGeoObject : nullptr; +} + +void QGVMapQGItem::resetGeometry() +{ + prepareGeometryChange(); +} + +QRectF QGVMapQGItem::boundingRect() const +{ + return mGeoObject->projShape().boundingRect(); +} + +void QGVMapQGItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) +{ + mGeoObject->projPaint(painter); + + if (mGeoObject->isSelected() && !mGeoObject->isFlag(QGV::ItemFlag::SelectCustom)) { + QPen pen = QPen(mGeoObject->getMap()->palette().highlight(), 1, Qt::DashLine); + pen.setCosmetic(true); + QBrush brush = QBrush(mGeoObject->getMap()->palette().light().color(), Qt::Dense4Pattern); + painter->setPen(pen); + painter->setBrush(brush); + painter->drawPath(mGeoObject->projShape()); + } + + if (QGV::isDrawDebug()) { + mGeoObject->setProperty("paintCount", mGeoObject->property("paintCount").toInt() + 1); + QPen pen = QPen(Qt::black); + pen.setWidth(1); + pen.setCosmetic(true); + QBrush brush = QBrush(Qt::white); + painter->setPen(pen); + painter->setBrush(brush); + auto rect = boundingRect().toRect(); + auto path = QGV::createTextPath(rect, mGeoObject->projDebug(), QFont(), pen.width()); + path = QGV::createTransfromScale(rect.center(), 0.75).map(path); + painter->drawPath(path); + + pen = QPen(Qt::black); + pen.setStyle(Qt::DashLine); + pen.setWidth(1); + pen.setCosmetic(true); + brush = QBrush(Qt::transparent); + painter->setPen(pen); + painter->setBrush(brush); + painter->drawRect(rect); + } +} + +QPainterPath QGVMapQGItem::shape() const +{ + return mGeoObject->projShape(); +} + +void QGVMapQGItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) +{ + if (mGeoObject->isFlag(QGV::ItemFlag::Highlightable)) { + mGeoObject->setFlag(QGV::ItemFlag::Highlighted); + } +} + +void QGVMapQGItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) +{ + if (mGeoObject->isFlag(QGV::ItemFlag::Highlightable)) { + mGeoObject->setFlag(QGV::ItemFlag::Highlighted, false); + } +} diff --git a/lib/src/QGVMapQGView.cpp b/lib/src/QGVMapQGView.cpp index 05b26ad..659c536 100644 --- a/lib/src/QGVMapQGView.cpp +++ b/lib/src/QGVMapQGView.cpp @@ -1,539 +1,539 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVMapQGView.h" -#include "QGVDrawItem.h" -#include "QGVMap.h" -#include "QGVMapQGItem.h" -#include "QGVMapQGView.h" -#include "QGVMapRubberBand.h" -#include "QGVWidget.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace { -int wheelAreaMargin = 10; -double wheelExponentDown = qPow(2, 1.0 / 5.0); -double wheelExponentUp = qPow(2, 1.0 / 2.0); -} - -QGVMapQGView::QGVMapQGView(QGVMap* geoMap) - : QGraphicsView(geoMap) -{ - Q_ASSERT(geoMap); - mGeoMap = geoMap; - mBlockUpdateCount = 0; - mMinScale = 1e-8; - mMaxScale = 1e+2; - mScale = 1.0; - mAzimuth = 0.0; - mMouseActions = QGV::MouseAction::All; - mViewRect = viewport()->rect(); - mState = QGV::MapState::Idle; - mQGScene.reset(new QGraphicsScene(this)); - mSelectionRect.reset(new QGVMapRubberBand(this)); - mSelectionRect->setMinSelection(QSize(5, 5)); - mContextMenu.reset(new QMenu(this)); - setScene(mQGScene.data()); - setContextMenuPolicy(Qt::NoContextMenu); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setOptimizationFlag(DontSavePainterState, true); - setOptimizationFlag(DontAdjustForAntialiasing, true); - setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); - setRenderHint(QPainter::Antialiasing, true); - setCacheMode(QGraphicsView::CacheBackground); - setMouseTracking(true); - setBackgroundBrush(QBrush(Qt::lightGray)); -} - -void QGVMapQGView::setMouseActions(QGV::MouseActions actions) -{ - mMouseActions = actions; -} - -QGV::MouseActions QGVMapQGView::getMouseActions() const -{ - return mMouseActions; -} - -QGVCameraState QGVMapQGView::getCamera() const -{ - const bool animation = mState == QGV::MapState::Animation; - return QGVCameraState(mGeoMap, mAzimuth, mScale, viewRect(), animation); -} - -void QGVMapQGView::cameraTo(const QGVCameraActions& actions, bool animation) -{ - const QGVCameraState oldState = getCamera(); - blockCameraUpdate(); - changeState((animation) ? QGV::MapState::Animation : QGV::MapState::Idle); - cameraScale(actions.scale()); - cameraMove(actions.projCenter()); - cameraRotate(actions.azimuth()); - unblockCameraUpdate(); - applyCameraUpdate(oldState); -} - -double QGVMapQGView::getMinScale() const -{ - return mMinScale; -} - -double QGVMapQGView::getMaxScale() const -{ - return mMaxScale; -} - -void QGVMapQGView::setScaleLimits(double minScale, double maxScale) -{ - mMinScale = minScale; - mMaxScale = maxScale; - cameraScale(mScale); -} - -void QGVMapQGView::cleanState() -{ - changeState(QGV::MapState::Idle); -} - -QRectF QGVMapQGView::viewRect() const -{ - return mapToScene(mViewRect).boundingRect(); -} - -void QGVMapQGView::changeState(QGV::MapState state) -{ - if (mState == state) { - return; - } - if (mState == QGV::MapState::Animation) { - QGVCameraState oldCamera = getCamera(); - mState = state; - applyCameraUpdate(oldCamera); - } else { - mState = state; - } - if (mState == QGV::MapState::Idle) { - mWheelMouseArea = QRect(); - mWheelProjAnchor = QPointF(); - mWheelBestFactor = getMinScale(); - mMoveProjAnchor = QPointF(); - mSelectionRect->hideRect(); - } - mGeoMap->onMapState(mState); -} - -void QGVMapQGView::cameraScale(double scale) -{ - const QGVCameraState oldState = getCamera(); - const double oldScale = mScale; - const double newScale = qMax(mMinScale, qMin(mMaxScale, scale)); - if (qFuzzyCompare(oldScale, newScale)) { - return; - } - const double deltaScale = newScale / oldScale; - QGraphicsView::scale(deltaScale, deltaScale); - mScale = newScale; - applyCameraUpdate(oldState); - qgvDebug() << "cameraScale" << scale; -} - -void QGVMapQGView::cameraRotate(double azimuth) -{ - const QGVCameraState oldState = getCamera(); - const double oldAzimuth = fmod(mAzimuth, 360); - const double newAzimuth = fmod(azimuth, 360); - if (qFuzzyCompare(oldAzimuth, newAzimuth)) { - return; - } - QGraphicsView::rotate(newAzimuth - oldAzimuth); - mAzimuth = newAzimuth; - applyCameraUpdate(oldState); - qgvDebug() << "cameraRotate" << azimuth; -} - -void QGVMapQGView::cameraMove(const QPointF& projPos) -{ - const QGVCameraState oldState = getCamera(); - const QPointF oldCenter = viewRect().center(); - if (oldCenter != projPos) { - QGraphicsView::centerOn(projPos); - applyCameraUpdate(oldState); - qgvDebug() << "cameraMove" << projPos; - } -} - -void QGVMapQGView::blockCameraUpdate() -{ - mBlockUpdateCount++; -} - -void QGVMapQGView::unblockCameraUpdate() -{ - if (mBlockUpdateCount == 0) { - return; - } - mBlockUpdateCount--; -} - -void QGVMapQGView::applyCameraUpdate(const QGVCameraState& oldState) -{ - if (mBlockUpdateCount > 0) { - return; - } - QGVCameraState newState = getCamera(); - if (oldState == newState) { - return; - } - mGeoMap->onMapCamera(oldState, newState); -} - -void QGVMapQGView::showTooltip(QHelpEvent* helpEvent) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Tooltip)) { - return; - } - helpEvent->accept(); - const QPointF projMouse = mapToScene(helpEvent->pos()); - QGraphicsItem* item = itemAt(helpEvent->pos()); - QGVDrawItem* geoObject = QGVMapQGItem::geoObjectFromQGItem(item); - QString toolTip = QString(); - if (geoObject != nullptr) { - toolTip = geoObject->projTooltip(projMouse); - } - if (!toolTip.isEmpty()) { - QToolTip::showText(helpEvent->globalPos(), toolTip); - } else { - QToolTip::hideText(); - } -} - -void QGVMapQGView::zoomByWheel(QWheelEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::ZoomWheel)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - if (mState != QGV::MapState::Wheel) { - changeState(QGV::MapState::Wheel); - mWheelMouseArea = QRect(event->pos(), QSize(1, 1)) - .adjusted(-wheelAreaMargin, -wheelAreaMargin, wheelAreaMargin, wheelAreaMargin); - mWheelProjAnchor = mapToScene(event->pos()); - mWheelBestFactor = mScale; - } else { - if (mWheelBestFactor < mScale) { - mWheelProjAnchor = mapToScene(event->pos()); - mWheelBestFactor = mScale; - } - } - - const QGVCameraState oldState = getCamera(); - blockCameraUpdate(); - double newScale = mScale; - if (event->delta() > 0) { - newScale *= wheelExponentDown; - } else { - newScale /= wheelExponentUp; - } - cameraScale(newScale); - const QPointF projMouse = mapToScene(event->pos()); - const double xDelta = (projMouse.x() - mWheelProjAnchor.x()); - const double yDelta = (projMouse.y() - mWheelProjAnchor.y()); - if (!qFuzzyIsNull(xDelta) || !qFuzzyIsNull(yDelta)) { - cameraMove(viewRect().center() - QPointF(xDelta, yDelta)); - } - unblockCameraUpdate(); - applyCameraUpdate(oldState); -} - -void QGVMapQGView::startMoving(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Move)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - changeState(QGV::MapState::Moving); - mMoveProjAnchor = mapToScene(event->pos()); -} - -void QGVMapQGView::startSelectionRect(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Selection) && !mMouseActions.testFlag(QGV::MouseAction::ZoomRect)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - changeState(QGV::MapState::SelectionRect); - mSelectionRect->setStartPoint(event->pos()); - mSelectionRect->showRect(); -} - -void QGVMapQGView::stopSelectionRect(QMouseEvent* event) -{ - const QRect rect = mSelectionRect->getRect(); - changeState(QGV::MapState::Idle); - if (event->modifiers() == Qt::NoModifier) { - zoomArea(event, rect); - } else if (event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier) { - selectObjectsByRect(event, rect); - } -} - -void QGVMapQGView::zoomArea(QMouseEvent* event, QRect areaRect) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::ZoomRect)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - const QRectF newProjRect = mapToScene(areaRect).boundingRect(); - const QGVCameraState oldState = getCamera(); - const QRectF oldProjRect = oldState.projRect(); - const double scaleFactor = - qMin(qAbs(oldProjRect.width() / newProjRect.width()), qAbs(oldProjRect.height() / newProjRect.height())); - auto fly = - new QGVCameraSimpleAnimation(QGVCameraActions(mGeoMap).scaleBy(scaleFactor).moveTo(newProjRect.center())); - fly->setDuration(1500); - fly->start(QAbstractAnimation::DeleteWhenStopped); -} - -void QGVMapQGView::selectObjectsByRect(QMouseEvent* event, QRect selRect) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Selection)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - if (event->modifiers() == Qt::ShiftModifier) { - mGeoMap->unselectAll(); - } - const QRectF projSelRect = QRectF(mGeoMap->geoView()->mapToScene(selRect.topLeft()), - mGeoMap->geoView()->mapToScene(selRect.bottomRight())); - auto selList = mGeoMap->search(projSelRect, Qt::ContainsItemShape); - for (auto* geoObject : selList) { - geoObject->setSelected(!geoObject->isSelected()); - } -} - -void QGVMapQGView::objectClick(QMouseEvent* event) -{ - if (event->button() != Qt::LeftButton) { - return; - } - const QPointF projPos = mGeoMap->geoView()->mapToScene(event->pos()); - auto geoObjects = mGeoMap->search(projPos, Qt::ContainsItemShape); - if (geoObjects.isEmpty()) { - return; - } - auto* geoObject = geoObjects.first(); - if (mMouseActions.testFlag(QGV::MouseAction::Selection) && geoObject->isSelectable()) { - if (event->button() == Qt::LeftButton) { - const bool wasSelect = geoObject->isSelected(); - if (event->modifiers() == Qt::NoModifier) { - geoObject->getMap()->unselectAll(); - geoObject->setSelected(!wasSelect); - } - if (event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier) { - geoObject->setSelected(!wasSelect); - } - } - } - if (geoObject->isFlag(QGV::ItemFlag::Clickable)) { - if (event->button() == Qt::LeftButton) { - geoObject->projOnMouseClick(projPos); - } - } -} - -void QGVMapQGView::objectDoubleClick(QMouseEvent* event) -{ - if (event->button() != Qt::LeftButton) { - return; - } - const QPointF projPos = mGeoMap->geoView()->mapToScene(event->pos()); - auto geoObjects = mGeoMap->search(projPos, Qt::ContainsItemShape); - if (geoObjects.isEmpty()) { - return; - } - auto* geoObject = geoObjects.first(); - if (geoObject->isFlag(QGV::ItemFlag::Clickable)) { - if (event->button() == Qt::LeftButton) { - geoObject->projOnMouseDoubleClick(projPos); - } - } -} - -void QGVMapQGView::moveForWheel(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::ZoomWheel)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - if (!mWheelMouseArea.contains(event->pos())) { - changeState(QGV::MapState::Idle); - } -} - -void QGVMapQGView::moveForRect(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Selection) && !mMouseActions.testFlag(QGV::MouseAction::ZoomRect)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - const QPoint endPoint = event->pos(); - mSelectionRect->setEndPoint(endPoint); -} - -void QGVMapQGView::moveMap(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Move)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - const QPointF projCenter = viewRect().center(); - const QPointF projMouse = mapToScene(event->pos()); - const double xDelta = (mMoveProjAnchor.x() - projMouse.x()); - const double yDelta = (mMoveProjAnchor.y() - projMouse.y()); - cameraMove(projCenter + QPointF(xDelta, yDelta)); -} - -void QGVMapQGView::unselectAll(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::Selection)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - mGeoMap->unselectAll(); - changeState(QGV::MapState::Idle); -} - -void QGVMapQGView::showMenu(QMouseEvent* event) -{ - if (!mMouseActions.testFlag(QGV::MouseAction::ContextMenu)) { - changeState(QGV::MapState::Idle); - return; - } - event->accept(); - changeState(QGV::MapState::Idle); - if (mGeoMap->actions().isEmpty()) { - return; - } - mContextMenu->clear(); - mContextMenu->insertActions(0, mGeoMap->actions()); - mContextMenu->exec(mapToGlobal(event->pos())); -} - -bool QGVMapQGView::event(QEvent* event) -{ - event->ignore(); - if (event->type() == QEvent::ToolTip) { - showTooltip(static_cast(event)); - } - return QGraphicsView::event(event); -} - -void QGVMapQGView::wheelEvent(QWheelEvent* event) -{ - event->ignore(); - zoomByWheel(event); - QWidget::wheelEvent(event); -} - -void QGVMapQGView::mousePressEvent(QMouseEvent* event) -{ - event->ignore(); - objectClick(event); - if (event->button() == Qt::LeftButton) { - if (event->modifiers() == Qt::NoModifier) { - startMoving(event); - } - } else if (event->button() == Qt::RightButton) { - startSelectionRect(event); - } - QGraphicsView::mousePressEvent(event); -} - -void QGVMapQGView::mouseReleaseEvent(QMouseEvent* event) -{ - event->ignore(); - if (mState == QGV::MapState::SelectionRect) { - if (mSelectionRect->isSelection()) { - stopSelectionRect(event); - } else { - showMenu(event); - } - } else { - changeState(QGV::MapState::Idle); - } - QGraphicsView::mouseReleaseEvent(event); -} - -void QGVMapQGView::mouseMoveEvent(QMouseEvent* event) -{ - event->ignore(); - if (mState == QGV::MapState::Wheel) { - moveForWheel(event); - } else if (mState == QGV::MapState::Moving) { - moveMap(event); - } else if (mState == QGV::MapState::SelectionRect) { - moveForRect(event); - } - QGraphicsView::mouseMoveEvent(event); -} - -void QGVMapQGView::mouseDoubleClickEvent(QMouseEvent* event) -{ - event->ignore(); - unselectAll(event); - objectDoubleClick(event); - QGraphicsView::mouseDoubleClickEvent(event); -} - -void QGVMapQGView::resizeEvent(QResizeEvent* event) -{ - const QGVCameraState oldState = getCamera(); - QGraphicsView::resizeEvent(event); - mViewRect = viewport()->rect(); - mGeoMap->anchoreWidgets(); - applyCameraUpdate(oldState); -} - -void QGVMapQGView::showEvent(QShowEvent* event) -{ - const QGVCameraState oldState = getCamera(); - QGraphicsView::showEvent(event); - applyCameraUpdate(oldState); -} - -void QGVMapQGView::keyPressEvent(QKeyEvent* event) -{ - QWidget::keyPressEvent(event); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVMapQGView.h" +#include "QGVDrawItem.h" +#include "QGVMap.h" +#include "QGVMapQGItem.h" +#include "QGVMapQGView.h" +#include "QGVMapRubberBand.h" +#include "QGVWidget.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace { +int wheelAreaMargin = 10; +double wheelExponentDown = qPow(2, 1.0 / 5.0); +double wheelExponentUp = qPow(2, 1.0 / 2.0); +} + +QGVMapQGView::QGVMapQGView(QGVMap* geoMap) + : QGraphicsView(geoMap) +{ + Q_ASSERT(geoMap); + mGeoMap = geoMap; + mBlockUpdateCount = 0; + mMinScale = 1e-8; + mMaxScale = 1e+2; + mScale = 1.0; + mAzimuth = 0.0; + mMouseActions = QGV::MouseAction::All; + mViewRect = viewport()->rect(); + mState = QGV::MapState::Idle; + mQGScene.reset(new QGraphicsScene(this)); + mSelectionRect.reset(new QGVMapRubberBand(this)); + mSelectionRect->setMinSelection(QSize(5, 5)); + mContextMenu.reset(new QMenu(this)); + setScene(mQGScene.data()); + setContextMenuPolicy(Qt::NoContextMenu); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setOptimizationFlag(DontSavePainterState, true); + setOptimizationFlag(DontAdjustForAntialiasing, true); + setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); + setRenderHint(QPainter::Antialiasing, true); + setCacheMode(QGraphicsView::CacheBackground); + setMouseTracking(true); + setBackgroundBrush(QBrush(Qt::lightGray)); +} + +void QGVMapQGView::setMouseActions(QGV::MouseActions actions) +{ + mMouseActions = actions; +} + +QGV::MouseActions QGVMapQGView::getMouseActions() const +{ + return mMouseActions; +} + +QGVCameraState QGVMapQGView::getCamera() const +{ + const bool animation = mState == QGV::MapState::Animation; + return QGVCameraState(mGeoMap, mAzimuth, mScale, viewRect(), animation); +} + +void QGVMapQGView::cameraTo(const QGVCameraActions& actions, bool animation) +{ + const QGVCameraState oldState = getCamera(); + blockCameraUpdate(); + changeState((animation) ? QGV::MapState::Animation : QGV::MapState::Idle); + cameraScale(actions.scale()); + cameraMove(actions.projCenter()); + cameraRotate(actions.azimuth()); + unblockCameraUpdate(); + applyCameraUpdate(oldState); +} + +double QGVMapQGView::getMinScale() const +{ + return mMinScale; +} + +double QGVMapQGView::getMaxScale() const +{ + return mMaxScale; +} + +void QGVMapQGView::setScaleLimits(double minScale, double maxScale) +{ + mMinScale = minScale; + mMaxScale = maxScale; + cameraScale(mScale); +} + +void QGVMapQGView::cleanState() +{ + changeState(QGV::MapState::Idle); +} + +QRectF QGVMapQGView::viewRect() const +{ + return mapToScene(mViewRect).boundingRect(); +} + +void QGVMapQGView::changeState(QGV::MapState state) +{ + if (mState == state) { + return; + } + if (mState == QGV::MapState::Animation) { + QGVCameraState oldCamera = getCamera(); + mState = state; + applyCameraUpdate(oldCamera); + } else { + mState = state; + } + if (mState == QGV::MapState::Idle) { + mWheelMouseArea = QRect(); + mWheelProjAnchor = QPointF(); + mWheelBestFactor = getMinScale(); + mMoveProjAnchor = QPointF(); + mSelectionRect->hideRect(); + } + mGeoMap->onMapState(mState); +} + +void QGVMapQGView::cameraScale(double scale) +{ + const QGVCameraState oldState = getCamera(); + const double oldScale = mScale; + const double newScale = qMax(mMinScale, qMin(mMaxScale, scale)); + if (qFuzzyCompare(oldScale, newScale)) { + return; + } + const double deltaScale = newScale / oldScale; + QGraphicsView::scale(deltaScale, deltaScale); + mScale = newScale; + applyCameraUpdate(oldState); + qgvDebug() << "cameraScale" << scale; +} + +void QGVMapQGView::cameraRotate(double azimuth) +{ + const QGVCameraState oldState = getCamera(); + const double oldAzimuth = fmod(mAzimuth, 360); + const double newAzimuth = fmod(azimuth, 360); + if (qFuzzyCompare(oldAzimuth, newAzimuth)) { + return; + } + QGraphicsView::rotate(newAzimuth - oldAzimuth); + mAzimuth = newAzimuth; + applyCameraUpdate(oldState); + qgvDebug() << "cameraRotate" << azimuth; +} + +void QGVMapQGView::cameraMove(const QPointF& projPos) +{ + const QGVCameraState oldState = getCamera(); + const QPointF oldCenter = viewRect().center(); + if (oldCenter != projPos) { + QGraphicsView::centerOn(projPos); + applyCameraUpdate(oldState); + qgvDebug() << "cameraMove" << projPos; + } +} + +void QGVMapQGView::blockCameraUpdate() +{ + mBlockUpdateCount++; +} + +void QGVMapQGView::unblockCameraUpdate() +{ + if (mBlockUpdateCount == 0) { + return; + } + mBlockUpdateCount--; +} + +void QGVMapQGView::applyCameraUpdate(const QGVCameraState& oldState) +{ + if (mBlockUpdateCount > 0) { + return; + } + QGVCameraState newState = getCamera(); + if (oldState == newState) { + return; + } + mGeoMap->onMapCamera(oldState, newState); +} + +void QGVMapQGView::showTooltip(QHelpEvent* helpEvent) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Tooltip)) { + return; + } + helpEvent->accept(); + const QPointF projMouse = mapToScene(helpEvent->pos()); + QGraphicsItem* item = itemAt(helpEvent->pos()); + QGVDrawItem* geoObject = QGVMapQGItem::geoObjectFromQGItem(item); + QString toolTip = QString(); + if (geoObject != nullptr) { + toolTip = geoObject->projTooltip(projMouse); + } + if (!toolTip.isEmpty()) { + QToolTip::showText(helpEvent->globalPos(), toolTip); + } else { + QToolTip::hideText(); + } +} + +void QGVMapQGView::zoomByWheel(QWheelEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::ZoomWheel)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + if (mState != QGV::MapState::Wheel) { + changeState(QGV::MapState::Wheel); + mWheelMouseArea = QRect(event->pos(), QSize(1, 1)) + .adjusted(-wheelAreaMargin, -wheelAreaMargin, wheelAreaMargin, wheelAreaMargin); + mWheelProjAnchor = mapToScene(event->pos()); + mWheelBestFactor = mScale; + } else { + if (mWheelBestFactor < mScale) { + mWheelProjAnchor = mapToScene(event->pos()); + mWheelBestFactor = mScale; + } + } + + const QGVCameraState oldState = getCamera(); + blockCameraUpdate(); + double newScale = mScale; + if (event->delta() > 0) { + newScale *= wheelExponentDown; + } else { + newScale /= wheelExponentUp; + } + cameraScale(newScale); + const QPointF projMouse = mapToScene(event->pos()); + const double xDelta = (projMouse.x() - mWheelProjAnchor.x()); + const double yDelta = (projMouse.y() - mWheelProjAnchor.y()); + if (!qFuzzyIsNull(xDelta) || !qFuzzyIsNull(yDelta)) { + cameraMove(viewRect().center() - QPointF(xDelta, yDelta)); + } + unblockCameraUpdate(); + applyCameraUpdate(oldState); +} + +void QGVMapQGView::startMoving(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Move)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + changeState(QGV::MapState::Moving); + mMoveProjAnchor = mapToScene(event->pos()); +} + +void QGVMapQGView::startSelectionRect(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Selection) && !mMouseActions.testFlag(QGV::MouseAction::ZoomRect)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + changeState(QGV::MapState::SelectionRect); + mSelectionRect->setStartPoint(event->pos()); + mSelectionRect->showRect(); +} + +void QGVMapQGView::stopSelectionRect(QMouseEvent* event) +{ + const QRect rect = mSelectionRect->getRect(); + changeState(QGV::MapState::Idle); + if (event->modifiers() == Qt::NoModifier) { + zoomArea(event, rect); + } else if (event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier) { + selectObjectsByRect(event, rect); + } +} + +void QGVMapQGView::zoomArea(QMouseEvent* event, QRect areaRect) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::ZoomRect)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + const QRectF newProjRect = mapToScene(areaRect).boundingRect(); + const QGVCameraState oldState = getCamera(); + const QRectF oldProjRect = oldState.projRect(); + const double scaleFactor = + qMin(qAbs(oldProjRect.width() / newProjRect.width()), qAbs(oldProjRect.height() / newProjRect.height())); + auto fly = + new QGVCameraSimpleAnimation(QGVCameraActions(mGeoMap).scaleBy(scaleFactor).moveTo(newProjRect.center())); + fly->setDuration(1500); + fly->start(QAbstractAnimation::DeleteWhenStopped); +} + +void QGVMapQGView::selectObjectsByRect(QMouseEvent* event, QRect selRect) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Selection)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + if (event->modifiers() == Qt::ShiftModifier) { + mGeoMap->unselectAll(); + } + const QRectF projSelRect = QRectF(mGeoMap->geoView()->mapToScene(selRect.topLeft()), + mGeoMap->geoView()->mapToScene(selRect.bottomRight())); + auto selList = mGeoMap->search(projSelRect, Qt::ContainsItemShape); + for (auto* geoObject : selList) { + geoObject->setSelected(!geoObject->isSelected()); + } +} + +void QGVMapQGView::objectClick(QMouseEvent* event) +{ + if (event->button() != Qt::LeftButton) { + return; + } + const QPointF projPos = mGeoMap->geoView()->mapToScene(event->pos()); + auto geoObjects = mGeoMap->search(projPos, Qt::ContainsItemShape); + if (geoObjects.isEmpty()) { + return; + } + auto* geoObject = geoObjects.first(); + if (mMouseActions.testFlag(QGV::MouseAction::Selection) && geoObject->isSelectable()) { + if (event->button() == Qt::LeftButton) { + const bool wasSelect = geoObject->isSelected(); + if (event->modifiers() == Qt::NoModifier) { + geoObject->getMap()->unselectAll(); + geoObject->setSelected(!wasSelect); + } + if (event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier) { + geoObject->setSelected(!wasSelect); + } + } + } + if (geoObject->isFlag(QGV::ItemFlag::Clickable)) { + if (event->button() == Qt::LeftButton) { + geoObject->projOnMouseClick(projPos); + } + } +} + +void QGVMapQGView::objectDoubleClick(QMouseEvent* event) +{ + if (event->button() != Qt::LeftButton) { + return; + } + const QPointF projPos = mGeoMap->geoView()->mapToScene(event->pos()); + auto geoObjects = mGeoMap->search(projPos, Qt::ContainsItemShape); + if (geoObjects.isEmpty()) { + return; + } + auto* geoObject = geoObjects.first(); + if (geoObject->isFlag(QGV::ItemFlag::Clickable)) { + if (event->button() == Qt::LeftButton) { + geoObject->projOnMouseDoubleClick(projPos); + } + } +} + +void QGVMapQGView::moveForWheel(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::ZoomWheel)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + if (!mWheelMouseArea.contains(event->pos())) { + changeState(QGV::MapState::Idle); + } +} + +void QGVMapQGView::moveForRect(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Selection) && !mMouseActions.testFlag(QGV::MouseAction::ZoomRect)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + const QPoint endPoint = event->pos(); + mSelectionRect->setEndPoint(endPoint); +} + +void QGVMapQGView::moveMap(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Move)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + const QPointF projCenter = viewRect().center(); + const QPointF projMouse = mapToScene(event->pos()); + const double xDelta = (mMoveProjAnchor.x() - projMouse.x()); + const double yDelta = (mMoveProjAnchor.y() - projMouse.y()); + cameraMove(projCenter + QPointF(xDelta, yDelta)); +} + +void QGVMapQGView::unselectAll(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::Selection)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + mGeoMap->unselectAll(); + changeState(QGV::MapState::Idle); +} + +void QGVMapQGView::showMenu(QMouseEvent* event) +{ + if (!mMouseActions.testFlag(QGV::MouseAction::ContextMenu)) { + changeState(QGV::MapState::Idle); + return; + } + event->accept(); + changeState(QGV::MapState::Idle); + if (mGeoMap->actions().isEmpty()) { + return; + } + mContextMenu->clear(); + mContextMenu->insertActions(0, mGeoMap->actions()); + mContextMenu->exec(mapToGlobal(event->pos())); +} + +bool QGVMapQGView::event(QEvent* event) +{ + event->ignore(); + if (event->type() == QEvent::ToolTip) { + showTooltip(static_cast(event)); + } + return QGraphicsView::event(event); +} + +void QGVMapQGView::wheelEvent(QWheelEvent* event) +{ + event->ignore(); + zoomByWheel(event); + QWidget::wheelEvent(event); +} + +void QGVMapQGView::mousePressEvent(QMouseEvent* event) +{ + event->ignore(); + objectClick(event); + if (event->button() == Qt::LeftButton) { + if (event->modifiers() == Qt::NoModifier) { + startMoving(event); + } + } else if (event->button() == Qt::RightButton) { + startSelectionRect(event); + } + QGraphicsView::mousePressEvent(event); +} + +void QGVMapQGView::mouseReleaseEvent(QMouseEvent* event) +{ + event->ignore(); + if (mState == QGV::MapState::SelectionRect) { + if (mSelectionRect->isSelection()) { + stopSelectionRect(event); + } else { + showMenu(event); + } + } else { + changeState(QGV::MapState::Idle); + } + QGraphicsView::mouseReleaseEvent(event); +} + +void QGVMapQGView::mouseMoveEvent(QMouseEvent* event) +{ + event->ignore(); + if (mState == QGV::MapState::Wheel) { + moveForWheel(event); + } else if (mState == QGV::MapState::Moving) { + moveMap(event); + } else if (mState == QGV::MapState::SelectionRect) { + moveForRect(event); + } + QGraphicsView::mouseMoveEvent(event); +} + +void QGVMapQGView::mouseDoubleClickEvent(QMouseEvent* event) +{ + event->ignore(); + unselectAll(event); + objectDoubleClick(event); + QGraphicsView::mouseDoubleClickEvent(event); +} + +void QGVMapQGView::resizeEvent(QResizeEvent* event) +{ + const QGVCameraState oldState = getCamera(); + QGraphicsView::resizeEvent(event); + mViewRect = viewport()->rect(); + mGeoMap->anchoreWidgets(); + applyCameraUpdate(oldState); +} + +void QGVMapQGView::showEvent(QShowEvent* event) +{ + const QGVCameraState oldState = getCamera(); + QGraphicsView::showEvent(event); + applyCameraUpdate(oldState); +} + +void QGVMapQGView::keyPressEvent(QKeyEvent* event) +{ + QWidget::keyPressEvent(event); +} diff --git a/lib/src/QGVMapRubberBand.cpp b/lib/src/QGVMapRubberBand.cpp index cbb8e35..e419cd2 100644 --- a/lib/src/QGVMapRubberBand.cpp +++ b/lib/src/QGVMapRubberBand.cpp @@ -1,108 +1,108 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVMapRubberBand.h" - -QGVMapRubberBand::QGVMapRubberBand(QWidget* parent) - : QObject(parent) -{ - setMinSelection(QSize(0, 0)); - setStartPoint(QPoint(0, 0)); -} - -void QGVMapRubberBand::setMinSelection(const QSize& min) -{ - mMin = min; -} - -void QGVMapRubberBand::setStartPoint(const QPoint& point) -{ - mStartPoint = point; - mEndPoint = point; - updateRect(); -} - -void QGVMapRubberBand::setEndPoint(const QPoint& point) -{ - mEndPoint = point; - updateRect(); -} - -bool QGVMapRubberBand::isActive() const -{ - return mRubberBand != nullptr; -} - -bool QGVMapRubberBand::isSelection() const -{ - if (isActive() == false) { - return false; - } - const QRect rect = getRect(); - return rect.width() > mMin.width() && rect.height() > mMin.height(); -} - -QRect QGVMapRubberBand::getRect() const -{ - QRect result; - if (mStartPoint.x() <= mEndPoint.x()) { - result.setLeft(mStartPoint.x()); - result.setRight(mEndPoint.x()); - } else { - result.setLeft(mEndPoint.x()); - result.setRight(mStartPoint.x()); - } - if (mStartPoint.y() <= mEndPoint.y()) { - result.setTop(mStartPoint.y()); - result.setBottom(mEndPoint.y()); - } else { - result.setTop(mEndPoint.y()); - result.setBottom(mStartPoint.y()); - } - return result; -} - -void QGVMapRubberBand::showRect() -{ - QWidget* myParent = nullptr; - if (parent() != nullptr) { - myParent = dynamic_cast(parent()); - } - if (myParent == nullptr) { - return; - } - mRubberBand.reset(new QRubberBand(QRubberBand::Rectangle, myParent)); - updateRect(); -} - -void QGVMapRubberBand::hideRect() -{ - mRubberBand.reset(nullptr); -} - -void QGVMapRubberBand::updateRect() -{ - if (isActive()) { - mRubberBand->setGeometry(getRect()); - if (isSelection()) { - mRubberBand->show(); - } else { - mRubberBand->hide(); - } - } -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVMapRubberBand.h" + +QGVMapRubberBand::QGVMapRubberBand(QWidget* parent) + : QObject(parent) +{ + setMinSelection(QSize(0, 0)); + setStartPoint(QPoint(0, 0)); +} + +void QGVMapRubberBand::setMinSelection(const QSize& min) +{ + mMin = min; +} + +void QGVMapRubberBand::setStartPoint(const QPoint& point) +{ + mStartPoint = point; + mEndPoint = point; + updateRect(); +} + +void QGVMapRubberBand::setEndPoint(const QPoint& point) +{ + mEndPoint = point; + updateRect(); +} + +bool QGVMapRubberBand::isActive() const +{ + return mRubberBand != nullptr; +} + +bool QGVMapRubberBand::isSelection() const +{ + if (isActive() == false) { + return false; + } + const QRect rect = getRect(); + return rect.width() > mMin.width() && rect.height() > mMin.height(); +} + +QRect QGVMapRubberBand::getRect() const +{ + QRect result; + if (mStartPoint.x() <= mEndPoint.x()) { + result.setLeft(mStartPoint.x()); + result.setRight(mEndPoint.x()); + } else { + result.setLeft(mEndPoint.x()); + result.setRight(mStartPoint.x()); + } + if (mStartPoint.y() <= mEndPoint.y()) { + result.setTop(mStartPoint.y()); + result.setBottom(mEndPoint.y()); + } else { + result.setTop(mEndPoint.y()); + result.setBottom(mStartPoint.y()); + } + return result; +} + +void QGVMapRubberBand::showRect() +{ + QWidget* myParent = nullptr; + if (parent() != nullptr) { + myParent = dynamic_cast(parent()); + } + if (myParent == nullptr) { + return; + } + mRubberBand.reset(new QRubberBand(QRubberBand::Rectangle, myParent)); + updateRect(); +} + +void QGVMapRubberBand::hideRect() +{ + mRubberBand.reset(nullptr); +} + +void QGVMapRubberBand::updateRect() +{ + if (isActive()) { + mRubberBand->setGeometry(getRect()); + if (isSelection()) { + mRubberBand->show(); + } else { + mRubberBand->hide(); + } + } +} diff --git a/lib/src/QGVProjection.cpp b/lib/src/QGVProjection.cpp index 9684ba5..ad4b973 100644 --- a/lib/src/QGVProjection.cpp +++ b/lib/src/QGVProjection.cpp @@ -1,41 +1,40 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 - -QGVProjection::QGVProjection(const QString& id, const QString& name, const QString& description) - : mID(id) - , mName(name) - , mDescription(description) -{ -} - -QString QGVProjection::getID() const -{ - return mID; -} - -QString QGVProjection::getName() const -{ - return mName; -} - -QString QGVProjection::getDescription() const -{ - return mDescription; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 + +QGVProjection::QGVProjection(const QString& id, const QString& name, const QString& description) + : mID(id) + , mName(name) + , mDescription(description) +{} + +QString QGVProjection::getID() const +{ + return mID; +} + +QString QGVProjection::getName() const +{ + return mName; +} + +QString QGVProjection::getDescription() const +{ + return mDescription; +} diff --git a/lib/src/QGVProjectionEPSG3857.cpp b/lib/src/QGVProjectionEPSG3857.cpp index 5d48723..ed52581 100644 --- a/lib/src/QGVProjectionEPSG3857.cpp +++ b/lib/src/QGVProjectionEPSG3857.cpp @@ -1,90 +1,90 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVProjectionEPSG3857.h" - -#include -#include - -QGVProjectionEPSG3857::QGVProjectionEPSG3857() - : QGVProjection("EPSG3857", - "WGS84 Web Mercator", - "QGVProjection used in web mapping applications like " - "Google/Bing/OpenStreetMap/etc. Sometimes known as " - "EPSG:900913.") -{ - mEarthRadius = 6378137.0; /* meters */ - mOriginShift = 2.0 * M_PI * mEarthRadius / 2.0; - mGeoBoundary = QGV::GeoRect(85, -180, -85, +180); - mProjBoundary = geoToProj(mGeoBoundary); -} - -QGV::GeoRect QGVProjectionEPSG3857::boundaryGeoRect() const -{ - return mGeoBoundary; -} - -QRectF QGVProjectionEPSG3857::boundaryProjRect() const -{ - return mProjBoundary; -} - -QPointF QGVProjectionEPSG3857::geoToProj(const QGV::GeoPos& geoPos) const -{ - const double lon = geoPos.longitude(); - const double lat = (geoPos.latitude() > mGeoBoundary.topLeft().latitude()) ? mGeoBoundary.topLeft().latitude() - : geoPos.latitude(); - const double x = lon * mOriginShift / 180.0; - const double preY = -qLn(qTan((90.0 + lat) * M_PI / 360.0)) / (M_PI / 180.0); - const double y = preY * mOriginShift / 180.0; - return QPointF(x, y); -} - -QGV::GeoPos QGVProjectionEPSG3857::projToGeo(const QPointF& projPos) const -{ - const double lon = (projPos.x() / mOriginShift) * 180.0; - const double preLat = (-projPos.y() / mOriginShift) * 180.0; - const double lat = 180.0 / M_PI * (2.0 * qAtan(qExp(preLat * M_PI / 180.0)) - M_PI / 2.0); - return QGV::GeoPos(lat, lon); -} - -QRectF QGVProjectionEPSG3857::geoToProj(const QGV::GeoRect& geoRect) const -{ - QRectF rect; - rect.setTopLeft(geoToProj(geoRect.topLeft())); - rect.setBottomRight(geoToProj(geoRect.bottomRight())); - return rect; -} - -QGV::GeoRect QGVProjectionEPSG3857::projToGeo(const QRectF& projRect) const -{ - return QGV::GeoRect(projToGeo(projRect.topLeft()), projToGeo(projRect.bottomRight())); -} - -double QGVProjectionEPSG3857::geodesicMeters(const QPointF& projPos1, const QPointF& projPos2) const -{ - const QGV::GeoPos geoPos1 = projToGeo(projPos1); - const QGV::GeoPos geoPos2 = projToGeo(projPos2); - const double latitudeArc = (geoPos1.latitude() - geoPos2.latitude()) * M_PI / 180.0; - const double longitudeArc = (geoPos1.longitude() - geoPos2.longitude()) * M_PI / 180.0; - const double latitudeH = qPow(sin(latitudeArc * 0.5), 2); - const double lontitudeH = qPow(sin(longitudeArc * 0.5), 2); - const double lonFactor = cos(geoPos1.latitude() * M_PI / 180.0) * cos(geoPos2.latitude() * M_PI / 180.0); - const double arcInRadians = 2.0 * asin(sqrt(latitudeH + lonFactor * lontitudeH)); - return mEarthRadius * arcInRadians; -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVProjectionEPSG3857.h" + +#include +#include + +QGVProjectionEPSG3857::QGVProjectionEPSG3857() + : QGVProjection("EPSG3857", + "WGS84 Web Mercator", + "QGVProjection used in web mapping applications like " + "Google/Bing/OpenStreetMap/etc. Sometimes known as " + "EPSG:900913.") +{ + mEarthRadius = 6378137.0; /* meters */ + mOriginShift = 2.0 * M_PI * mEarthRadius / 2.0; + mGeoBoundary = QGV::GeoRect(85, -180, -85, +180); + mProjBoundary = geoToProj(mGeoBoundary); +} + +QGV::GeoRect QGVProjectionEPSG3857::boundaryGeoRect() const +{ + return mGeoBoundary; +} + +QRectF QGVProjectionEPSG3857::boundaryProjRect() const +{ + return mProjBoundary; +} + +QPointF QGVProjectionEPSG3857::geoToProj(const QGV::GeoPos& geoPos) const +{ + const double lon = geoPos.longitude(); + const double lat = (geoPos.latitude() > mGeoBoundary.topLeft().latitude()) ? mGeoBoundary.topLeft().latitude() + : geoPos.latitude(); + const double x = lon * mOriginShift / 180.0; + const double preY = -qLn(qTan((90.0 + lat) * M_PI / 360.0)) / (M_PI / 180.0); + const double y = preY * mOriginShift / 180.0; + return QPointF(x, y); +} + +QGV::GeoPos QGVProjectionEPSG3857::projToGeo(const QPointF& projPos) const +{ + const double lon = (projPos.x() / mOriginShift) * 180.0; + const double preLat = (-projPos.y() / mOriginShift) * 180.0; + const double lat = 180.0 / M_PI * (2.0 * qAtan(qExp(preLat * M_PI / 180.0)) - M_PI / 2.0); + return QGV::GeoPos(lat, lon); +} + +QRectF QGVProjectionEPSG3857::geoToProj(const QGV::GeoRect& geoRect) const +{ + QRectF rect; + rect.setTopLeft(geoToProj(geoRect.topLeft())); + rect.setBottomRight(geoToProj(geoRect.bottomRight())); + return rect; +} + +QGV::GeoRect QGVProjectionEPSG3857::projToGeo(const QRectF& projRect) const +{ + return QGV::GeoRect(projToGeo(projRect.topLeft()), projToGeo(projRect.bottomRight())); +} + +double QGVProjectionEPSG3857::geodesicMeters(const QPointF& projPos1, const QPointF& projPos2) const +{ + const QGV::GeoPos geoPos1 = projToGeo(projPos1); + const QGV::GeoPos geoPos2 = projToGeo(projPos2); + const double latitudeArc = (geoPos1.latitude() - geoPos2.latitude()) * M_PI / 180.0; + const double longitudeArc = (geoPos1.longitude() - geoPos2.longitude()) * M_PI / 180.0; + const double latitudeH = qPow(sin(latitudeArc * 0.5), 2); + const double lontitudeH = qPow(sin(longitudeArc * 0.5), 2); + const double lonFactor = cos(geoPos1.latitude() * M_PI / 180.0) * cos(geoPos2.latitude() * M_PI / 180.0); + const double arcInRadians = 2.0 * asin(sqrt(latitudeH + lonFactor * lontitudeH)); + return mEarthRadius * arcInRadians; +} diff --git a/lib/src/QGVWidget.cpp b/lib/src/QGVWidget.cpp index fbb5d53..046d4b5 100644 --- a/lib/src/QGVWidget.cpp +++ b/lib/src/QGVWidget.cpp @@ -1,141 +1,139 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVWidget.h" -#include "QGVMapQGView.h" - -QGVWidget::QGVWidget() -{ - mGeoMap = nullptr; - mAnchor = QPoint(0, 0); - mEdge.clear(); -} - -QGVWidget::~QGVWidget() -{ - if (mGeoMap != nullptr) { - mGeoMap->removeWidget(this); - } -} - -void QGVWidget::setMap(QGVMap* geoMap) -{ - mGeoMap = geoMap; - if (mGeoMap != nullptr) { - setParent(mGeoMap->geoView()); - } else { - setParent(nullptr); - } - onProjection(mGeoMap); - anchoreWidget(); -} - -QGVMap* QGVWidget::getMap() const -{ - return mGeoMap; -} - -void QGVWidget::setAnchor(QPoint anchor, QSet edge) -{ - mAnchor = anchor; - mEdge = edge; - anchoreWidget(); -} - -QPointF QGVWidget::getAnchor() const -{ - return mAnchor; -} - -QSet QGVWidget::getEdge() const -{ - return mEdge; -} - -bool QGVWidget::isAnchorLeft() const -{ - return (mEdge.contains(Qt::LeftEdge) && !mEdge.contains(Qt::RightEdge)); -} - -bool QGVWidget::isAnchorRight() const -{ - return (!mEdge.contains(Qt::LeftEdge) && mEdge.contains(Qt::RightEdge)); -} - -bool QGVWidget::isAnchorHCenter() const -{ - return !isAnchorLeft() && !isAnchorRight(); -} - -bool QGVWidget::isAnchorTop() const -{ - return (mEdge.contains(Qt::TopEdge) && !mEdge.contains(Qt::BottomEdge)); -} - -bool QGVWidget::isAnchorBottom() const -{ - return (!mEdge.contains(Qt::TopEdge) && mEdge.contains(Qt::BottomEdge)); -} - -bool QGVWidget::isAnchorVCenter() const -{ - return !isAnchorTop() && !isAnchorBottom(); -} - -void QGVWidget::anchoreWidget() -{ - if (parentWidget() == nullptr) { - return; - } - const int parentWidth = parentWidget()->width(); - const int parentHeight = parentWidget()->height(); - int leftOffset = 0; - int topOffset = 0; - if (isAnchorLeft()) { - leftOffset = mAnchor.x(); - } - if (isAnchorRight()) { - leftOffset = parentWidth - width() - mAnchor.x(); - } - if (isAnchorHCenter()) { - leftOffset = parentWidth / 2 - width() / 2 + mAnchor.x(); - } - if (isAnchorTop()) { - topOffset = mAnchor.y(); - } - if (isAnchorBottom()) { - topOffset = parentHeight - height() - mAnchor.y(); - } - if (isAnchorVCenter()) { - topOffset = parentHeight / 2 - height() / 2 + mAnchor.y(); - } - move(leftOffset, topOffset); -} - -void QGVWidget::onProjection(QGVMap* /*geoMap*/) -{ -} - -void QGVWidget::onCamera(const QGVCameraState& /*oldState*/, const QGVCameraState& /*newState*/) -{ -} - -void QGVWidget::resizeEvent(QResizeEvent* /*event*/) -{ - anchoreWidget(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVWidget.h" +#include "QGVMapQGView.h" + +QGVWidget::QGVWidget() +{ + mGeoMap = nullptr; + mAnchor = QPoint(0, 0); + mEdge.clear(); +} + +QGVWidget::~QGVWidget() +{ + if (mGeoMap != nullptr) { + mGeoMap->removeWidget(this); + } +} + +void QGVWidget::setMap(QGVMap* geoMap) +{ + mGeoMap = geoMap; + if (mGeoMap != nullptr) { + setParent(mGeoMap->geoView()); + } else { + setParent(nullptr); + } + onProjection(mGeoMap); + anchoreWidget(); +} + +QGVMap* QGVWidget::getMap() const +{ + return mGeoMap; +} + +void QGVWidget::setAnchor(QPoint anchor, QSet edge) +{ + mAnchor = anchor; + mEdge = edge; + anchoreWidget(); +} + +QPointF QGVWidget::getAnchor() const +{ + return mAnchor; +} + +QSet QGVWidget::getEdge() const +{ + return mEdge; +} + +bool QGVWidget::isAnchorLeft() const +{ + return (mEdge.contains(Qt::LeftEdge) && !mEdge.contains(Qt::RightEdge)); +} + +bool QGVWidget::isAnchorRight() const +{ + return (!mEdge.contains(Qt::LeftEdge) && mEdge.contains(Qt::RightEdge)); +} + +bool QGVWidget::isAnchorHCenter() const +{ + return !isAnchorLeft() && !isAnchorRight(); +} + +bool QGVWidget::isAnchorTop() const +{ + return (mEdge.contains(Qt::TopEdge) && !mEdge.contains(Qt::BottomEdge)); +} + +bool QGVWidget::isAnchorBottom() const +{ + return (!mEdge.contains(Qt::TopEdge) && mEdge.contains(Qt::BottomEdge)); +} + +bool QGVWidget::isAnchorVCenter() const +{ + return !isAnchorTop() && !isAnchorBottom(); +} + +void QGVWidget::anchoreWidget() +{ + if (parentWidget() == nullptr) { + return; + } + const int parentWidth = parentWidget()->width(); + const int parentHeight = parentWidget()->height(); + int leftOffset = 0; + int topOffset = 0; + if (isAnchorLeft()) { + leftOffset = mAnchor.x(); + } + if (isAnchorRight()) { + leftOffset = parentWidth - width() - mAnchor.x(); + } + if (isAnchorHCenter()) { + leftOffset = parentWidth / 2 - width() / 2 + mAnchor.x(); + } + if (isAnchorTop()) { + topOffset = mAnchor.y(); + } + if (isAnchorBottom()) { + topOffset = parentHeight - height() - mAnchor.y(); + } + if (isAnchorVCenter()) { + topOffset = parentHeight / 2 - height() / 2 + mAnchor.y(); + } + move(leftOffset, topOffset); +} + +void QGVWidget::onProjection(QGVMap* /*geoMap*/) +{} + +void QGVWidget::onCamera(const QGVCameraState& /*oldState*/, const QGVCameraState& /*newState*/) +{} + +void QGVWidget::resizeEvent(QResizeEvent* /*event*/) +{ + anchoreWidget(); +} diff --git a/lib/src/QGVWidgetCompass.cpp b/lib/src/QGVWidgetCompass.cpp index 84992ce..7b539d6 100644 --- a/lib/src/QGVWidgetCompass.cpp +++ b/lib/src/QGVWidgetCompass.cpp @@ -1,142 +1,142 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVWidgetCompass.h" - -#include -#include -#include -#include - -namespace { -const int defaultRadius = 4; -const double stickyAngleMargin = 5; -} - -QGVWidgetCompass::QGVWidgetCompass() -{ - setMouseTracking(true); - setAnchor(QPoint(10, 10), { Qt::LeftEdge, Qt::TopEdge }); - setPixmap(QPixmap()); - mTracking = false; - mOffset = 0; - setPixmap(createPixmap()); -} - -void QGVWidgetCompass::setPixmap(QPixmap pixmap) -{ - mPixmap = pixmap; - if (mPixmap.isNull()) { - resize(QSize(defaultRadius, defaultRadius)); - } else { - resize(mPixmap.size()); - } -} - -QPixmap QGVWidgetCompass::createPixmap() -{ - static const QPolygon polygon = QVector{ - QPoint(0, 60), QPoint(20, 0), QPoint(40, 60), QPoint(20, 45), QPoint(00, 60), - }; - - int maxSize = polygon.boundingRect().height(); - maxSize = qSqrt(qPow(maxSize, 2) + qPow(maxSize, 2)); - const QRect rect = QRect(QPoint(0, 0), QSize(maxSize, maxSize)); - const QPointF centerDelta = rect.center() - polygon.boundingRect().center(); - - QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied); - image.fill(qRgba(0, 0, 0, 0)); - QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); - QPainter painter(&pixmap); - QPen pen = QPen(Qt::black); - pen.setWidth(1); - pen.setCosmetic(true); - painter.setPen(pen); - QBrush brush = QBrush(Qt::blue); - painter.setBrush(brush); - QPainterPath path; - path.addPolygon(polygon); - path.translate(centerDelta + QPointF(pen.width(), pen.width())); - painter.drawPath(path); - return pixmap; -} - -double QGVWidgetCompass::mouseToAzimuth(const QPoint& pos, double offset) const -{ - const QLineF northLine(rect().center(), QPointF(rect().center().x(), rect().top())); - const QLineF posLine(rect().center(), pos); - if (posLine.length() >= 10) { - double azimuth = posLine.angleTo(northLine) + offset; - if (qAbs(fmod(azimuth, 90.0)) <= stickyAngleMargin || qAbs(fmod(azimuth, 90.0)) >= 90.0 - stickyAngleMargin) { - azimuth = 90.0 * qRound(azimuth / 90.0); - } - return azimuth; - } - return getMap()->getCamera().azimuth(); -} - -void QGVWidgetCompass::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) -{ - QGVWidget::onCamera(oldState, newState); - if (qFuzzyCompare(oldState.azimuth(), newState.azimuth())) { - return; - } - mTransfrom = QGV::createTransfromAzimuth(mPixmap.rect().center(), newState.azimuth()); - repaint(); -} - -void QGVWidgetCompass::paintEvent(QPaintEvent* /*event*/) -{ - if (mPixmap.isNull()) { - return; - } - QPainter painter(this); - if (mTracking) { - painter.setOpacity(0.5); - } - painter.setTransform(mTransfrom); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - painter.drawImage(QRect(0, 0, width(), height()), mPixmap.toImage(), mPixmap.rect()); -} - -void QGVWidgetCompass::mouseMoveEvent(QMouseEvent* event) -{ - if (mTracking) { - const double azimuth = mouseToAzimuth(event->pos(), -mOffset); - getMap()->cameraTo(QGVCameraActions(getMap()).rotateTo(azimuth)); - } -} - -void QGVWidgetCompass::mousePressEvent(QMouseEvent* event) -{ - const double azimuth = getMap()->getCamera().azimuth(); - mOffset = mouseToAzimuth(event->pos(), -azimuth); - mTracking = true; - repaint(); -} - -void QGVWidgetCompass::mouseReleaseEvent(QMouseEvent* /*event*/) -{ - mTracking = false; - repaint(); -} - -void QGVWidgetCompass::mouseDoubleClickEvent(QMouseEvent* /*event*/) -{ - getMap()->cameraTo(QGVCameraActions(getMap()).rotateTo(0)); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVWidgetCompass.h" + +#include +#include +#include +#include + +namespace { +const int defaultRadius = 4; +const double stickyAngleMargin = 5; +} + +QGVWidgetCompass::QGVWidgetCompass() +{ + setMouseTracking(true); + setAnchor(QPoint(10, 10), { Qt::LeftEdge, Qt::TopEdge }); + setPixmap(QPixmap()); + mTracking = false; + mOffset = 0; + setPixmap(createPixmap()); +} + +void QGVWidgetCompass::setPixmap(QPixmap pixmap) +{ + mPixmap = pixmap; + if (mPixmap.isNull()) { + resize(QSize(defaultRadius, defaultRadius)); + } else { + resize(mPixmap.size()); + } +} + +QPixmap QGVWidgetCompass::createPixmap() +{ + static const QPolygon polygon = QVector{ + QPoint(0, 60), QPoint(20, 0), QPoint(40, 60), QPoint(20, 45), QPoint(00, 60), + }; + + int maxSize = polygon.boundingRect().height(); + maxSize = qSqrt(qPow(maxSize, 2) + qPow(maxSize, 2)); + const QRect rect = QRect(QPoint(0, 0), QSize(maxSize, maxSize)); + const QPointF centerDelta = rect.center() - polygon.boundingRect().center(); + + QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied); + image.fill(qRgba(0, 0, 0, 0)); + QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); + QPainter painter(&pixmap); + QPen pen = QPen(Qt::black); + pen.setWidth(1); + pen.setCosmetic(true); + painter.setPen(pen); + QBrush brush = QBrush(Qt::blue); + painter.setBrush(brush); + QPainterPath path; + path.addPolygon(polygon); + path.translate(centerDelta + QPointF(pen.width(), pen.width())); + painter.drawPath(path); + return pixmap; +} + +double QGVWidgetCompass::mouseToAzimuth(const QPoint& pos, double offset) const +{ + const QLineF northLine(rect().center(), QPointF(rect().center().x(), rect().top())); + const QLineF posLine(rect().center(), pos); + if (posLine.length() >= 10) { + double azimuth = posLine.angleTo(northLine) + offset; + if (qAbs(fmod(azimuth, 90.0)) <= stickyAngleMargin || qAbs(fmod(azimuth, 90.0)) >= 90.0 - stickyAngleMargin) { + azimuth = 90.0 * qRound(azimuth / 90.0); + } + return azimuth; + } + return getMap()->getCamera().azimuth(); +} + +void QGVWidgetCompass::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) +{ + QGVWidget::onCamera(oldState, newState); + if (qFuzzyCompare(oldState.azimuth(), newState.azimuth())) { + return; + } + mTransfrom = QGV::createTransfromAzimuth(mPixmap.rect().center(), newState.azimuth()); + repaint(); +} + +void QGVWidgetCompass::paintEvent(QPaintEvent* /*event*/) +{ + if (mPixmap.isNull()) { + return; + } + QPainter painter(this); + if (mTracking) { + painter.setOpacity(0.5); + } + painter.setTransform(mTransfrom); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.drawImage(QRect(0, 0, width(), height()), mPixmap.toImage(), mPixmap.rect()); +} + +void QGVWidgetCompass::mouseMoveEvent(QMouseEvent* event) +{ + if (mTracking) { + const double azimuth = mouseToAzimuth(event->pos(), -mOffset); + getMap()->cameraTo(QGVCameraActions(getMap()).rotateTo(azimuth)); + } +} + +void QGVWidgetCompass::mousePressEvent(QMouseEvent* event) +{ + const double azimuth = getMap()->getCamera().azimuth(); + mOffset = mouseToAzimuth(event->pos(), -azimuth); + mTracking = true; + repaint(); +} + +void QGVWidgetCompass::mouseReleaseEvent(QMouseEvent* /*event*/) +{ + mTracking = false; + repaint(); +} + +void QGVWidgetCompass::mouseDoubleClickEvent(QMouseEvent* /*event*/) +{ + getMap()->cameraTo(QGVCameraActions(getMap()).rotateTo(0)); +} diff --git a/lib/src/QGVWidgetScale.cpp b/lib/src/QGVWidgetScale.cpp index 5624128..8245516 100644 --- a/lib/src/QGVWidgetScale.cpp +++ b/lib/src/QGVWidgetScale.cpp @@ -1,165 +1,165 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVWidgetScale.h" -#include "QGVMapQGView.h" - -#include -#include -#include - -namespace { -const int defaultLengthPixel = 150; -const int minLengthPixel = 130; -} - -QGVWidgetScale::QGVWidgetScale(Qt::Orientation orientation) -{ - mAutoAdjust = true; - mScaleMeters = 0; - mScalePixels = 0; - mOrientation = orientation; - if (mOrientation == Qt::Horizontal) { - setAnchor(QPoint(10, 10), QSet() << Qt::RightEdge << Qt::BottomEdge); - } else { - setAnchor(QPoint(10, 15 + fontMetrics().height()), QSet() << Qt::RightEdge << Qt::BottomEdge); - } - - setAttribute(Qt::WA_TransparentForMouseEvents, true); - setVisible(false); -} - -void QGVWidgetScale::setAutoAdjust(bool autoAdjust) -{ - mAutoAdjust = autoAdjust; - if (getMap() == nullptr) { - setVisible(false); - return; - } - const QGVCameraState camState = getMap()->getCamera(); - onCamera(camState, camState); -} - -bool QGVWidgetScale::getAutoAdjust() const -{ - return mAutoAdjust; -} - -void QGVWidgetScale::setOrientation(Qt::Orientation orientation) -{ - mOrientation = orientation; - if (getMap() == nullptr) { - return; - } - const QGVCameraState camState = getMap()->getCamera(); - onCamera(camState, camState); -} - -Qt::Orientation QGVWidgetScale::getOrientation() const -{ - return mOrientation; -} - -QString QGVWidgetScale::getDistanceLabel(int meters, int accuracy) const -{ - if (meters > 1000) { - return tr("%1 km").arg(QString::number(static_cast(meters) / 1000, 'f', accuracy)); - } else { - return tr("%1 m").arg(QString::number(static_cast(meters), 'f', accuracy)); - } -} - -void QGVWidgetScale::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) -{ - QGVWidget::onCamera(oldState, newState); - const QPoint viewPoint1 = geometry().topLeft(); - QPoint viewPoint2; - if (mOrientation == Qt::Horizontal) { - viewPoint2 = QPoint(viewPoint1.x() + defaultLengthPixel, viewPoint1.y()); - } else { - viewPoint2 = QPoint(viewPoint1.x(), viewPoint1.y() + defaultLengthPixel); - } - - const QPointF projPoint1 = getMap()->mapToProj(viewPoint1); - const QPointF projPoint2 = getMap()->mapToProj(viewPoint2); - const QGVProjection* projection = getMap()->getProjection(); - if (!projection->boundaryProjRect().contains(projPoint1) || !projection->boundaryProjRect().contains(projPoint2)) { - resize(QSize(0, 0)); - repaint(); - return; - } - - int newLengthPixels = defaultLengthPixel; - int newLengthMeters = static_cast(projection->geodesicMeters(projPoint1, projPoint2)); - if (mAutoAdjust) { - const double metersLog = qMax(1.0, log10(newLengthMeters)); - const int meters10 = static_cast(qPow(10, qFloor(metersLog))); - const double correction = static_cast(meters10) / newLengthMeters; - newLengthMeters = meters10; - newLengthPixels = qCeil(correction * newLengthPixels); - if (newLengthPixels < minLengthPixel) { - const double factor = qPow(2, qCeil(log(minLengthPixel / newLengthPixels) * M_LOG2E)); - newLengthMeters *= factor; - newLengthPixels *= factor; - } - } - - if (mScaleMeters != newLengthMeters || mScalePixels != newLengthPixels) { - const int height = fontMetrics().boundingRect("W").height() + 5; - mScaleMeters = newLengthMeters; - mScalePixels = newLengthPixels; - if (mOrientation == Qt::Horizontal) { - resize(QSize(mScalePixels, height)); - } else { - resize(QSize(height, mScalePixels)); - } - repaint(); - } -} - -void QGVWidgetScale::paintEvent(QPaintEvent* /*event*/) -{ - if (size().isEmpty()) { - return; - } - QRect paintRect; - if (mOrientation == Qt::Horizontal) { - paintRect = QRect(QPoint(0, 0), size()); - } else { - paintRect = QRect(QPoint(0, 0), QSize(size().height(), size().width())); - } - paintRect.moveCenter(rect().center()); - - QPainter painter(this); - if (mOrientation != Qt::Horizontal) { - painter.setTransform(QGV::createTransfromAzimuth(rect().center(), -90.0)); - } - - const int lnWidth = 2; - QRect lineRect = paintRect; - lineRect.adjust(lnWidth, lnWidth + lineRect.height() / 2, -lnWidth, -lnWidth); - painter.setPen(QPen(QBrush(Qt::black), lnWidth)); - painter.drawLine(QLine(QPoint(lineRect.left(), lineRect.bottom()), QPoint(lineRect.right(), lineRect.bottom()))); - painter.drawLine(QLine(QPoint(lineRect.left(), lineRect.bottom()), QPoint(lineRect.left(), lineRect.top()))); - painter.drawLine(QLine(QPoint(lineRect.right(), lineRect.bottom()), QPoint(lineRect.right(), lineRect.top()))); - - QRect textRect = paintRect; - textRect.moveCenter(paintRect.center()); - painter.setPen(QPen()); - painter.drawText(textRect, Qt::AlignCenter, getDistanceLabel(mScaleMeters)); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVWidgetScale.h" +#include "QGVMapQGView.h" + +#include +#include +#include + +namespace { +const int defaultLengthPixel = 150; +const int minLengthPixel = 130; +} + +QGVWidgetScale::QGVWidgetScale(Qt::Orientation orientation) +{ + mAutoAdjust = true; + mScaleMeters = 0; + mScalePixels = 0; + mOrientation = orientation; + if (mOrientation == Qt::Horizontal) { + setAnchor(QPoint(10, 10), QSet() << Qt::RightEdge << Qt::BottomEdge); + } else { + setAnchor(QPoint(10, 15 + fontMetrics().height()), QSet() << Qt::RightEdge << Qt::BottomEdge); + } + + setAttribute(Qt::WA_TransparentForMouseEvents, true); + setVisible(false); +} + +void QGVWidgetScale::setAutoAdjust(bool autoAdjust) +{ + mAutoAdjust = autoAdjust; + if (getMap() == nullptr) { + setVisible(false); + return; + } + const QGVCameraState camState = getMap()->getCamera(); + onCamera(camState, camState); +} + +bool QGVWidgetScale::getAutoAdjust() const +{ + return mAutoAdjust; +} + +void QGVWidgetScale::setOrientation(Qt::Orientation orientation) +{ + mOrientation = orientation; + if (getMap() == nullptr) { + return; + } + const QGVCameraState camState = getMap()->getCamera(); + onCamera(camState, camState); +} + +Qt::Orientation QGVWidgetScale::getOrientation() const +{ + return mOrientation; +} + +QString QGVWidgetScale::getDistanceLabel(int meters, int accuracy) const +{ + if (meters > 1000) { + return tr("%1 km").arg(QString::number(static_cast(meters) / 1000, 'f', accuracy)); + } else { + return tr("%1 m").arg(QString::number(static_cast(meters), 'f', accuracy)); + } +} + +void QGVWidgetScale::onCamera(const QGVCameraState& oldState, const QGVCameraState& newState) +{ + QGVWidget::onCamera(oldState, newState); + const QPoint viewPoint1 = geometry().topLeft(); + QPoint viewPoint2; + if (mOrientation == Qt::Horizontal) { + viewPoint2 = QPoint(viewPoint1.x() + defaultLengthPixel, viewPoint1.y()); + } else { + viewPoint2 = QPoint(viewPoint1.x(), viewPoint1.y() + defaultLengthPixel); + } + + const QPointF projPoint1 = getMap()->mapToProj(viewPoint1); + const QPointF projPoint2 = getMap()->mapToProj(viewPoint2); + const QGVProjection* projection = getMap()->getProjection(); + if (!projection->boundaryProjRect().contains(projPoint1) || !projection->boundaryProjRect().contains(projPoint2)) { + resize(QSize(0, 0)); + repaint(); + return; + } + + int newLengthPixels = defaultLengthPixel; + int newLengthMeters = static_cast(projection->geodesicMeters(projPoint1, projPoint2)); + if (mAutoAdjust) { + const double metersLog = qMax(1.0, log10(newLengthMeters)); + const int meters10 = static_cast(qPow(10, qFloor(metersLog))); + const double correction = static_cast(meters10) / newLengthMeters; + newLengthMeters = meters10; + newLengthPixels = qCeil(correction * newLengthPixels); + if (newLengthPixels < minLengthPixel) { + const double factor = qPow(2, qCeil(log(minLengthPixel / newLengthPixels) * M_LOG2E)); + newLengthMeters *= factor; + newLengthPixels *= factor; + } + } + + if (mScaleMeters != newLengthMeters || mScalePixels != newLengthPixels) { + const int height = fontMetrics().boundingRect("W").height() + 5; + mScaleMeters = newLengthMeters; + mScalePixels = newLengthPixels; + if (mOrientation == Qt::Horizontal) { + resize(QSize(mScalePixels, height)); + } else { + resize(QSize(height, mScalePixels)); + } + repaint(); + } +} + +void QGVWidgetScale::paintEvent(QPaintEvent* /*event*/) +{ + if (size().isEmpty()) { + return; + } + QRect paintRect; + if (mOrientation == Qt::Horizontal) { + paintRect = QRect(QPoint(0, 0), size()); + } else { + paintRect = QRect(QPoint(0, 0), QSize(size().height(), size().width())); + } + paintRect.moveCenter(rect().center()); + + QPainter painter(this); + if (mOrientation != Qt::Horizontal) { + painter.setTransform(QGV::createTransfromAzimuth(rect().center(), -90.0)); + } + + const int lnWidth = 2; + QRect lineRect = paintRect; + lineRect.adjust(lnWidth, lnWidth + lineRect.height() / 2, -lnWidth, -lnWidth); + painter.setPen(QPen(QBrush(Qt::black), lnWidth)); + painter.drawLine(QLine(QPoint(lineRect.left(), lineRect.bottom()), QPoint(lineRect.right(), lineRect.bottom()))); + painter.drawLine(QLine(QPoint(lineRect.left(), lineRect.bottom()), QPoint(lineRect.left(), lineRect.top()))); + painter.drawLine(QLine(QPoint(lineRect.right(), lineRect.bottom()), QPoint(lineRect.right(), lineRect.top()))); + + QRect textRect = paintRect; + textRect.moveCenter(paintRect.center()); + painter.setPen(QPen()); + painter.drawText(textRect, Qt::AlignCenter, getDistanceLabel(mScaleMeters)); +} diff --git a/lib/src/QGVWidgetText.cpp b/lib/src/QGVWidgetText.cpp index 4718952..dea5318 100644 --- a/lib/src/QGVWidgetText.cpp +++ b/lib/src/QGVWidgetText.cpp @@ -1,49 +1,49 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVWidgetText.h" - -#include - -QGVWidgetText::QGVWidgetText() -{ - mLabel.reset(new QLabel()); - mLabel->setText(""); - setAttribute(Qt::WA_TransparentForMouseEvents, true); - setAnchor(QPoint(10, 10), { Qt::LeftEdge, Qt::BottomEdge }); - setLayout(new QHBoxLayout(this)); - layout()->setSpacing(0); - layout()->setSizeConstraint(QLayout::SetMinimumSize); - layout()->setContentsMargins(0, 0, 0, 0); - layout()->addWidget(mLabel.data()); -} - -QLabel* QGVWidgetText::label() -{ - return mLabel.data(); -} - -void QGVWidgetText::setText(const QString& text) -{ - mLabel->setText(text); -} - -QString QGVWidgetText::getText() const -{ - return mLabel->text(); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVWidgetText.h" + +#include + +QGVWidgetText::QGVWidgetText() +{ + mLabel.reset(new QLabel()); + mLabel->setText(""); + setAttribute(Qt::WA_TransparentForMouseEvents, true); + setAnchor(QPoint(10, 10), { Qt::LeftEdge, Qt::BottomEdge }); + setLayout(new QHBoxLayout(this)); + layout()->setSpacing(0); + layout()->setSizeConstraint(QLayout::SetMinimumSize); + layout()->setContentsMargins(0, 0, 0, 0); + layout()->addWidget(mLabel.data()); +} + +QLabel* QGVWidgetText::label() +{ + return mLabel.data(); +} + +void QGVWidgetText::setText(const QString& text) +{ + mLabel->setText(text); +} + +QString QGVWidgetText::getText() const +{ + return mLabel->text(); +} diff --git a/lib/src/QGVWidgetZoom.cpp b/lib/src/QGVWidgetZoom.cpp index 53bff05..7036500 100644 --- a/lib/src/QGVWidgetZoom.cpp +++ b/lib/src/QGVWidgetZoom.cpp @@ -1,112 +1,112 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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 "QGVWidgetZoom.h" - -#include -#include -#include -#include -#include -#include - -namespace { -QSize iconSize = QSize(24, 24); -double zoomExponentDown = qPow(2, 1.0 / 5.0); -double zoomExponentUp = 1.0 / qPow(2, 1.0 / 5.0); -} - -QGVWidgetZoom::QGVWidgetZoom() -{ - mButtonPlus.reset(new QToolButton()); - mButtonPlus->setAutoRepeat(true); - mButtonPlus->setIconSize(iconSize); - mButtonPlus->setToolButtonStyle(Qt::ToolButtonIconOnly); - mButtonPlus->setIcon(QIcon(createPixmap(iconSize * 0.75, "+"))); - connect(mButtonPlus.data(), &QToolButton::clicked, this, &QGVWidgetZoom::zoomPlus); - - mButtonMinus.reset(new QToolButton()); - mButtonMinus->setAutoRepeat(true); - mButtonMinus->setIconSize(iconSize); - mButtonMinus->setToolButtonStyle(Qt::ToolButtonIconOnly); - mButtonMinus->setIcon(QIcon(createPixmap(iconSize * 0.75, "-"))); - connect(mButtonMinus.data(), &QToolButton::clicked, this, &QGVWidgetZoom::zoomMinus); - - setOrientation(Qt::Vertical); - setAnchor(QPoint(10, 0), { Qt::LeftEdge }); -} - -void QGVWidgetZoom::setOrientation(Qt::Orientation orientation) -{ - if (layout() != nullptr) { - delete layout(); - } - mOrientation = orientation; - if (mOrientation == Qt::Horizontal) { - setLayout(new QHBoxLayout(this)); - } else { - setLayout(new QVBoxLayout(this)); - } - layout()->setSpacing(0); - layout()->setSizeConstraint(QLayout::SetMinimumSize); - layout()->setContentsMargins(0, 0, 0, 0); - layout()->addWidget(mButtonPlus.data()); - layout()->addWidget(mButtonMinus.data()); -} - -Qt::Orientation QGVWidgetZoom::getOrientation() const -{ - return mOrientation; -} - -QToolButton* QGVWidgetZoom::plus() -{ - return mButtonPlus.data(); -} - -QToolButton* QGVWidgetZoom::minus() -{ - return mButtonMinus.data(); -} - -QPixmap QGVWidgetZoom::createPixmap(const QSize& size, const QString& text) -{ - QImage image(size, QImage::Format_ARGB32_Premultiplied); - image.fill(qRgba(0, 0, 0, 0)); - QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); - QPainter painter(&pixmap); - QPen pen = QPen(Qt::black); - pen.setWidth(1); - pen.setCosmetic(true); - painter.setPen(pen); - QBrush brush = QBrush(Qt::blue); - painter.setBrush(brush); - const auto path = QGV::createTextPath(QRect(QPoint(0, 0), size), text, font(), pen.width()); - painter.drawPath(path); - return pixmap; -} - -void QGVWidgetZoom::zoomPlus() -{ - getMap()->cameraTo(QGVCameraActions(getMap()).scaleBy(zoomExponentDown)); -} - -void QGVWidgetZoom::zoomMinus() -{ - getMap()->cameraTo(QGVCameraActions(getMap()).scaleBy(zoomExponentUp)); -} +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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 "QGVWidgetZoom.h" + +#include +#include +#include +#include +#include +#include + +namespace { +QSize iconSize = QSize(24, 24); +double zoomExponentDown = qPow(2, 1.0 / 5.0); +double zoomExponentUp = 1.0 / qPow(2, 1.0 / 5.0); +} + +QGVWidgetZoom::QGVWidgetZoom() +{ + mButtonPlus.reset(new QToolButton()); + mButtonPlus->setAutoRepeat(true); + mButtonPlus->setIconSize(iconSize); + mButtonPlus->setToolButtonStyle(Qt::ToolButtonIconOnly); + mButtonPlus->setIcon(QIcon(createPixmap(iconSize * 0.75, "+"))); + connect(mButtonPlus.data(), &QToolButton::clicked, this, &QGVWidgetZoom::zoomPlus); + + mButtonMinus.reset(new QToolButton()); + mButtonMinus->setAutoRepeat(true); + mButtonMinus->setIconSize(iconSize); + mButtonMinus->setToolButtonStyle(Qt::ToolButtonIconOnly); + mButtonMinus->setIcon(QIcon(createPixmap(iconSize * 0.75, "-"))); + connect(mButtonMinus.data(), &QToolButton::clicked, this, &QGVWidgetZoom::zoomMinus); + + setOrientation(Qt::Vertical); + setAnchor(QPoint(10, 0), { Qt::LeftEdge }); +} + +void QGVWidgetZoom::setOrientation(Qt::Orientation orientation) +{ + if (layout() != nullptr) { + delete layout(); + } + mOrientation = orientation; + if (mOrientation == Qt::Horizontal) { + setLayout(new QHBoxLayout(this)); + } else { + setLayout(new QVBoxLayout(this)); + } + layout()->setSpacing(0); + layout()->setSizeConstraint(QLayout::SetMinimumSize); + layout()->setContentsMargins(0, 0, 0, 0); + layout()->addWidget(mButtonPlus.data()); + layout()->addWidget(mButtonMinus.data()); +} + +Qt::Orientation QGVWidgetZoom::getOrientation() const +{ + return mOrientation; +} + +QToolButton* QGVWidgetZoom::plus() +{ + return mButtonPlus.data(); +} + +QToolButton* QGVWidgetZoom::minus() +{ + return mButtonMinus.data(); +} + +QPixmap QGVWidgetZoom::createPixmap(const QSize& size, const QString& text) +{ + QImage image(size, QImage::Format_ARGB32_Premultiplied); + image.fill(qRgba(0, 0, 0, 0)); + QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); + QPainter painter(&pixmap); + QPen pen = QPen(Qt::black); + pen.setWidth(1); + pen.setCosmetic(true); + painter.setPen(pen); + QBrush brush = QBrush(Qt::blue); + painter.setBrush(brush); + const auto path = QGV::createTextPath(QRect(QPoint(0, 0), size), text, font(), pen.width()); + painter.drawPath(path); + return pixmap; +} + +void QGVWidgetZoom::zoomPlus() +{ + getMap()->cameraTo(QGVCameraActions(getMap()).scaleBy(zoomExponentDown)); +} + +void QGVWidgetZoom::zoomMinus() +{ + getMap()->cameraTo(QGVCameraActions(getMap()).scaleBy(zoomExponentUp)); +} diff --git a/scripts/add_header.py b/scripts/add_header.py old mode 100644 new mode 100755 index e9c13a0..0682bd1 --- a/scripts/add_header.py +++ b/scripts/add_header.py @@ -1,12 +1,26 @@ +#!/usr/bin/env python3 + import sys import argparse import os import re -target_head = b'' +line_ending= b'\n' + +def read_file(file_path): + print("read file %s" % file_path) + fw = open(file_path, 'rb') + return fw.read() + +def write_file(file_path, body): + fw = open(file_path, 'wb') + fw.write(body) + print("update file %s" % file_path) -def replace(file_path): - global target_head +def compare_body(origin_body, target_body): + return origin_body == target_body + +def replace(file_path, target_head): head_start = False head_end = False first_line = False @@ -24,7 +38,7 @@ def replace(file_path): head_end = True # Detect end line in head if head_start and not head_end: - head_end = re.match(r'^\s+\*\*\*+\/', lineStr) + head_end = re.match(r'^\s*\*\*\*+\/', lineStr) continue # Wait first line in body if not first_line: @@ -34,41 +48,37 @@ def replace(file_path): # Add line by line body += lineBin # Output with head and body - output = target_head + b'\r\n' + body - # CRLF in text - output = output.replace(b'\r\n', b'\n') - output = output.replace(b'\n', b'\r\n') - # Write file - fw = open(file_path, 'wb') - fw.write(output) - print("replaced") - -def load_target_head(file_path): - global target_head - fr = open(file_path, 'rb') - target_head = fr.read() - # CRLF in text - target_head = target_head.replace(b'\r\n', b'\n') - target_head = target_head.replace(b'\n', b'\r\n') + output = target_head + line_ending + body + return output -def replace_in_path(path): - print(path) +def replace_in_path(path, head_file, apply_needed): + result = 0 + target_head = read_file(head_file) + print("search files in %s" % path) for root, dirs, files in os.walk(path): for file in files: if (file.endswith('.h') or file.endswith('.cpp')) and \ not file.startswith('moc') and \ not 'build/' in root : - fullname = root + "/" + file - print(fullname) - replace(fullname) + file_path = root + "/" + file + origin_body = read_file(file_path) + target_body = replace(file_path, target_head) + if not compare_body(origin_body, target_body): + print("HEAD DIFFER IN %s" % file_path) + result = 1 + if apply_needed: + write_file(file_path, target_body) + return result def main(): parser = argparse.ArgumentParser() parser.add_argument("path", help="path to project") - parser.add_argument("head", help="path to head file") + parser.add_argument("head_file", help="path to head file") + parser.add_argument('--apply', action='store_true') args = parser.parse_args() - load_target_head(args.head) - replace_in_path(args.path) + print("Replace in '%s' Target head file '%s'" % (args.path, args.head_file)) + print(args) + return replace_in_path(args.path, args.head_file, args.apply) if __name__ == "__main__": sys.exit(main()) diff --git a/scripts/clang_format.py b/scripts/clang_format.py deleted file mode 100644 index 3f4a0a1..0000000 --- a/scripts/clang_format.py +++ /dev/null @@ -1,32 +0,0 @@ -import sys -import argparse -import os -import subprocess - -project_path='.' - -def clang_format(file_path): - global project_path - subprocess.call(['clang-format', '-i', file_path], cwd = project_path) - print("formated") - -def format_in_path(path): - print(path) - for root, dirs, files in os.walk(path): - for file in files: - if (file.endswith('.h') or file.endswith('.cpp')) and \ - not file.startswith('moc') and \ - not 'build/' in root : - fullname = root + "/" + file - print(fullname) - clang_format(fullname) - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("path", help="path to project") - args = parser.parse_args() - project_path = args.path - format_in_path(project_path) - -if __name__ == "__main__": - sys.exit(main()) diff --git a/scripts/qgv_lgpl_head.txt b/scripts/legacy_head.txt similarity index 93% rename from scripts/qgv_lgpl_head.txt rename to scripts/legacy_head.txt index 3ac52ac..fb96d65 100644 --- a/scripts/qgv_lgpl_head.txt +++ b/scripts/legacy_head.txt @@ -1,17 +1,17 @@ -/*************************************************************************** - * QGeoView is a Qt / C ++ widget for visualizing geographic data. - * Copyright (C) 2018-2019 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. - ****************************************************************************/ +/*************************************************************************** + * QGeoView is a Qt / C ++ widget for visualizing geographic data. + * Copyright (C) 2018-2020 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. + ****************************************************************************/