QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsprocessingfeedback.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingfeedback.cpp
3 -------------------------
4 begin : June 2017
5 copyright : (C) 2017 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 <gdal_version.h>
21#include <ogr_api.h>
22#include <proj.h>
23
24#include "qgsgeos.h"
25#include "qgsmessagelog.h"
27
28#include "moc_qgsprocessingfeedback.cpp"
29
30#ifdef HAVE_PDAL_QGIS
31#include <pdal/pdal.hpp>
32#endif
33
34#ifdef WITH_SFCGAL
35#include <SFCGAL/capi/sfcgal_c.h>
36#endif
37
39 : mLogFeedback( logFeedback )
40{
41
42}
43
44void QgsProcessingFeedback::setProgressText( const QString &text )
45{
46 mHtmlLog.append( text.toHtmlEscaped().replace( '\n', QLatin1String( "<br>" ) ) + QStringLiteral( "<br/>" ) );
47 mTextLog.append( text + '\n' );
48}
49
50void QgsProcessingFeedback::log( const QString &htmlMessage, const QString &textMessage )
51{
52 constexpr int MESSAGE_COUNT_LIMIT = 10000;
53 // Avoid logging too many messages, which might blow memory.
54 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
55 return;
56 ++mMessageLoggedCount;
57 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
58 {
59 mHtmlLog.append( QStringLiteral( "<span style=\"color:red\">%1</span><br/>" ).arg( tr( "Message log truncated" ) ) );
60 mTextLog.append( tr( "Message log truncated" ) + '\n' );
61 }
62 else
63 {
64 mHtmlLog.append( htmlMessage );
65 mTextLog.append( textMessage );
66 }
67}
68
69
70void QgsProcessingFeedback::reportError( const QString &error, bool )
71{
72 if ( mLogFeedback )
73 QgsMessageLog::logMessage( error, tr( "Processing" ), Qgis::MessageLevel::Critical );
74
75 log( QStringLiteral( "<span style=\"color:red\">%1</span><br/>" ).arg( error.toHtmlEscaped() ).replace( '\n', QLatin1String( "<br>" ) ),
76 error + '\n' );
77}
78
79void QgsProcessingFeedback::pushWarning( const QString &warning )
80{
81 if ( mLogFeedback )
82 QgsMessageLog::logMessage( warning, tr( "Processing" ), Qgis::MessageLevel::Warning );
83
84 log( QStringLiteral( "<span style=\"color:#b85a20;\">%1</span><br/>" ).arg( warning.toHtmlEscaped() ).replace( '\n', QLatin1String( "<br>" ) ) + QStringLiteral( "<br/>" ),
85 warning + '\n' );
86}
87
88void QgsProcessingFeedback::pushInfo( const QString &info )
89{
90 if ( mLogFeedback )
91 QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::MessageLevel::Info );
92
93 mHtmlLog.append( info.toHtmlEscaped().replace( '\n', QLatin1String( "<br>" ) ) + QStringLiteral( "<br/>" ) );
94 mTextLog.append( info + '\n' );
95}
96
97void QgsProcessingFeedback::pushFormattedMessage( const QString &html, const QString &text )
98{
99 if ( mLogFeedback )
100 QgsMessageLog::logMessage( text, tr( "Processing" ), Qgis::MessageLevel::Info );
101
102 mHtmlLog.append( html + QStringLiteral( "<br/>" ) );
103 mTextLog.append( text + '\n' );
104}
105
106void QgsProcessingFeedback::pushCommandInfo( const QString &info )
107{
108 if ( mLogFeedback )
109 QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::MessageLevel::Info );
110
111 log( QStringLiteral( "<code>%1</code><br/>" ).arg( info.toHtmlEscaped().replace( '\n', QLatin1String( "<br>" ) ) ),
112 info + '\n' );
113}
114
115void QgsProcessingFeedback::pushDebugInfo( const QString &info )
116{
117 if ( mLogFeedback )
118 QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::MessageLevel::Info );
119
120 log( QStringLiteral( "<span style=\"color:#777\">%1</span><br/>" ).arg( info.toHtmlEscaped().replace( '\n', QLatin1String( "<br>" ) ) ),
121 info + '\n' );
122}
123
124void QgsProcessingFeedback::pushConsoleInfo( const QString &info )
125{
126 if ( mLogFeedback )
127 QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::MessageLevel::Info );
128
129 log( QStringLiteral( "<code style=\"color:#777\">%1</code><br/>" ).arg( info.toHtmlEscaped().replace( '\n', QLatin1String( "<br>" ) ) ),
130 info + '\n' );
131}
132
134{
135 pushDebugInfo( tr( "QGIS version: %1" ).arg( Qgis::version() ) );
136 if ( QString( Qgis::devVersion() ) != QLatin1String( "exported" ) )
137 {
138 pushDebugInfo( tr( "QGIS code revision: %1" ).arg( Qgis::devVersion() ) );
139 }
140 pushDebugInfo( tr( "Qt version: %1" ).arg( qVersion() ) );
141 pushDebugInfo( tr( "Python version: %1" ).arg( PYTHON_VERSION ) );
142 pushDebugInfo( tr( "GDAL version: %1" ).arg( GDALVersionInfo( "RELEASE_NAME" ) ) );
143 pushDebugInfo( tr( "GEOS version: %1" ).arg( GEOSversion() ) );
144
145 const PJ_INFO info = proj_info();
146 pushDebugInfo( tr( "PROJ version: %1" ).arg( info.release ) );
147
148#ifdef HAVE_PDAL_QGIS
149#if PDAL_VERSION_MAJOR_INT > 1 || (PDAL_VERSION_MAJOR_INT == 1 && PDAL_VERSION_MINOR_INT >= 7)
150 pushDebugInfo( tr( "PDAL version: %1" ).arg( QString::fromStdString( pdal::Config::fullVersionString() ) ) );
151#else
152 pushDebugInfo( tr( "PDAL version: %1" ).arg( QString::fromStdString( pdal::GetFullVersionString() ) ) );
153#endif
154#endif
155
156#ifdef WITH_SFCGAL
157 pushDebugInfo( tr( "SFCGAL version: %1" ).arg( sfcgal_version() ) );
158#else
159 pushDebugInfo( tr( "No support for SFCGAL" ) );
160#endif
161
162 if ( provider && !provider->versionInfo().isEmpty() )
163 {
164 pushDebugInfo( tr( "%1 version: %2" ).arg( provider->name(), provider->versionInfo() ) );
165 }
166}
167
169{
170 if ( results.empty() )
171 return;
172
173 pushInfo( tr( "Results:" ) );
174
175 const QList< const QgsProcessingOutputDefinition * > outputs = algorithm->outputDefinitions();
176 for ( const QgsProcessingOutputDefinition *output : outputs )
177 {
178 const QString outputName = output->name();
179 if ( outputName == QLatin1String( "CHILD_RESULTS" ) || outputName == QLatin1String( "CHILD_INPUTS" ) )
180 continue;
181
182 if ( !results.contains( outputName ) )
183 continue;
184
185 bool ok = false;
186 const QString textValue = output->valueAsString( results.value( output->name() ), context, ok );
187 const QString formattedValue = output->valueAsFormattedString( results.value( output->name() ), context, ok );
188 if ( ok )
189 {
190 pushFormattedMessage( QStringLiteral( "<code>&nbsp;&nbsp;%1: %2</code>" ).arg( output->name(), formattedValue ),
191 QStringLiteral( " %1: %2" ).arg( output->name(), textValue ) );
192 }
193 }
194}
195
197{
198 return mHtmlLog;
199}
200
202{
203 return mTextLog;
204}
205
206
208 : mChildSteps( childAlgorithmCount )
209 , mFeedback( feedback )
210{
211 if ( mFeedback )
212 {
213 connect( mFeedback, &QgsFeedback::canceled, this, &QgsFeedback::cancel, Qt::DirectConnection );
214 connect( this, &QgsFeedback::progressChanged, this, &QgsProcessingMultiStepFeedback::updateOverallProgress );
215 }
216}
217
219{
220 mCurrentStep = step;
221
222 if ( mFeedback )
223 mFeedback->setProgress( 100.0 * static_cast< double >( mCurrentStep ) / mChildSteps );
224}
225
227{
228 if ( mFeedback )
229 mFeedback->setProgressText( text );
230}
231
232void QgsProcessingMultiStepFeedback::reportError( const QString &error, bool fatalError )
233{
234 if ( mFeedback )
235 mFeedback->reportError( error, fatalError );
236}
237
239{
240 if ( mFeedback )
241 mFeedback->pushWarning( warning );
242}
243
245{
246 if ( mFeedback )
247 mFeedback->pushInfo( info );
248}
249
251{
252 if ( mFeedback )
253 mFeedback->pushCommandInfo( info );
254}
255
257{
258 if ( mFeedback )
259 mFeedback->pushDebugInfo( info );
260}
261
263{
264 if ( mFeedback )
265 mFeedback->pushConsoleInfo( info );
266}
267
268void QgsProcessingMultiStepFeedback::pushFormattedMessage( const QString &html, const QString &text )
269{
270 if ( mFeedback )
271 mFeedback->pushFormattedMessage( html, text );
272}
273
275{
276 if ( mFeedback )
277 return mFeedback->htmlLog();
278 return QString();
279}
280
282{
283 if ( mFeedback )
284 return mFeedback->textLog();
285 return QString();
286}
287
288void QgsProcessingMultiStepFeedback::updateOverallProgress( double progress )
289{
290 const double baseProgress = 100.0 * static_cast< double >( mCurrentStep ) / mChildSteps;
291 const double currentAlgorithmProgress = progress / mChildSteps;
292 if ( mFeedback )
293 mFeedback->setProgress( baseProgress + currentAlgorithmProgress );
294}
static QString version()
Version string.
Definition qgis.cpp:677
@ Warning
Warning message.
Definition qgis.h:158
@ Critical
Critical/error message.
Definition qgis.h:159
@ Info
Information message.
Definition qgis.h:157
static QString devVersion()
The development version.
Definition qgis.cpp:694
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
void canceled()
Internal routines can connect to this signal if they use event loop.
void cancel()
Tells the internal routines that the current operation should be canceled. This should be run by the ...
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
double progress() const
Returns the current progress reported by the feedback object.
Definition qgsfeedback.h:77
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
virtual void pushCommandInfo(const QString &info)
Pushes an informational message containing a command from the algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
void pushVersionInfo(const QgsProcessingProvider *provider=nullptr)
Pushes a summary of the QGIS (and underlying library) version information to the log.
virtual QString textLog() const
Returns the plain text contents of the log, which contains all messages pushed to the feedback object...
QgsProcessingFeedback(bool logFeedback=true)
Constructor for QgsProcessingFeedback.
void pushFormattedResults(const QgsProcessingAlgorithm *algorithm, QgsProcessingContext &context, const QVariantMap &results)
Pushes a summary of the execution results to the log.
virtual QString htmlLog() const
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void pushFormattedMessage(const QString &html, const QString &text)
Pushes a pre-formatted message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
virtual void pushConsoleInfo(const QString &info)
Pushes a console feedback message from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
QgsProcessingMultiStepFeedback(int steps, QgsProcessingFeedback *feedback)
Constructor for QgsProcessingMultiStepFeedback, for a process with the specified number of steps.
void pushDebugInfo(const QString &info) override
Pushes an informational message containing debugging helpers from the algorithm.
void pushFormattedMessage(const QString &html, const QString &text) override
Pushes a pre-formatted message from the algorithm.
void pushConsoleInfo(const QString &info) override
Pushes a console feedback message from the algorithm.
void pushInfo(const QString &info) override
Pushes a general informational message from the algorithm.
void pushWarning(const QString &warning) override
Pushes a warning informational message from the algorithm.
void setProgressText(const QString &text) override
Sets a progress report text string.
void setCurrentStep(int step)
Sets the step which is being executed.
void reportError(const QString &error, bool fatalError=false) override
Reports that the algorithm encountered an error while executing.
QString textLog() const override
Returns the plain text contents of the log, which contains all messages pushed to the feedback object...
void pushCommandInfo(const QString &info) override
Pushes an informational message containing a command from the algorithm.
QString htmlLog() const override
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback ob...
Base class for the definition of processing outputs.
Abstract base class for processing providers.
virtual QString versionInfo() const
Returns a version information string for the provider, or an empty string if this is not applicable (...
virtual QString name() const =0
Returns the provider name, which is used to describe the provider within the GUI.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call