add Map inverse geocoding
add minimum/maximum to ScrollSpinBox
This commit is contained in:
@@ -72,7 +72,7 @@ set(__deps_application "QAD::Widgets")
|
|||||||
set(__deps_blockview "QAD::Widgets")
|
set(__deps_blockview "QAD::Widgets")
|
||||||
set(__deps_graphic "QAD::Widgets")
|
set(__deps_graphic "QAD::Widgets")
|
||||||
set(__deps_sql_table "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 "QAD::Widgets;PIP")
|
||||||
set(__deps_piqt_utils "QAD::Blockview;QAD::PIQt")
|
set(__deps_piqt_utils "QAD::Blockview;QAD::PIQt")
|
||||||
|
|
||||||
|
|||||||
92
libs/map/osm_geocoding.cpp
Normal file
92
libs/map/osm_geocoding.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "osm_geocoding.h"
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
84
libs/map/osm_geocoding.h
Normal file
84
libs/map/osm_geocoding.h
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef osm_geocoding_h
|
||||||
|
#define osm_geocoding_h
|
||||||
|
|
||||||
|
#include "qad_map_export.h"
|
||||||
|
|
||||||
|
#include <QGeoCoordinate>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QPointF>
|
||||||
|
|
||||||
|
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
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pivariant_geoposition.h"
|
#include "pivariant_geoposition.h"
|
||||||
|
|
||||||
#include "mapitemimage.h"
|
#include "mapitemimage.h"
|
||||||
|
#include "osm_geocoding.h"
|
||||||
#include "piqt.h"
|
#include "piqt.h"
|
||||||
#include "pivaluetree.h"
|
#include "pivaluetree.h"
|
||||||
#include "ui_pivariant_geoposition.h"
|
#include "ui_pivariant_geoposition.h"
|
||||||
@@ -31,7 +32,18 @@ PIVariantEditors::GeoPosition::GeoPosition() {
|
|||||||
item->setScale(0.333 * appScale(this));
|
item->setScale(0.333 * appScale(this));
|
||||||
item->setPosition(ui.map->center());
|
item->setPosition(ui.map->center());
|
||||||
ui.map->addItem(item);
|
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;
|
if (dlg.exec() != QDialog::Accepted) return;
|
||||||
PIGeoPosition gp({item->position().x(), item->position().y(), 0.}, PIGeoPosition::Geodetic);
|
PIGeoPosition gp({item->position().x(), item->position().y(), 0.}, PIGeoPosition::Geodetic);
|
||||||
setValue(PIVariant::fromValue(gp));
|
setValue(PIVariant::fromValue(gp));
|
||||||
|
|||||||
@@ -16,11 +16,27 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="MapView" name="map">
|
<widget class="MapView" name="map">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="zoom">
|
<property name="zoom">
|
||||||
<double>15.000000000000000</double>
|
<double>15.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>-</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
|
|||||||
@@ -138,6 +138,13 @@ PIVariantMap PIVariantEditors::NumberBase::attributes() const {
|
|||||||
ret[Attribute::expression] = Q2PIString(w->expression());
|
ret[Attribute::expression] = Q2PIString(w->expression());
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case tScrollSpinBox: {
|
||||||
|
auto * w = qobject_cast<ScrollSpinBox *>(widget);
|
||||||
|
if (w) {
|
||||||
|
ret[Attribute::minimum] = w->minimum();
|
||||||
|
ret[Attribute::maximum] = w->maximum();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -247,6 +254,8 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
|
|||||||
case tScrollSpinBox: {
|
case tScrollSpinBox: {
|
||||||
auto * w = qobject_cast<ScrollSpinBox *>(widget);
|
auto * w = qobject_cast<ScrollSpinBox *>(widget);
|
||||||
if (!w) return;
|
if (!w) return;
|
||||||
|
w->setMinimum(min);
|
||||||
|
w->setMaximum(max);
|
||||||
} break;
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ ScrollSpinBox::ScrollSpinBox(QWidget * parent): QWidget(parent) {
|
|||||||
connect(ui->spin, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double)));
|
connect(ui->spin, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double)));
|
||||||
last_value = 0.;
|
last_value = 0.;
|
||||||
sensivity_ = 0.2;
|
sensivity_ = 0.2;
|
||||||
|
m_maximum = 2147483647;
|
||||||
|
m_minimum = -m_maximum;
|
||||||
scroll_scale = sensivity_ / 10;
|
scroll_scale = sensivity_ / 10;
|
||||||
canceled = false;
|
canceled = false;
|
||||||
}
|
}
|
||||||
@@ -108,12 +110,24 @@ void ScrollSpinBox::mouseMove(QMouseEvent * e) {
|
|||||||
double dv = (down_pos.y() - e->pos().y()) * scroll_scale;
|
double dv = (down_pos.y() - e->pos().y()) * scroll_scale;
|
||||||
if (dv != 0.) {
|
if (dv != 0.) {
|
||||||
QCursor::setPos(ui->handle->mapToGlobal(down_pos));
|
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) {
|
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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ class QAD_WIDGETS_EXPORT ScrollSpinBox: public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(double sensivity READ sensivity WRITE setSensivity)
|
Q_PROPERTY(double sensivity READ sensivity WRITE setSensivity)
|
||||||
Q_PROPERTY(double value READ value WRITE setValue)
|
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:
|
public:
|
||||||
explicit ScrollSpinBox(QWidget * parent = 0);
|
explicit ScrollSpinBox(QWidget * parent = 0);
|
||||||
@@ -44,6 +46,8 @@ public:
|
|||||||
EvalSpinBox * spin();
|
EvalSpinBox * spin();
|
||||||
double value() const;
|
double value() const;
|
||||||
double sensivity() const { return sensivity_; }
|
double sensivity() const { return sensivity_; }
|
||||||
|
int minimum() const { return m_minimum; }
|
||||||
|
int maximum() const { return m_maximum; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent(QEvent * e);
|
void changeEvent(QEvent * e);
|
||||||
@@ -57,11 +61,14 @@ protected:
|
|||||||
QPoint down_pos;
|
QPoint down_pos;
|
||||||
QString last_text;
|
QString last_text;
|
||||||
double last_value, scroll_scale, sensivity_;
|
double last_value, scroll_scale, sensivity_;
|
||||||
|
double m_minimum, m_maximum;
|
||||||
bool canceled;
|
bool canceled;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setSensivity(double s) { sensivity_ = s; }
|
void setSensivity(double s) { sensivity_ = s; }
|
||||||
void setValue(double v);
|
void setValue(double v);
|
||||||
|
void setMinimum(int minimum);
|
||||||
|
void setMaximum(int maximum);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void valueChanged(double);
|
void valueChanged(double);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "pivariant.h"
|
|
||||||
#include "qad_locations.h"
|
#include "qad_locations.h"
|
||||||
#include "qad_types.h"
|
#include "qad_types.h"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user