From 3c29b7b5665eea303e02861ae5ab73460a578c2c Mon Sep 17 00:00:00 2001 From: peri4 Date: Sun, 5 Feb 2023 21:24:30 +0300 Subject: [PATCH] add Map inverse geocoding add minimum/maximum to ScrollSpinBox --- cmake/FindQAD.cmake | 2 +- libs/map/osm_geocoding.cpp | 92 +++++++++++++++++++ libs/map/osm_geocoding.h | 84 +++++++++++++++++ libs/map/pivariant_geoposition.cpp | 14 ++- libs/map/pivariant_geoposition_map.ui | 16 ++++ libs/piqt_utils/pivariant_edit_widgets.cpp | 9 ++ libs/widgets/scroll_spin_box.cpp | 18 +++- libs/widgets/scroll_spin_box.h | 7 ++ .../valuetreeeditor/valuetreeeditor_main.cpp | 1 - 9 files changed, 238 insertions(+), 5 deletions(-) create mode 100644 libs/map/osm_geocoding.cpp create mode 100644 libs/map/osm_geocoding.h diff --git a/cmake/FindQAD.cmake b/cmake/FindQAD.cmake index 5442951..6ba8129 100644 --- a/cmake/FindQAD.cmake +++ b/cmake/FindQAD.cmake @@ -72,7 +72,7 @@ set(__deps_application "QAD::Widgets") set(__deps_blockview "QAD::Widgets") set(__deps_graphic "QAD::Widgets") set(__deps_sql_table "QAD::Widgets") -set(__deps_map "QAD::Utils") +set(__deps_map "QAD::Utils;QAD::PIQt") set(__deps_piqt "QAD::Widgets;PIP") set(__deps_piqt_utils "QAD::Blockview;QAD::PIQt") diff --git a/libs/map/osm_geocoding.cpp b/libs/map/osm_geocoding.cpp new file mode 100644 index 0000000..40977c4 --- /dev/null +++ b/libs/map/osm_geocoding.cpp @@ -0,0 +1,92 @@ +#include "osm_geocoding.h" + +#include +#include +#include +#include +#include +#include + + +OSMGeocodingResult::OSMGeocodingResult(QObject * parent): QObject(parent) {} + + +OSMGeocodingResult::~OSMGeocodingResult() {} + + +void OSMGeocodingResult::abort() { + if (reply) { + reply->abort(); + reply->deleteLater(); + blockSignals(true); + deleteLater(); + reply = nullptr; + } +} + + +QString OSMGeocodingResult::displayName() const { + return res.object().value("display_name").toString(); +} + + +QPointF OSMGeocodingResult::resultCoordinate() const { + auto loc_c = QLocale::c(); + return QPointF(loc_c.toDouble(res.object().value("lat").toString()), loc_c.toDouble(res.object().value("lng").toString())); +} + + +void OSMGeocodingResult::requestDone() { + emit ready(); + deleteLater(); +} + + +// OSMGeocoding + +OSMGeocoding::OSMGeocoding(): QObject() { + nam = new QNetworkAccessManager(); + provider = "https://nominatim.openstreetmap.org"; + // https://nominatim.openstreetmap.org/reverse?lat=52.79870&lon=27.56572&format=json +} + + +OSMGeocoding::~OSMGeocoding() { + delete nam; +} + + +OSMGeocoding * OSMGeocoding::instance() { + static OSMGeocoding ret; + return &ret; +} + + +OSMGeocodingResult * OSMGeocoding::queue(QPointF coord) { + return instance()->reverseCoding(coord); +} + + +OSMGeocodingResult * OSMGeocoding::reverseCoding(QPointF coord) { + auto loc_c = QLocale::c(); + QNetworkRequest req( + provider + + QString("/reverse?lat=%1&lon=%2&format=json").arg(loc_c.toString(coord.x(), 'f', 8)).arg(loc_c.toString(coord.y(), 'f', 8))); + req.setHeader(QNetworkRequest::UserAgentHeader, "Qt/5"); + req.setRawHeader("Accept-Language", (QLocale().name() + "," + QLocale().bcp47Name()).toLatin1()); + auto * r = nam->get(req); + if (!r) return nullptr; + OSMGeocodingResult * ret = new OSMGeocodingResult(nam); + ret->reply = r; + connect(r, &QNetworkReply::finished, this, [r, ret]() { + r->deleteLater(); + if (r->error() != QNetworkReply::NoError) { + qDebug() << "Error:" << r->error(); + } else { + QByteArray data = r->readAll(); + if (!data.isEmpty()) ret->res = QJsonDocument::fromJson(data); + } + ret->requestDone(); + }); + return ret; +} diff --git a/libs/map/osm_geocoding.h b/libs/map/osm_geocoding.h new file mode 100644 index 0000000..208c35a --- /dev/null +++ b/libs/map/osm_geocoding.h @@ -0,0 +1,84 @@ +/* + QAD - Qt ADvanced + + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef osm_geocoding_h +#define osm_geocoding_h + +#include "qad_map_export.h" + +#include +#include +#include + +class QNetworkReply; +class QNetworkAccessManager; + + +class QAD_MAP_EXPORT OSMGeocodingResult: public QObject { + Q_OBJECT + friend class OSMGeocoding; + +public: + void abort(); + + bool isEmpty() const { return res.isEmpty(); } + QJsonDocument result() const { return res; } + QString displayName() const; + QPointF resultCoordinate() const; + +private: + OSMGeocodingResult(QObject * parent); + ~OSMGeocodingResult(); + + void requestDone(); + QJsonDocument res; + QNetworkReply * reply = nullptr; + +signals: + void ready(); +}; + + +class QAD_MAP_EXPORT OSMGeocoding: public QObject { + Q_OBJECT + +public: + static OSMGeocodingResult * queue(QPointF coord); + static OSMGeocodingResult * queue(QGeoCoordinate coord) { return queue(QPointF(coord.latitude(), coord.longitude())); } + +private: + explicit OSMGeocoding(); + ~OSMGeocoding(); + + static OSMGeocoding * instance(); + + OSMGeocodingResult * reverseCoding(QPointF coord); + + QNetworkAccessManager * nam = nullptr; + QString provider; + +public slots: + +private slots: + +signals: +}; + + +#endif diff --git a/libs/map/pivariant_geoposition.cpp b/libs/map/pivariant_geoposition.cpp index 90e9597..5c23f6b 100644 --- a/libs/map/pivariant_geoposition.cpp +++ b/libs/map/pivariant_geoposition.cpp @@ -1,6 +1,7 @@ #include "pivariant_geoposition.h" #include "mapitemimage.h" +#include "osm_geocoding.h" #include "piqt.h" #include "pivaluetree.h" #include "ui_pivariant_geoposition.h" @@ -31,7 +32,18 @@ PIVariantEditors::GeoPosition::GeoPosition() { item->setScale(0.333 * appScale(this)); item->setPosition(ui.map->center()); ui.map->addItem(item); - connect(ui.map, &MapView::mapClicked, this, [item](QPointF c) { item->setPosition(c); }); + OSMGeocodingResult * gc_res = nullptr; + connect(ui.map, &MapView::mapClicked, this, [this, item, &gc_res, ui](QPointF c) { + item->setPosition(c); + if (gc_res) gc_res->abort(); + gc_res = OSMGeocoding::queue(c); + ui.label->setText("-"); + connect(gc_res, &OSMGeocodingResult::ready, this, [&gc_res, ui]() { + ui.label->setText(gc_res->displayName()); + gc_res = nullptr; + }); + }); + ui.map->mapClicked(ui.map->center()); if (dlg.exec() != QDialog::Accepted) return; PIGeoPosition gp({item->position().x(), item->position().y(), 0.}, PIGeoPosition::Geodetic); setValue(PIVariant::fromValue(gp)); diff --git a/libs/map/pivariant_geoposition_map.ui b/libs/map/pivariant_geoposition_map.ui index 72d4218..b5cfad8 100644 --- a/libs/map/pivariant_geoposition_map.ui +++ b/libs/map/pivariant_geoposition_map.ui @@ -16,11 +16,27 @@ + + + 0 + 0 + + 15.000000000000000 + + + + - + + + true + + + diff --git a/libs/piqt_utils/pivariant_edit_widgets.cpp b/libs/piqt_utils/pivariant_edit_widgets.cpp index af096a5..4188e3c 100644 --- a/libs/piqt_utils/pivariant_edit_widgets.cpp +++ b/libs/piqt_utils/pivariant_edit_widgets.cpp @@ -138,6 +138,13 @@ PIVariantMap PIVariantEditors::NumberBase::attributes() const { ret[Attribute::expression] = Q2PIString(w->expression()); } } break; + case tScrollSpinBox: { + auto * w = qobject_cast(widget); + if (w) { + ret[Attribute::minimum] = w->minimum(); + ret[Attribute::maximum] = w->maximum(); + } + } break; default: break; } return ret; @@ -247,6 +254,8 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) { case tScrollSpinBox: { auto * w = qobject_cast(widget); if (!w) return; + w->setMinimum(min); + w->setMaximum(max); } break; default: break; } diff --git a/libs/widgets/scroll_spin_box.cpp b/libs/widgets/scroll_spin_box.cpp index d4cfd04..c42863b 100644 --- a/libs/widgets/scroll_spin_box.cpp +++ b/libs/widgets/scroll_spin_box.cpp @@ -37,6 +37,8 @@ ScrollSpinBox::ScrollSpinBox(QWidget * parent): QWidget(parent) { connect(ui->spin, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double))); last_value = 0.; sensivity_ = 0.2; + m_maximum = 2147483647; + m_minimum = -m_maximum; scroll_scale = sensivity_ / 10; canceled = false; } @@ -108,12 +110,24 @@ void ScrollSpinBox::mouseMove(QMouseEvent * e) { double dv = (down_pos.y() - e->pos().y()) * scroll_scale; if (dv != 0.) { QCursor::setPos(ui->handle->mapToGlobal(down_pos)); - ui->spin->setValue(ui->spin->value() + last_value * dv); + setValue(ui->spin->value() + last_value * dv); } } } void ScrollSpinBox::setValue(double v) { - ui->spin->setValue(v); + ui->spin->setValue(qBound(m_minimum, v, m_maximum)); +} + + +void ScrollSpinBox::setMinimum(int minimum) { + m_minimum = minimum; + setValue(value()); +} + + +void ScrollSpinBox::setMaximum(int maximum) { + m_maximum = maximum; + setValue(value()); } diff --git a/libs/widgets/scroll_spin_box.h b/libs/widgets/scroll_spin_box.h index 13a3d99..13d6275 100644 --- a/libs/widgets/scroll_spin_box.h +++ b/libs/widgets/scroll_spin_box.h @@ -37,6 +37,8 @@ class QAD_WIDGETS_EXPORT ScrollSpinBox: public QWidget { Q_OBJECT Q_PROPERTY(double sensivity READ sensivity WRITE setSensivity) Q_PROPERTY(double value READ value WRITE setValue) + Q_PROPERTY(int minimum READ minimum WRITE setMinimum) + Q_PROPERTY(int maximum READ maximum WRITE setMaximum) public: explicit ScrollSpinBox(QWidget * parent = 0); @@ -44,6 +46,8 @@ public: EvalSpinBox * spin(); double value() const; double sensivity() const { return sensivity_; } + int minimum() const { return m_minimum; } + int maximum() const { return m_maximum; } protected: void changeEvent(QEvent * e); @@ -57,11 +61,14 @@ protected: QPoint down_pos; QString last_text; double last_value, scroll_scale, sensivity_; + double m_minimum, m_maximum; bool canceled; public slots: void setSensivity(double s) { sensivity_ = s; } void setValue(double v); + void setMinimum(int minimum); + void setMaximum(int maximum); signals: void valueChanged(double); diff --git a/utils/valuetreeeditor/valuetreeeditor_main.cpp b/utils/valuetreeeditor/valuetreeeditor_main.cpp index d19caa0..339036c 100644 --- a/utils/valuetreeeditor/valuetreeeditor_main.cpp +++ b/utils/valuetreeeditor/valuetreeeditor_main.cpp @@ -1,5 +1,4 @@ #include "mainwindow.h" -#include "pivariant.h" #include "qad_locations.h" #include "qad_types.h"