2

I want to create a custom processing tool for geocoding in QGIS.

It will reproduce the "Batch Nominatim geocoder" geoalgorithm, besides several things:

  • another URL of a geocoder will be used instead of the the Nominatim
  • there will be no limitations in requests

From the "Batch Nominatim geocoder" I would like to inherit: GUI, functionality and logic.

I tried to create a model in the Graphical Modeler and export it as a Python Processing Script, however it does not look like what I need.

"""
Model exported as python.
Name : geocoding
Group : STMA
With QGIS : 32205
"""

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterFeatureSink
import processing


class Geocoding(QgsProcessingAlgorithm):

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterVectorLayer('Adressen', 'adressen', types=[QgsProcessing.TypeVector], defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Geocodiert', 'geocodiert', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, supportsAppend=True, defaultValue=None))

    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(1, model_feedback)
        results = {}
        outputs = {}

        # Batch Nominatim geocoder
        alg_params = {
            'FIELD': 'Anschrift',
            'INPUT': parameters['Adressen'],
            'OUTPUT': parameters['Geocodiert']
        }
        outputs['BatchNominatimGeocoder'] = processing.run('native:batchnominatimgeocoder', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Geocodiert'] = outputs['BatchNominatimGeocoder']['OUTPUT']
        return results

    def name(self):
        return 'geocoding'

    def displayName(self):
        return 'geocoding'

    def group(self):
        return 'STMA'

    def groupId(self):
        return ''

    def createInstance(self):
        return Geocoding()

I could find this geoalgorithm in QGIS/src/core/geocoding/qgsnominatimgeocoder.cpp on the GitHub. This is the part with an URL:

QgsNominatimGeocoder::QgsNominatimGeocoder( const QString &countryCodes, const QString &endpoint )
  : QgsGeocoderInterface()
  , mCountryCodes( countryCodes )
  , mEndpoint( QStringLiteral( "https://nominatim.qgis.org/search" ) )

But C++ is simply beyond my programming skills.

Another (maybe a feasible) solution is to reproduce the "Google Maps Geocoder" plugin developed by @ndawson. It is basically a processing tool, similar to "Batch Nominatim geocoder" but implemented for Google Maps. This plugin is available on the GitHub: https://github.com/north-road/qgis-google-maps-geocoder. Unfortunately the geocoding in this plugin is dependent on the QgsGoogleMapsGeocoder class, not a simple request to Google Maps API.

What are my available approaches?

Perhaps it is in general impossible because I simply collide with copyrights of the core developer (Mathieu Pellerin @nirvn).

4
  • 1
    No colliding since QGIS project is in GPL2 : github.com/qgis/QGIS/blob/master/COPYING Jun 22 at 8:28
  • 1
  • 1
    Note that 90% of what these implementations do is stitching together core library classes to create request objects that conform with the respective API, sending and receiving http(s) requests, and parsing the respective API responses - some sanity checks aside. What this means for you is that you will either have to rewrite these 90% in C++ to suit your own API - or simply write an own, independent Python plugin to begin with.
    – geozelot
    Jun 22 at 9:43
  • 1
    I would just rewrite the script of batchnominatim from scratch in Python, thats probably the most straight forward option. Even if you don't know c++, you can still get the logic of the code. About license I dont see an issue. Even if you use parts of others code, most of them allow usage by naming the authors or under the same terms.
    – MrXsquared
    Jun 22 at 14:45

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.