QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
Loading...
Searching...
No Matches
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
20#include "qgsgeocoder.h"
21#include "qgsgeocodercontext.h"
22#include "qgsgeocoderresult.h"
23#include "qgsvectorlayer.h"
24
25#include <QString>
26
27using namespace Qt::StringLiterals;
28
33
35{
36 return QObject::tr( "geocode" ).split( ',' );
37}
38
40{
41 return QObject::tr( "Vector general" );
42}
43
45{
46 return u"vectorgeneral"_s;
47}
48
49void QgsBatchGeocodeAlgorithm::initParameters( const QVariantMap &configuration )
50{
51 mIsInPlace = configuration.value( u"IN_PLACE"_s ).toBool();
52
53 addParameter( new QgsProcessingParameterField( u"FIELD"_s, QObject::tr( "Address field" ), QVariant(), u"INPUT"_s, Qgis::ProcessingFieldParameterDataType::String ) );
54
55 if ( mIsInPlace )
56 {
57 const QgsFields newFields = mGeocoder->appendedFields();
58 for ( const QgsField &newField : newFields )
60 new QgsProcessingParameterField( newField.name(), QObject::tr( "%1 field" ).arg( newField.name() ), newField.name(), u"INPUT"_s, Qgis::ProcessingFieldParameterDataType::Any, false, true )
61 );
62 }
63}
64
66{
67 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::Vector );
68}
69
71{
72 if ( const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( layer ) )
73 {
74 return vl->geometryType() == Qgis::GeometryType::Point;
75 }
76 return false;
77}
78
80{
81 return QObject::tr( "Geocoded" );
82}
83
85{
86 mAddressField = parameterAsString( parameters, u"FIELD"_s, context );
87
88 if ( mIsInPlace )
89 {
90 const QgsFields newFields = mGeocoder->appendedFields();
91 for ( const QgsField &newField : newFields )
92 mInPlaceFieldMap.insert( newField.name(), parameterAsString( parameters, newField.name(), context ) );
93 }
94
95 return true;
96}
97
102
104{
105 mOutputCrs = inputCrs;
106 return mOutputCrs;
107}
108
110{
111 if ( !mIsInPlace )
112 {
113 // append any additional fields created by the geocoder
114 const QgsFields newFields = mGeocoder->appendedFields();
115 mAdditionalFields = newFields.names();
116
117 return QgsProcessingUtils::combineFields( inputFields, newFields );
118 }
119 else
120 {
121 return inputFields;
122 }
123}
124
126{
127 QGS_MARK_ALGORITHM_SOURCE
128
129 QgsFeature f = feature;
130
131 const QString address = f.attribute( mAddressField ).toString();
132 if ( address.isEmpty() )
133 {
134 f.padAttributes( mAdditionalFields.count() );
135 feedback->pushWarning( QObject::tr( "Empty address field for feature %1" ).arg( feature.id() ) );
136 return QgsFeatureList() << f;
137 }
138
139 const QgsGeocoderContext geocodeContext( context.transformContext() );
140 const QList<QgsGeocoderResult> results = mGeocoder->geocodeString( address, geocodeContext, feedback );
141 if ( results.empty() )
142 {
143 f.padAttributes( mAdditionalFields.count() );
144 feedback->pushWarning( QObject::tr( "No result for %1" ).arg( address ) );
145 return QgsFeatureList() << f;
146 }
147
148 if ( !results.at( 0 ).isValid() )
149 {
150 f.padAttributes( mAdditionalFields.count() );
151 feedback->reportError( QObject::tr( "Error geocoding %1: %2" ).arg( address, results.at( 0 ).error() ) );
152 return QgsFeatureList() << f;
153 }
154
155 QgsAttributes attr = f.attributes();
156 const QVariantMap additionalAttributes = results.at( 0 ).additionalAttributes();
157 if ( !mIsInPlace )
158 {
159 for ( const QString &additionalField : mAdditionalFields )
160 {
161 attr.append( additionalAttributes.value( additionalField ) );
162 }
163 f.setAttributes( attr );
164 }
165 else
166 {
167 for ( auto it = mInPlaceFieldMap.constBegin(); it != mInPlaceFieldMap.constEnd(); ++it )
168 {
169 if ( !it.value().isEmpty() )
170 {
171 f.setAttribute( it.value(), additionalAttributes.value( it.key() ) );
172 }
173 }
174 }
175
176 const QgsCoordinateTransform transform = QgsCoordinateTransform( results.at( 0 ).crs(), mOutputCrs, context.transformContext() );
177 QgsGeometry g = results.at( 0 ).geometry();
178 try
179 {
180 g.transform( transform );
181 }
182 catch ( QgsCsException & )
183 {
184 feedback->reportError( QObject::tr( "Error transforming %1 to layer CRS" ).arg( address ) );
185 return QgsFeatureList() << f;
186 }
187
188 f.setGeometry( g );
189 return QgsFeatureList() << f;
190}
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3755
@ String
Accepts string fields.
Definition qgis.h:4038
@ Point
Points.
Definition qgis.h:380
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ Point
Point.
Definition qgis.h:296
A vector of attributes.
bool prepareAlgorithm(const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback) override
Prepares the algorithm to run using the specified parameters.
QgsFeatureList processFeature(const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback *feedback) override
Processes an individual input feature from the source.
void initParameters(const QVariantMap &configuration=QVariantMap()) override
Initializes any extra parameters added by the algorithm subclass.
QString group() const override
Returns the name of the group this algorithm belongs to.
QString outputName() const override
Returns the translated, user visible name for any layers created by this algorithm.
QgsCoordinateReferenceSystem outputCrs(const QgsCoordinateReferenceSystem &inputCrs) const override
Maps the input source coordinate reference system (inputCrs) to a corresponding output CRS generated ...
QgsBatchGeocodeAlgorithm(QgsGeocoderInterface *geocoder)
Constructor for QgsBatchGeocodeAlgorithm.
QgsFields outputFields(const QgsFields &inputFields) const override
Maps the input source fields (inputFields) to corresponding output fields generated by the algorithm.
QString groupId() const override
Returns the unique ID of the group this algorithm belongs to.
QStringList tags() const override
Returns a list of tags which relate to the algorithm, and are used to assist users in searching for s...
bool supportInPlaceEdit(const QgsMapLayer *layer) const override
Checks whether this algorithm supports in-place editing on the given layer Default implementation ret...
Qgis::WkbType outputWkbType(Qgis::WkbType inputWkbType) const override
Maps the input WKB geometry type (inputWkbType) to the corresponding output WKB type generated by the...
QList< int > inputLayerTypes() const override
Returns the valid input layer types for the source layer for this algorithm.
Represents a coordinate reference system (CRS).
Handles coordinate transforms between two coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsFeatureId id
Definition qgsfeature.h:63
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:56
Container of fields for a vector layer.
Definition qgsfields.h:45
QStringList names
Definition qgsfields.h:50
Encapsulates the context of a geocoding operation.
Interface for geocoders.
Definition qgsgeocoder.h:37
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
Base class for all map layer types.
Definition qgsmaplayer.h:83
bool addParameter(QgsProcessingParameterDefinition *parameterDefinition, bool createOutput=true)
Adds a parameter definition to the algorithm.
QString parameterAsString(const QVariantMap &parameters, const QString &name, const QgsProcessingContext &context) const
Evaluates the parameter with matching name to a static string value.
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Base class for providing feedback from a processing algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A vector layer or feature source field parameter for processing algorithms.
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).
Represents a vector layer which manages a vector based dataset.
QList< QgsFeature > QgsFeatureList