QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsalgorithmbatchgeocode.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmbatchgeocode.cpp
3  ------------------
4  begin : August 2020
5  copyright : (C) 2020 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsgeocoder.h"
20 #include "qgsgeocoderresult.h"
21 #include "qgsgeocodercontext.h"
22 #include "qgsvectorlayer.h"
23 
26  , mGeocoder( geocoder )
27 {
28 
29 }
30 
31 QStringList QgsBatchGeocodeAlgorithm::tags() const
32 {
33  return QObject::tr( "geocode" ).split( ',' );
34 }
35 
37 {
38  return QObject::tr( "Vector general" );
39 }
40 
42 {
43  return QStringLiteral( "vectorgeneral" );
44 }
45 
46 void QgsBatchGeocodeAlgorithm::initParameters( const QVariantMap &configuration )
47 {
48  mIsInPlace = configuration.value( QStringLiteral( "IN_PLACE" ) ).toBool();
49 
50  addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ), QObject::tr( "Address field" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::String ) );
51 
52  if ( mIsInPlace )
53  {
54  const QgsFields newFields = mGeocoder->appendedFields();
55  for ( const QgsField &newField : newFields )
56  addParameter( new QgsProcessingParameterField( newField.name(), QObject::tr( "%1 field" ).arg( newField.name() ), newField.name(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
57  }
58 }
59 
61 {
62  return QList<int>() << QgsProcessing::TypeVector;
63 }
64 
66 {
67  if ( const QgsVectorLayer *vl = qobject_cast< const QgsVectorLayer * >( layer ) )
68  {
69  return vl->geometryType() == QgsWkbTypes::PointGeometry;
70  }
71  return false;
72 }
73 
75 {
76  return QObject::tr( "Geocoded" );
77 }
78 
80 {
81  mAddressField = parameterAsString( parameters, QStringLiteral( "FIELD" ), context );
82 
83  if ( mIsInPlace )
84  {
85  const QgsFields newFields = mGeocoder->appendedFields();
86  for ( const QgsField &newField : newFields )
87  mInPlaceFieldMap.insert( newField.name(), parameterAsString( parameters, newField.name(), context ) );
88  }
89 
90  return true;
91 }
92 
94 {
95  return QgsWkbTypes::Point;
96 }
97 
99 {
100  mOutputCrs = inputCrs;
101  return mOutputCrs;
102 }
103 
105 {
106  if ( !mIsInPlace )
107  {
108  // append any additional fields created by the geocoder
109  const QgsFields newFields = mGeocoder->appendedFields();
110  mAdditionalFields = newFields.names();
111 
112  return QgsProcessingUtils::combineFields( inputFields, newFields );
113  }
114  else
115  {
116  return inputFields;
117  }
118 }
119 
121 {
122  QgsFeature f = feature;
123 
124  const QString address = f.attribute( mAddressField ).toString();
125  if ( address.isEmpty() )
126  {
127  f.padAttributes( mAdditionalFields.count() );
128  feedback->pushWarning( QObject::tr( "Empty address field for feature %1" ).arg( feature.id() ) );
129  return QgsFeatureList() << f;
130  }
131 
132  const QgsGeocoderContext geocodeContext( context.transformContext() );
133  const QList< QgsGeocoderResult > results = mGeocoder->geocodeString( address, geocodeContext, feedback );
134  if ( results.empty() )
135  {
136  f.padAttributes( mAdditionalFields.count() );
137  feedback->pushWarning( QObject::tr( "No result for %1" ).arg( address ) );
138  return QgsFeatureList() << f;
139  }
140 
141  if ( !results.at( 0 ).isValid() )
142  {
143  f.padAttributes( mAdditionalFields.count() );
144  feedback->reportError( QObject::tr( "Error geocoding %1: %2" ).arg( address, results.at( 0 ).error() ) );
145  return QgsFeatureList() << f;
146  }
147 
148  QgsAttributes attr = f.attributes();
149  const QVariantMap additionalAttributes = results.at( 0 ).additionalAttributes();
150  if ( !mIsInPlace )
151  {
152  for ( const QString &additionalField : mAdditionalFields )
153  {
154  attr.append( additionalAttributes.value( additionalField ) );
155  }
156  f.setAttributes( attr );
157  }
158  else
159  {
160  for ( auto it = mInPlaceFieldMap.constBegin(); it != mInPlaceFieldMap.constEnd(); ++it )
161  {
162  if ( !it.value().isEmpty() )
163  {
164  f.setAttribute( it.value(), additionalAttributes.value( it.key() ) );
165  }
166  }
167  }
168 
169  const QgsCoordinateTransform transform = QgsCoordinateTransform( results.at( 0 ).crs(), mOutputCrs, context.transformContext() );
170  QgsGeometry g = results.at( 0 ).geometry();
171  try
172  {
173  g.transform( transform );
174  }
175  catch ( QgsCsException & )
176  {
177  feedback->reportError( QObject::tr( "Error transforming %1 to layer CRS" ).arg( address ) );
178  return QgsFeatureList() << f;
179  }
180 
181  f.setGeometry( g );
182  return QgsFeatureList() << f;
183 }
QgsProcessingParameterField::String
@ String
Accepts string fields.
Definition: qgsprocessingparameters.h:2949
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
qgsgeocoder.h
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:37
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
QgsProcessingFeedback::reportError
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Definition: qgsprocessingfeedback.cpp:59
QgsProcessingAlgorithm::addParameter
bool addParameter(QgsProcessingParameterDefinition *parameterDefinition, bool createOutput=true)
Adds a parameter definition to the algorithm.
Definition: qgsprocessingalgorithm.cpp:386
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsBatchGeocodeAlgorithm::outputWkbType
QgsWkbTypes::Type outputWkbType(QgsWkbTypes::Type inputWkbType) const override
Maps the input WKB geometry type (inputWkbType) to the corresponding output WKB type generated by the...
Definition: qgsalgorithmbatchgeocode.cpp:93
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
QgsProcessingAlgorithm::parameterAsString
QString parameterAsString(const QVariantMap &parameters, const QString &name, const QgsProcessingContext &context) const
Evaluates the parameter with matching name to a static string value.
Definition: qgsprocessingalgorithm.cpp:663
QgsProcessingUtils::combineFields
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
Definition: qgsprocessingutils.cpp:1238
QgsProcessingFeatureBasedAlgorithm
An abstract QgsProcessingAlgorithm base class for processing algorithms which operate "feature-by-fea...
Definition: qgsprocessingalgorithm.h:1143
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
qgsgeocoderresult.h
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsProcessing::TypeVector
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:54
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:46
QgsGeocoderInterface::appendedFields
virtual QgsFields appendedFields() const
Returns a set of newly created fields which will be appended to existing features during the geocode ...
Definition: qgsgeocoder.cpp:25
QgsBatchGeocodeAlgorithm::QgsBatchGeocodeAlgorithm
QgsBatchGeocodeAlgorithm(QgsGeocoderInterface *geocoder)
Constructor for QgsBatchGeocodeAlgorithm.
Definition: qgsalgorithmbatchgeocode.cpp:24
QgsBatchGeocodeAlgorithm::outputName
QString outputName() const override
Returns the translated, user visible name for any layers created by this algorithm.
Definition: qgsalgorithmbatchgeocode.cpp:74
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:327
QgsGeocoderInterface::geocodeString
virtual QList< QgsGeocoderResult > geocodeString(const QString &string, const QgsGeocoderContext &context, QgsFeedback *feedback=nullptr) const
Geocodes a string.
Definition: qgsgeocoder.cpp:29
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:165
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
qgsvectorlayer.h
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
Definition: qgsfeature.cpp:262
QgsGeocoderContext
Encapsulates the context of a geocoding operation.
Definition: qgsgeocodercontext.h:31
QgsBatchGeocodeAlgorithm::processFeature
QgsFeatureList processFeature(const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback *feedback) override
Processes an individual input feature from the source.
Definition: qgsalgorithmbatchgeocode.cpp:120
QgsBatchGeocodeAlgorithm::group
QString group() const override
Returns the name of the group this algorithm belongs to.
Definition: qgsalgorithmbatchgeocode.cpp:36
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsBatchGeocodeAlgorithm::inputLayerTypes
QList< int > inputLayerTypes() const override
Returns the valid input layer types for the source layer for this algorithm.
Definition: qgsalgorithmbatchgeocode.cpp:60
QgsAttributes
A vector of attributes. Mostly equal to QVector<QVariant>.
Definition: qgsattributes.h:57
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsBatchGeocodeAlgorithm::supportInPlaceEdit
bool supportInPlaceEdit(const QgsMapLayer *layer) const override
Checks whether this algorithm supports in-place editing on the given layer Default implementation for...
Definition: qgsalgorithmbatchgeocode.cpp:65
QgsBatchGeocodeAlgorithm::outputFields
QgsFields outputFields(const QgsFields &inputFields) const override
Maps the input source fields (inputFields) to corresponding output fields generated by the algorithm.
Definition: qgsalgorithmbatchgeocode.cpp:104
QgsBatchGeocodeAlgorithm::initParameters
void initParameters(const QVariantMap &configuration=QVariantMap()) override
Initializes any extra parameters added by the algorithm subclass.
Definition: qgsalgorithmbatchgeocode.cpp:46
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
QgsFeature::padAttributes
void padAttributes(int count)
Resizes the attributes attached to this feature by appending the specified count of NULL values to th...
Definition: qgsfeature.cpp:253
QgsProcessingParameterField::Any
@ Any
Accepts any field.
Definition: qgsprocessingparameters.h:2947
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsBatchGeocodeAlgorithm::outputCrs
QgsCoordinateReferenceSystem outputCrs(const QgsCoordinateReferenceSystem &inputCrs) const override
Maps the input source coordinate reference system (inputCrs) to a corresponding output CRS generated ...
Definition: qgsalgorithmbatchgeocode.cpp:98
QgsBatchGeocodeAlgorithm::groupId
QString groupId() const override
Returns the unique ID of the group this algorithm belongs to.
Definition: qgsalgorithmbatchgeocode.cpp:41
QgsProcessingParameterField
A vector layer or feature source field parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2940
QgsBatchGeocodeAlgorithm::tags
QStringList tags() const override
Returns a list of tags which relate to the algorithm, and are used to assist users in searching for s...
Definition: qgsalgorithmbatchgeocode.cpp:31
QgsBatchGeocodeAlgorithm::prepareAlgorithm
bool prepareAlgorithm(const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback) override
Prepares the algorithm to run using the specified parameters.
Definition: qgsalgorithmbatchgeocode.cpp:79
QgsGeocoderInterface
Interface for geocoders.
Definition: qgsgeocoder.h:36
QgsProcessingFeedback::pushWarning
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
Definition: qgsprocessingfeedback.cpp:68
QgsFields::names
QStringList names() const
Returns a list with field names.
Definition: qgsfields.cpp:143
qgsalgorithmbatchgeocode.h
qgsgeocodercontext.h
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50