Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE][locator] Add a nominatim locator filter
  • Loading branch information
nirvn committed Mar 5, 2021
1 parent c6370c7 commit 7eaa5b7
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 9 deletions.
Expand Up @@ -56,7 +56,7 @@ Returns the URL generated for geocoding the specified ``address``.

QgsGeocoderResult jsonToResult( const QVariantMap &json ) const;
%Docstring
Converts a JSON result returned from the Google Maps service to a geocoder result object.
Converts a JSON result returned from the Nominatim service to a geocoder result object.
%End

QString endpoint() const;
Expand Down
30 changes: 30 additions & 0 deletions src/app/locator/qgsinbuiltlocatorfilters.cpp
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/

#include <QDesktopServices>
#include <QClipboard>
#include <QMap>
#include <QSpinBox>
Expand All @@ -33,6 +34,8 @@
#include "qgsfeedback.h"
#include "qgisapp.h"
#include "qgsmaplayermodel.h"
#include "qgsmessagebar.h"
#include "qgsmessagebaritem.h"
#include "qgslayoutmanager.h"
#include "qgsmapcanvas.h"
#include "qgsfeatureaction.h"
Expand Down Expand Up @@ -1189,3 +1192,30 @@ void QgsGotoLocatorFilter::triggerResult( const QgsLocatorResult &result )

mapCanvas->flashGeometries( QList< QgsGeometry >() << QgsGeometry::fromPointXY( point ) );
}

QgsNominatimLocatorFilter::QgsNominatimLocatorFilter( QgsGeocoderInterface *geocoder, QgsMapCanvas *canvas )
: QgsGeocoderLocatorFilter( QStringLiteral( "nominatimgeocoder" ), tr( "Nominatim Geocoder" ), QStringLiteral( "nom" ), geocoder, canvas )
{
setFetchResultsDelay( 1000 );
setUseWithoutPrefix( false );
}

void QgsNominatimLocatorFilter::triggerResult( const QgsLocatorResult &result )
{

QgsSettings settings;
if ( !settings.value( "locator_filters/nominatim_geocoder/attribution_shown", false, QgsSettings::App ).toBool() )
{
settings.setValue( "locator_filters/nominatim_geocoder/attribution_shown", true, QgsSettings::App );

QgsMessageBarItem *messageWidget = QgisApp::instance()->messageBar()->createMessage( tr( "The Nominatim geocoder data is made available by OpenStreetMap Foundation and contributors." ) );
QPushButton *learnMoreButton = new QPushButton( tr( "Learn more" ) );
connect( learnMoreButton, &QPushButton::clicked, learnMoreButton, [ = ]
{
QDesktopServices::openUrl( QStringLiteral( "https://nominatim.org/" ) );
} );
messageWidget->layout()->addWidget( learnMoreButton );
QgisApp::instance()->messageBar()->pushWidget( messageWidget, Qgis::Info );
}
QgsGeocoderLocatorFilter::triggerResult( result );
}
13 changes: 13 additions & 0 deletions src/app/locator/qgsinbuiltlocatorfilters.h
Expand Up @@ -20,6 +20,7 @@

#include "qgis_app.h"
#include "qgslocatorfilter.h"
#include "qgsgeocoderlocatorfilter.h"
#include "qgsexpressioncontext.h"
#include "qgsfeatureiterator.h"
#include "qgsvectorlayerfeatureiterator.h"
Expand Down Expand Up @@ -259,6 +260,18 @@ class APP_EXPORT QgsGotoLocatorFilter : public QgsLocatorFilter

};

class APP_EXPORT QgsNominatimLocatorFilter : public QgsGeocoderLocatorFilter
{
Q_OBJECT

public:

QgsNominatimLocatorFilter( QgsGeocoderInterface *geocoder, QgsMapCanvas *canvas );

void triggerResult( const QgsLocatorResult &result ) override;

};

#endif // QGSINBUILTLOCATORFILTERS_H


5 changes: 5 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -267,6 +267,8 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgslocatorwidget.h"
#include "qgslocator.h"
#include "qgsinbuiltlocatorfilters.h"
#include "qgsgeocoderlocatorfilter.h"
#include "qgsnominatimgeocoder.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapcanvasdockwidget.h"
Expand Down Expand Up @@ -3915,6 +3917,9 @@ void QgisApp::createStatusBar()
mLocatorWidget->locator()->registerFilter( new QgsBookmarkLocatorFilter() );
mLocatorWidget->locator()->registerFilter( new QgsSettingsLocatorFilter() );
mLocatorWidget->locator()->registerFilter( new QgsGotoLocatorFilter() );

mNominatimGeocoder.reset( new QgsNominatimGeocoder() );
mLocatorWidget->locator()->registerFilter( new QgsNominatimLocatorFilter( mNominatimGeocoder.get(), mMapCanvas ) );
}

void QgisApp::setIconSizes( int size )
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -139,6 +139,7 @@ class QgsLabelingWidget;
class QgsLayerStylingWidget;
class QgsDiagramProperties;
class QgsLocatorWidget;
class QgsNominatimGeocoder;
class QgsDataSourceManagerDialog;
class QgsBrowserGuiModel;
class QgsBrowserModel;
Expand Down Expand Up @@ -2682,6 +2683,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void tapAndHoldTriggered( QTapAndHoldGesture *gesture );

QgsLocatorWidget *mLocatorWidget = nullptr;
std::unique_ptr<QgsNominatimGeocoder> mNominatimGeocoder;

QgsStatusBar *mStatusBar = nullptr;

Expand Down
12 changes: 6 additions & 6 deletions src/core/geocoding/qgsnominatimgeocoder.cpp
Expand Up @@ -26,8 +26,8 @@
#include <QJsonDocument>
#include <QJsonArray>

QMutex QgsNominatimGeocoder::sMutex;
QMap< QUrl, QList< QgsGeocoderResult > > QgsNominatimGeocoder::sCachedResults;
typedef QMap< QUrl, QList< QgsGeocoderResult > > CachedGeocodeResult;
Q_GLOBAL_STATIC( CachedGeocodeResult, sCachedResults )
qint64 QgsNominatimGeocoder::sLastRequestTimestamp = 0;

QgsNominatimGeocoder::QgsNominatimGeocoder( const QString &countryCodes, const QString &endpoint )
Expand Down Expand Up @@ -89,8 +89,8 @@ QList<QgsGeocoderResult> QgsNominatimGeocoder::geocodeString( const QString &str
const QUrl url = requestUrl( string, bounds );

QMutexLocker locker( &sMutex );
auto it = sCachedResults.constFind( url );
if ( it != sCachedResults.constEnd() )
auto it = sCachedResults()->constFind( url );
if ( it != sCachedResults()->constEnd() )
{
return *it;
}
Expand Down Expand Up @@ -126,7 +126,7 @@ QList<QgsGeocoderResult> QgsNominatimGeocoder::geocodeString( const QString &str
const QVariantList results = doc.array().toVariantList();
if ( results.isEmpty() )
{
sCachedResults.insert( url, QList<QgsGeocoderResult>() );
sCachedResults()->insert( url, QList<QgsGeocoderResult>() );
return QList<QgsGeocoderResult>();
}

Expand All @@ -137,7 +137,7 @@ QList<QgsGeocoderResult> QgsNominatimGeocoder::geocodeString( const QString &str
matches << jsonToResult( result.toMap() );
}

sCachedResults.insert( url, matches );
sCachedResults()->insert( url, matches );

return matches;
}
Expand Down
3 changes: 1 addition & 2 deletions src/core/geocoding/qgsnominatimgeocoder.h
Expand Up @@ -59,7 +59,7 @@ class CORE_EXPORT QgsNominatimGeocoder : public QgsGeocoderInterface
QUrl requestUrl( const QString &address, const QgsRectangle &bounds = QgsRectangle() ) const;

/**
* Converts a JSON result returned from the Google Maps service to a geocoder result object.
* Converts a JSON result returned from the Nominatim service to a geocoder result object.
*/
QgsGeocoderResult jsonToResult( const QVariantMap &json ) const;

Expand Down Expand Up @@ -116,7 +116,6 @@ class CORE_EXPORT QgsNominatimGeocoder : public QgsGeocoderInterface
double mRequestsPerSecond = 1;

static QMutex sMutex;
static QMap< QUrl, QList< QgsGeocoderResult > > sCachedResults;

static qint64 sLastRequestTimestamp;

Expand Down

0 comments on commit 7eaa5b7

Please sign in to comment.