[Marble-commits] KDE/kdeedu/marble/src/lib/routing
Dennis Nienhüser
earthwings at gentoo.org
Thu Mar 18 21:39:40 CET 2010
SVN commit 1104896 by nienhueser:
Reverse geocoding via openstreetmap nominatim to show addresses instead of lat/lon pairs in input fields
M +69 -3 RoutingInputWidget.cpp
M +8 -0 RoutingInputWidget.h
--- trunk/KDE/kdeedu/marble/src/lib/routing/RoutingInputWidget.cpp #1104895:1104896
@@ -14,6 +14,8 @@
#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "RouteSkeleton.h"
+#include "TinyWebBrowser.h"
+#include "MarbleLocale.h"
#include <QtCore/QTimer>
#include <QtGui/QLineEdit>
@@ -21,6 +23,10 @@
#include <QtGui/QPushButton>
#include <QtGui/QMovie>
#include <QtGui/QIcon>
+#include <QtXml/QDomDocument>
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkReply>
+#include <QtCore/QUrl>
namespace Marble {
@@ -37,8 +43,6 @@
MarbleRunnerManager *m_runnerManager;
- RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent);
-
MarblePlacemarkModel* m_placemarkModel;
QMovie m_progress;
@@ -48,12 +52,22 @@
RouteSkeleton* m_route;
int m_index;
+
+ QNetworkAccessManager *m_manager;
+
+ QTimer m_nominatimTimer;
+
+ /** Constructor */
+ RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent);
+
+ /** Initiate reverse geocoding request to download address */
+ void adjustText();
};
RoutingInputWidgetPrivate::RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent) :
m_lineEdit(0), m_runnerManager(new MarbleRunnerManager(parent)),
m_placemarkModel(0), m_progress(":/data/bitmaps/progress.mng"),
- m_route(skeleton), m_index(index)
+ m_route(skeleton), m_index(index), m_manager(new QNetworkAccessManager(parent))
{
m_stateButton = new QPushButton(parent);
m_stateButton->setToolTip("Center Map here");
@@ -87,8 +101,15 @@
m_pickButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_progressTimer.setInterval(100);
+ m_nominatimTimer.setInterval(1000);
+ m_nominatimTimer.setSingleShot(true);
}
+void RoutingInputWidgetPrivate::adjustText()
+{
+ m_nominatimTimer.start();
+}
+
RoutingInputWidget::RoutingInputWidget(RouteSkeleton *skeleton, int index, QWidget *parent) :
QWidget(parent), d(new RoutingInputWidgetPrivate(skeleton, index, this))
{
@@ -120,6 +141,8 @@
this, SLOT(finishSearch()));
connect(skeleton, SIGNAL(positionChanged(int, GeoDataCoordinates)),
this, SLOT(updatePosition(int, GeoDataCoordinates)));
+ connect(&d->m_nominatimTimer, SIGNAL(timeout()),
+ this, SLOT(startHttpRequest()));
}
RoutingInputWidget::~RoutingInputWidget()
@@ -127,6 +150,29 @@
delete d;
}
+void RoutingInputWidget::startHttpRequest()
+{
+ if (!hasTargetPosition())
+ return;
+
+ GeoDataCoordinates position = targetPosition();
+ QString base = "http://nominatim.openstreetmap.org/reverse?format=xml&addressdetails=0";
+ // @todo: Alternative URI with addressdetails=1 could be used for shorther placemark name
+ QString query = "&lon=%1&lat=%2&accept-language=%3";
+ double lon = position.longitude(GeoDataCoordinates::Degree);
+ double lat = position.latitude(GeoDataCoordinates::Degree);
+ QString url = QString(base + query).arg(lon).arg(lat).arg(MarbleLocale::languageCode());
+
+ QObject::connect(d->m_manager, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(handleHttpReply(QNetworkReply*)));
+
+ QNetworkRequest request;
+ request.setUrl(QUrl(url));
+ request.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "RoutingInputWidget") );
+
+ d->m_manager->get(QNetworkRequest(request));
+}
+
void RoutingInputWidget::setPlacemarkModel(MarblePlacemarkModel* model)
{
d->m_placemarkModel = model;
@@ -145,6 +191,7 @@
if (!hasTargetPosition()) {
d->m_route->setPosition(d->m_index, position);
emit targetValidityChanged(true);
+ d->adjustText();
}
}
@@ -246,9 +293,28 @@
d->m_stateButton->setEnabled(hasTargetPosition());
d->m_stateButton->setIcon(d->m_route->pixmap(d->m_index));
emit targetValidityChanged(hasTargetPosition());
+ d->adjustText();
}
}
+void RoutingInputWidget::handleHttpReply( QNetworkReply* reply )
+{
+ QDomDocument xml;
+ if (!xml.setContent(reply->readAll())) {
+ qWarning() << "Cannot parse osm nominatim result " << xml.toString();
+ return;
+ }
+
+ QVector<GeoDataPlacemark> placemarks;
+ QDomElement root = xml.documentElement();
+ QDomNodeList places = root.elementsByTagName("result");
+ if (places.size()==1) {
+ QString address = places.item(0).toElement().text();
+ d->m_lineEdit->setText(address);
+ d->m_lineEdit->setCursorPosition(0);
+ }
+}
+
} // namespace Marble
#include "RoutingInputWidget.moc"
--- trunk/KDE/kdeedu/marble/src/lib/routing/RoutingInputWidget.h #1104895:1104896
@@ -15,6 +15,8 @@
#include <QtGui/QWidget>
+class QNetworkReply;
+
namespace Marble {
class RoutingInputWidgetPrivate;
@@ -129,6 +131,12 @@
/** Set the target position (dragging) */
void updatePosition(int index, const GeoDataCoordinates &position);
+ /** Start reverse geocoding request */
+ void startHttpRequest();
+
+ /** Http request with nominatim.openstreetmap.org done */
+ void handleHttpReply( QNetworkReply* );
+
private:
RoutingInputWidgetPrivate* const d;
};
More information about the Marble-commits
mailing list