40using namespace Qt::StringLiterals;
55 renderer->mSourceMode = mSourceMode;
56 renderer->mXBand = mXBand;
57 renderer->mYBand = mYBand;
58 renderer->mDirectionBand = mDirectionBand;
59 renderer->mDirectionEncoding = mDirectionEncoding;
60 renderer->mSettings = mSettings;
61 renderer->mMinimumMagnitude = mMinimumMagnitude;
62 renderer->mMaximumMagnitude = mMaximumMagnitude;
76 auto renderer = std::make_unique<QgsRasterVectorFieldRenderer>(
input );
77 renderer->readXml( elem );
80 renderer->setXBand( elem.attribute( u
"x-band"_s, u
"-1"_s ).toInt() );
81 renderer->setYBand( elem.attribute( u
"y-band"_s, u
"-1"_s ).toInt() );
82 renderer->setDirectionBand( elem.attribute( u
"direction-band"_s, u
"-1"_s ).toInt() );
85 if ( elem.hasAttribute( u
"minimum-magnitude"_s ) )
86 renderer->setMinimumMagnitude( elem.attribute( u
"minimum-magnitude"_s ).toDouble() );
87 if ( elem.hasAttribute( u
"maximum-magnitude"_s ) )
88 renderer->setMaximumMagnitude( elem.attribute( u
"maximum-magnitude"_s ).toDouble() );
90 const QDomElement settingsElem = elem.firstChildElement( u
"vector-settings"_s );
91 if ( !settingsElem.isNull() )
103 if ( parentElem.isNull() )
106 QDomElement rasterRendererElem = doc.createElement( u
"rasterrenderer"_s );
109 rasterRendererElem.setAttribute( u
"source-mode"_s,
qgsEnumValueToKey( mSourceMode ) );
110 rasterRendererElem.setAttribute( u
"x-band"_s, mXBand );
111 rasterRendererElem.setAttribute( u
"y-band"_s, mYBand );
112 rasterRendererElem.setAttribute( u
"direction-band"_s, mDirectionBand );
113 rasterRendererElem.setAttribute( u
"direction-encoding"_s,
qgsEnumValueToKey( mDirectionEncoding ) );
114 if ( !std::isnan( mMinimumMagnitude ) )
115 rasterRendererElem.setAttribute( u
"minimum-magnitude"_s,
qgsDoubleToString( mMinimumMagnitude ) );
116 if ( !std::isnan( mMaximumMagnitude ) )
117 rasterRendererElem.setAttribute( u
"maximum-magnitude"_s,
qgsDoubleToString( mMaximumMagnitude ) );
120 parentElem.appendChild( rasterRendererElem );
123bool QgsRasterVectorFieldRenderer::shouldAcceptBand(
int band )
const
131 if ( !shouldAcceptBand( band ) )
140 if ( !shouldAcceptBand( band ) )
149 if ( !shouldAcceptBand( band ) )
152 mDirectionBand = band;
159 switch ( mSourceMode )
169 if ( mDirectionBand > 0 )
170 bands << mDirectionBand;
178 QList<QPair<QString, QColor>> items;
180 switch ( mSettings.coloringMethod() )
183 items << qMakePair( QString(), mSettings.color() );
188 const QList<QgsColorRampShader::ColorRampItem> rampItems = mSettings.colorRampShader().colorRampItemList();
189 items.reserve( rampItems.size() );
191 items << qMakePair( rampItem.label, rampItem.color );
220 const int sourceWidth = input->
xSize();
221 const int sourceHeight = input->
ySize();
222 if ( sourceWidth <= 0 || sourceHeight <= 0 || sourceExtent.
isEmpty() )
225 const double xResolution = sourceExtent.
width() / sourceWidth;
226 const double yResolution = sourceExtent.
height() / sourceHeight;
229 const double firstColumn = std::floor( ( extent.
xMinimum() - sourceExtent.
xMinimum() ) / xResolution );
230 const double lastColumn = std::ceil( ( extent.
xMaximum() - sourceExtent.
xMinimum() ) / xResolution );
231 const double firstRow = std::floor( ( sourceExtent.
yMaximum() - extent.
yMaximum() ) / yResolution );
232 const double lastRow = std::ceil( ( sourceExtent.
yMaximum() - extent.
yMinimum() ) / yResolution );
234 const qint64 columns = std::max<qint64>( 1,
static_cast<qint64
>( lastColumn - firstColumn ) );
235 const qint64 rows = std::max<qint64>( 1,
static_cast<qint64
>( lastRow - firstRow ) );
239 step = std::max( step, ( columns + 2 * width - 1 ) / ( 2 * width ) );
240 step = std::max( step, ( rows + 2 * height - 1 ) / ( 2 * height ) );
244 grid.
columns =
static_cast<int>( ( columns + step - 1 ) / step );
245 grid.
rows =
static_cast<int>( ( rows + step - 1 ) / step );
247 sourceExtent.
xMinimum() + firstColumn * xResolution,
248 sourceExtent.
yMaximum() - ( firstRow +
static_cast<double>( grid.
rows ) * step ) * yResolution,
249 sourceExtent.
xMinimum() + ( firstColumn +
static_cast<double>( grid.
columns ) * step ) * xResolution,
250 sourceExtent.
yMaximum() - firstRow * yResolution
269 return QSizeF( 1.0, 1.0 );
272 if ( mapUnitsPerPixel <= 0 )
273 return QSizeF( 1.0, 1.0 );
285 nextColumn = transform.
transform( nextColumn );
286 nextRow = transform.
transform( nextRow );
291 QgsDebugError( u
"Could not transform the block extent to the map CRS"_s );
292 return QSizeF( 1.0, 1.0 );
295 const auto ratio = [mapUnitsPerPixel](
double blockPixelSizeInMapUnits ) {
296 if ( !std::isfinite( blockPixelSizeInMapUnits ) || blockPixelSizeInMapUnits <= 0 )
298 return std::clamp( mapUnitsPerPixel / blockPixelSizeInMapUnits, 0.05, 20.0 );
301 return QSizeF( ratio( center.
distance( nextColumn ) ), ratio( center.
distance( nextRow ) ) );
310 minimum = std::numeric_limits<double>::max();
311 maximum = std::numeric_limits<double>::lowest();
314 const int rows = std::min( xValues->
height(), yValues->
height() );
315 const int columns = std::min( xValues->
width(), yValues->
width() );
316 for (
int row = 0; row < rows; ++row )
318 for (
int column = 0; column < columns; ++column )
320 bool isNoData =
false;
321 const double x = xValues->
valueAndNoData( row, column, isNoData );
322 if ( isNoData || std::isnan( x ) )
325 const double y = yValues->
valueAndNoData( row, column, isNoData );
326 if ( isNoData || std::isnan( y ) )
329 const double magnitude = std::hypot( x, y );
330 minimum = std::min( minimum, magnitude );
331 maximum = std::max( maximum, magnitude );
343 auto outputBlock = std::make_unique<QgsRasterBlock>();
344 if ( !
mInput || width <= 0 || height <= 0 ||
extent.isEmpty() )
345 return outputBlock.release();
348 switch ( mSourceMode )
351 if ( mXBand <= 0 || mYBand <= 0 )
352 return outputBlock.release();
356 if ( mDirectionBand <= 0 )
357 return outputBlock.release();
367 std::shared_ptr<const QgsRasterBlock> xValues;
368 std::shared_ptr<const QgsRasterBlock> yValues;
369 std::shared_ptr<const QgsRasterBlock> directionValues;
374 switch ( mSourceMode )
380 if ( !xValues || !yValues || xValues->isEmpty() || yValues->isEmpty() )
383 return outputBlock.release();
388 double dataMinimum = 0;
389 double dataMaximum = 0;
390 if ( !calculateMagnitudeRange( xValues.get(), yValues.get(), dataMinimum, dataMaximum ) )
391 return outputBlock.release();
405 if ( resamplingWasEnabled )
410 if ( resamplingWasEnabled )
413 if ( !directionValues || directionValues->isEmpty() )
416 return outputBlock.release();
426 QImage image( width, height, QImage::Format_ARGB32_Premultiplied );
427 if ( image.isNull() )
428 return outputBlock.release();
429 image.fill( Qt::transparent );
434 QPainter painter( &image );
435 painter.setRenderHint( QPainter::Antialiasing,
true );
448 const QSizeF blockPixelsPerMapPixel = hasMapContext ? calculateBlockPixelsPerMapPixel( mapContext,
extent, width, height ) : QSizeF( 1.0, 1.0 );
460 context.
setScaleFactor( mapContext.
scaleFactor() * std::sqrt( blockPixelsPerMapPixel.width() * blockPixelsPerMapPixel.height() ) );
490 settings.setUserGridCellWidth( std::max( 1,
static_cast<int>( std::round(
settings.userGridCellWidth() * blockPixelsPerMapPixel.width() ) ) ) );
491 settings.setUserGridCellHeight( std::max( 1,
static_cast<int>( std::round(
settings.userGridCellHeight() * blockPixelsPerMapPixel.height() ) ) ) );
495 std::unique_ptr<QgsVectorFieldValueSource> source;
496 switch ( mSourceMode )
499 source = std::make_unique<QgsRasterVectorFieldValueSource>( xValues, yValues, grid.
extent, dataExtent,
maximumMagnitude );
503 source = std::make_unique<QgsRasterVectorFieldEncodedDirectionValueSource>( directionValues, mDirectionEncoding, grid.
extent, dataExtent );
528 outputBlock->setImage( &image );
529 return outputBlock.release();
@ WindBarbs
Displaying vector dataset with wind barbs.
@ Arrows
Displaying vector dataset with arrows.
@ Traces
Displaying vector dataset with particle traces.
@ Streamlines
Displaying vector dataset with streamlines.
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
@ CartesianComponents
Two bands holding the x and y components of the vectors.
@ EncodedDirection
A single band holding integer coded compass directions, see Qgis::RasterDirectionEncoding.
@ UseNoDataForOutOfRangePixels
Out of range pixels (eg those values outside of the rendered map's z range filter) should be set usin...
@ Antialiasing
Use antialiasing while drawing.
@ Esri
Esri: 1=E, 2=SE, 4=S, 8=SW, 16=W, 32=NW, 64=N, 128=NE.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
Custom exception class for Coordinate Reference System related exceptions.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
@ ColorRamp
Render with a color ramp.
@ SingleColor
Render with a single color.
Perform transforms between map coordinates and device coordinates.
bool isValid() const
Returns true if the object is valid (i.e.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
Feedback object tailored for raster block reading.
QgsRenderContext renderContext() const
Returns the render context of the associated block reading.
int height() const
Returns the height (number of rows) of the raster block.
double valueAndNoData(int row, int column, bool &isNoData) const
Reads a single value from the pixel at row and column, if type of block is numeric.
int width() const
Returns the width (number of columns) of the raster block.
Base class for raster data providers.
bool isProviderResamplingEnabled() const
Returns whether provider-level resampling is enabled.
virtual bool enableProviderResampling(bool enable)
Enable or disable provider-level resampling.
QgsRectangle extent() const override=0
Returns the extent of the layer.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual int xSize() const
Gets raster size.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
virtual int bandCount() const =0
Gets number of bands.
QgsRasterInterface * mInput
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type=QString())
Constructor for QgsRasterRenderer.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses).
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
bool setXBand(int band)
Attempts to set the band which holds the x component of the vectors.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
Qgis::RasterRendererFlags flags() const override
Returns flags which dictate renderer behavior.
QgsRasterVectorFieldRenderer(QgsRasterInterface *input)
Creates a vector field renderer.
bool setDirectionBand(int band)
Attempts to set the band which holds the coded compass directions.
bool setYBand(int band)
Attempts to set the band which holds the y component of the vectors.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
QList< QPair< QString, QColor > > legendSymbologyItems() const override
Returns symbology items if provided by renderer.
double maximumMagnitude() const
Returns the magnitude the symbology treats as the largest one of the raster.
QgsRasterVectorFieldRenderer * clone() const override
Clone itself, create deep copy.
~QgsRasterVectorFieldRenderer() override
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
static std::unique_ptr< QgsRasterRenderer > create(const QDomElement &elem, QgsRasterInterface *input)
Creates an instance of the renderer based on definition from XML (used by renderer registry).
double minimumMagnitude() const
Returns the magnitude the symbology treats as the smallest one of the raster.
QgsVectorFieldSettings settings() const
Returns the settings used to render the vector field.
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
void setMapExtent(const QgsRectangle &extent)
Sets the original extent of the map being rendered.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setDistanceArea(const QgsDistanceArea &distanceArea)
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
double symbologyReferenceScale() const
Returns the symbology reference scale.
double rendererScale() const
Returns the renderer map scale.
QgsCoordinateTransformContext transformContext() const
Returns the context's coordinate transform context, which stores various information regarding which ...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly during rendering to check if rendering should ...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setSymbologyReferenceScale(double scale)
Sets the symbology reference scale.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the context's coordinate transform context, which stores various information regarding which dat...
void setFlags(Qgis::RenderContextFlags flags)
Set combination of flags that will be used for rendering.
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
void setRendererScale(double scale)
Sets the renderer map scale.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
Responsible for rendering vector field data.
void drawStreamlines(std::unique_ptr< QgsVectorFieldValueSource > source, QgsRasterBlockFeedback *feedback=nullptr)
Integrates and draws streamlines over the whole rendered extent, sampling the vector field from sourc...
void drawGlyphs(std::unique_ptr< QgsVectorFieldValueSource > source, const QgsPointXY &anchor, QgsFeedback *feedback=nullptr)
Draws one glyph per position of the placement grid described by the settings the engine was construct...
void drawTraces(std::unique_ptr< QgsVectorFieldValueSource > source)
Seeds particles over the whole rendered extent, moves them one time step and draws their traces,...
Represents a renderer settings for vector datasets.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
#define QgsDebugError(str)
constexpr qint64 VECTOR_FIELD_MAXIMUM_SAMPLES
Upper bound on the number of vector values read from the two bands for a single block.
The extent and size at which the two component bands are read for one block.