33#include <QImageWriter>
36using namespace Qt::StringLiterals;
40class QgsAlgorithmElevationProfilePlotItem :
public Qgs2DXyPlot
43 explicit QgsAlgorithmElevationProfilePlotItem(
int width,
int height,
int dpi )
48 setSize( QSizeF( width, height ) );
51 void setRenderer( QgsProfilePlotRenderer *renderer ) { mRenderer = renderer; }
55 if ( !mPlotArea.isNull() )
61 QgsRenderContext context;
64 QgsPlotRenderContext plotContext;
70 void renderContent( QgsRenderContext &rc, QgsPlotRenderContext &,
const QRectF &plotArea,
const QgsPlotData & )
override
77 rc.
painter()->translate( mPlotArea.left(), mPlotArea.top() );
78 const QStringList sourceIds = mRenderer->sourceIds();
79 for (
const QString &source : sourceIds )
81 mRenderer->render( rc, mPlotArea.width(), mPlotArea.height(), xMinimum(),
xMaximum(),
yMinimum(),
yMaximum(), source );
83 rc.
painter()->translate( -mPlotArea.left(), -mPlotArea.top() );
89 QgsProfilePlotRenderer *mRenderer =
nullptr;
92void QgsGenerateElevationProfileAlgorithm::initAlgorithm(
const QVariantMap & )
102 auto minimumDistanceParam
105 addParameter( minimumDistanceParam.release() );
106 auto maximumDistanceParam
109 addParameter( maximumDistanceParam.release() );
110 auto minimumElevationParam
113 addParameter( minimumElevationParam.release() );
114 auto maximumElevationParam
117 addParameter( maximumElevationParam.release() );
119 auto textColorParam = std::make_unique<QgsProcessingParameterColor>( u
"TEXT_COLOR"_s, QObject::tr(
"Chart text color" ), QColor( 0, 0, 0 ),
true,
true );
121 addParameter( textColorParam.release() );
123 auto textFontFamilyParam = std::make_unique<QgsProcessingParameterString>( u
"TEXT_FONT_FAMILY"_s, QObject::tr(
"Chart text font family" ), QVariant(),
false,
true );
125 addParameter( textFontFamilyParam.release() );
127 auto textFontStyleParam = std::make_unique<QgsProcessingParameterString>( u
"TEXT_FONT_STYLE"_s, QObject::tr(
"Chart text font style" ), QVariant(),
false,
true );
129 addParameter( textFontStyleParam.release() );
133 addParameter( textFontSizeParam.release() );
135 auto backgroundColorParam = std::make_unique<QgsProcessingParameterColor>( u
"BACKGROUND_COLOR"_s, QObject::tr(
"Chart background color" ), QColor( 255, 255, 255 ),
true,
true );
137 addParameter( backgroundColorParam.release() );
138 auto borderColorParam = std::make_unique<QgsProcessingParameterColor>( u
"BORDER_COLOR"_s, QObject::tr(
"Chart border color" ), QColor( 99, 99, 99 ),
true,
true );
140 addParameter( borderColorParam.release() );
144 addParameter( toleranceParam.release() );
148 addParameter( dpiParam.release() );
153QString QgsGenerateElevationProfileAlgorithm::name()
const
155 return u
"generateelevationprofileimage"_s;
158QString QgsGenerateElevationProfileAlgorithm::displayName()
const
160 return QObject::tr(
"Generate elevation profile image" );
163QStringList QgsGenerateElevationProfileAlgorithm::tags()
const
165 return QObject::tr(
"altitude,elevation,terrain,dem" ).split(
',' );
168QString QgsGenerateElevationProfileAlgorithm::group()
const
170 return QObject::tr(
"Plots" );
173QString QgsGenerateElevationProfileAlgorithm::groupId()
const
178QString QgsGenerateElevationProfileAlgorithm::shortHelpString()
const
180 return QObject::tr(
"This algorithm creates an elevation profile image from a list of map layer and an optional terrain." );
183QString QgsGenerateElevationProfileAlgorithm::shortDescription()
const
185 return QObject::tr(
"Creates an elevation profile image from a list of map layer and an optional terrain." );
188QgsGenerateElevationProfileAlgorithm *QgsGenerateElevationProfileAlgorithm::createInstance()
const
190 return new QgsGenerateElevationProfileAlgorithm();
195 const QgsGeometry curveGeom = parameterAsGeometry( parameters, u
"CURVE"_s, context );
198 QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, u
"MAP_LAYERS"_s, context );
199 QgsMapLayer *terrainLayer = parameterAsLayer( parameters, u
"TERRAIN_LAYER"_s, context );
201 const double tolerance = parameterAsDouble( parameters, u
"TOLERANCE"_s, context );
203 QList<QgsAbstractProfileSource *> sources;
207 sources.append( source );
211 request.setCrs( curveCrs );
212 request.setTolerance( tolerance );
220 auto terrainProvider = std::make_unique<QgsRasterDemTerrainProvider>();
221 terrainProvider->setLayer( rasterLayer );
222 request.setTerrainProvider( terrainProvider.release() );
226 auto terrainProvider = std::make_unique<QgsMeshTerrainProvider>();
227 terrainProvider->setLayer( meshLayer );
228 request.setTerrainProvider( terrainProvider.release() );
233 mRenderer = std::make_unique<QgsProfilePlotRenderer>( sources, request );
240 QGS_MARK_ALGORITHM_SOURCE
242 const QgsGeometry curveGeom = parameterAsGeometry( parameters, u
"CURVE"_s, context );
244 const bool hasMinimumDistance = parameters.value( u
"MINIMUM_DISTANCE"_s ).isValid();
245 const double minimumDistance = parameterAsDouble( parameters, u
"MINIMUM_DISTANCE"_s, context );
246 const bool hasMaximumDistance = parameters.value( u
"MAXIMUM_DISTANCE"_s ).isValid();
247 const double maximumDistance = parameterAsDouble( parameters, u
"MAXIMUM_DISTANCE"_s, context );
248 const bool hasMinimumElevation = parameters.value( u
"MINIMUM_ELEVATION"_s ).isValid();
249 const double minimumElevation = parameterAsDouble( parameters, u
"MINIMUM_ELEVATION"_s, context );
250 const bool hasMaximumElevation = parameters.value( u
"MAXIMUM_ELEVATION"_s ).isValid();
251 const double maximumElevation = parameterAsDouble( parameters, u
"MAXIMUM_ELEVATION"_s, context );
253 const int width = parameterAsInt( parameters, u
"WIDTH"_s, context );
254 const int height = parameterAsInt( parameters, u
"HEIGHT"_s, context );
255 const int dpi = parameterAsInt( parameters, u
"DPI"_s, context );
257 const QString outputImage = parameterAsString( parameters, u
"OUTPUT"_s, context );
259 const QColor textColor = parameterAsColor( parameters, u
"TEXT_COLOR"_s, context );
260 const QColor backgroundColor = parameterAsColor( parameters, u
"BACKGROUND_COLOR"_s, context );
261 const QColor borderColor = parameterAsColor( parameters, u
"BORDER_COLOR"_s, context );
263 QgsAlgorithmElevationProfilePlotItem plotItem( width, height, dpi );
265 const QString textFontFamily = parameterAsString( parameters, u
"TEXT_FONT_FAMILY"_s, context );
266 const QString textFontStyle = parameterAsString( parameters, u
"TEXT_FONT_STYLE"_s, context );
267 const double textFontSize = parameterAsDouble( parameters, u
"TEXT_FONT_SIZE"_s, context );
269 if ( !textFontFamily.isEmpty() || !textFontStyle.isEmpty() || textFontSize > 0 )
272 QFont font = textFormat.
font();
273 if ( !textFontFamily.isEmpty() )
277 if ( !textFontStyle.isEmpty() )
282 if ( textFontSize > 0 )
284 textFormat.
setSize( textFontSize );
288 plotItem.xAxis().setTextFormat( textFormat );
289 plotItem.yAxis().setTextFormat( textFormat );
292 if ( textColor.isValid() )
296 plotItem.xAxis().setTextFormat( textFormat );
297 textFormat = plotItem.yAxis().textFormat();
299 plotItem.yAxis().setTextFormat( textFormat );
302 if ( borderColor.isValid() )
304 auto lineSymbolLayer = std::make_unique<QgsSimpleLineSymbolLayer>( borderColor, 0.1 );
305 lineSymbolLayer->setPenCapStyle( Qt::FlatCap );
313 if ( backgroundColor.isValid() )
315 auto fillSymbolLayer = std::make_unique<QgsSimpleFillSymbolLayer>( backgroundColor, Qt::SolidPattern, backgroundColor );
320 generationContext.
setDpi( dpi );
321 generationContext.
setMaximumErrorMapUnits( MAX_ERROR_PIXELS * ( curveGeom.constGet()->length() ) / plotItem.plotArea().width() );
324 mRenderer->setContext( generationContext );
326 mRenderer->startGeneration();
327 mRenderer->waitForFinished();
341 zMinimum = zRange.
lower() - 5;
342 zMaximum = zRange.
lower() + 5;
347 const double margin = ( zRange.
upper() - zRange.
lower() ) * 0.05;
348 zMinimum = zRange.
lower() - margin;
349 zMaximum = zRange.
upper() + margin;
352 plotItem.setYMinimum( hasMinimumElevation ? minimumElevation : zMinimum );
353 plotItem.setYMaximum( hasMaximumElevation ? maximumElevation : zMaximum );
354 plotItem.setXMinimum( hasMinimumDistance ? minimumDistance : 0 );
355 plotItem.setXMaximum( hasMaximumDistance ? maximumDistance : curveGeom.constGet()->length() );
357 plotItem.setRenderer( mRenderer.get() );
359 QImage image(
static_cast<int>( plotItem.size().width() ),
static_cast<int>( plotItem.size().height() ), QImage::Format_ARGB32_Premultiplied );
360 image.fill( Qt::transparent );
362 QPainter painter( &image );
363 painter.setRenderHint( QPainter::Antialiasing,
true );
368 plotItem.calculateOptimisedIntervals( renderContext, plotContext );
369 plotItem.render( renderContext, plotContext );
371 image.save( outputImage );
374 outputs.insert( u
"OUTPUT"_s, outputImage );
@ MapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer).
@ Points
Points (e.g., for font sizes).
@ Hidden
Parameter is hidden and should not be shown to users.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ Double
Double/float values.
virtual void renderContent(QgsRenderContext &context, QgsPlotRenderContext &plotContext, const QRectF &plotArea, const QgsPlotData &plotData=QgsPlotData())
Renders the plot content.
void setSize(QSizeF size)
Sets the overall size of the plot (including titles and over components which sit outside the plot ar...
Base class for 2-dimensional plot/chart/graphs with an X and Y axes.
double yMaximum() const
Returns the maximum value of the y axis.
void setYMinimum(double minimum)
Sets the minimum value of the y axis.
void calculateOptimisedIntervals(QgsRenderContext &context, QgsPlotRenderContext &plotContext)
Automatically sets the grid and label intervals to optimal values for display in the given render con...
double yMinimum() const
Returns the minimum value of the y axis.
QRectF interiorPlotArea(QgsRenderContext &context, QgsPlotRenderContext &plotContext, const QgsPlotData &plotData=QgsPlotData()) const override
Returns the area of the plot which corresponds to the actual plot content (excluding all titles and o...
void setYMaximum(double maximum)
Sets the maximum value of the y axis.
double xMaximum() const
Returns the maximum value of the x axis.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
Interface for classes which can generate elevation profiles.
Represents a coordinate reference system (CRS).
Abstract base class for curved geometry type.
QgsRange which stores a range of double values.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
A line symbol type, for rendering LineString and MultiLineString geometries.
Base class for all map layer types.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Contains information about the context of a plot rendering operation.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Base class for providing feedback from a processing algorithm.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
A geometry parameter for processing algorithms.
A map layer parameter for processing algorithms.
A parameter for processing algorithms which accepts multiple map layers.
A numeric parameter for processing algorithms.
static QString supportedImageFileFilters()
Returns a file filter string of all supported image formats, suitable for use in file picker dialogs.
Encapsulates the context in which an elevation profile is to be generated.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the profie, to be used in size conversions.
void setMaximumErrorMapUnits(double error)
Sets the maximum allowed error in the generated result, in profile curve map units.
void setMapUnitsPerDistancePixel(double units)
Sets the number of map units per pixel in the distance dimension.
Encapsulates properties and constraints relating to fetching elevation profiles from different source...
T lower() const
Returns the lower bound of the range.
T upper() const
Returns the upper bound of the range.
Represents a raster layer.
Contains information about the context of a rendering operation.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
QFont font() const
Returns the font used for rendering text.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsSymbolLayer * > QgsSymbolLayerList