33using namespace Qt::StringLiterals;
39 QString expression =
properties.value( u
"geometryModifier"_s ).toString();
40 if ( expression.isEmpty() )
42 expression = u
"@geometry"_s;
44 QgsGeometryGeneratorSymbolLayer *symbolLayer =
new QgsGeometryGeneratorSymbolLayer( expression );
46 if (
properties.value( u
"SymbolType"_s ) ==
"Marker"_L1 )
50 else if (
properties.value( u
"SymbolType"_s ) ==
"Line"_L1 )
65QgsGeometryGeneratorSymbolLayer::QgsGeometryGeneratorSymbolLayer(
const QString &expression )
72 return u
"GeometryGenerator"_s;
81 mSymbol = mFillSymbol.get();
87 mSymbol = mLineSymbol.get();
93 mSymbol = mMarkerSymbol.get();
121 mRenderingFeature =
true;
122 mHasRenderedFeature =
false;
127 mRenderingFeature =
false;
133 return mFillSymbol->usesMapUnits();
134 else if ( mLineSymbol )
135 return mLineSymbol->usesMapUnits();
136 else if ( mMarkerSymbol )
137 return mMarkerSymbol->usesMapUnits();
144 return mFillSymbol->color();
145 else if ( mLineSymbol )
146 return mLineSymbol->color();
147 else if ( mMarkerSymbol )
148 return mMarkerSymbol->color();
155 return mFillSymbol->outputUnit();
156 else if ( mLineSymbol )
157 return mLineSymbol->outputUnit();
158 else if ( mMarkerSymbol )
159 return mMarkerSymbol->outputUnit();
166 mFillSymbol->setOutputUnit( unit );
167 else if ( mLineSymbol )
168 mLineSymbol->setOutputUnit( unit );
169 else if ( mMarkerSymbol )
170 mMarkerSymbol->setOutputUnit( unit );
176 return mFillSymbol->mapUnitScale();
177 else if ( mLineSymbol )
178 return mLineSymbol->mapUnitScale();
179 else if ( mMarkerSymbol )
180 return mMarkerSymbol->mapUnitScale();
195 QgsGeometryGeneratorSymbolLayer *
clone =
new QgsGeometryGeneratorSymbolLayer( mExpression->expression() );
198 clone->mFillSymbol.reset( mFillSymbol->clone() );
200 clone->mLineSymbol.reset( mLineSymbol->clone() );
202 clone->mMarkerSymbol.reset( mMarkerSymbol->clone() );
204 clone->setSymbolType( mSymbolType );
205 clone->setUnits( mUnits );
215 props.insert( u
"geometryModifier"_s, mExpression->expression() );
216 switch ( mSymbolType )
219 props.insert( u
"SymbolType"_s, u
"Marker"_s );
222 props.insert( u
"SymbolType"_s, u
"Line"_s );
225 props.insert( u
"SymbolType"_s, u
"Fill"_s );
244 if ( patchShapeGeometry.
isEmpty() )
260 originalSymbolType = mSymbol->type();
274 QgsLegendPatchShape evaluatedPatchShape( mSymbol->type(), coerceToExpectedType( iconGeometry ) );
284 mExpression = std::make_unique<QgsExpression>( exp );
289 return mExpression->expression();
294 switch ( symbol->
type() )
341 const QTransform painterToTargetUnits = QTransform::fromScale( scale, scale );
342 drawGeometry.transform( painterToTargetUnits );
350 QVariant value = mExpression->evaluate( &expressionContext );
351 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, mExpression.get() );
354 geom.
transform( painterToTargetUnits.inverted() );
361 switch ( mSymbolType )
367 if ( !geoms.empty() )
368 return geoms.at( 0 );
375 if ( !geoms.empty() )
376 return geoms.at( 0 );
383 if ( !geoms.empty() )
384 return geoms.at( 0 );
395 if ( mRenderingFeature && mHasRenderedFeature )
410 switch ( geometryType )
414 Q_ASSERT( points->size() == 1 );
428 auto polygon = std::make_unique< QgsPolygon >();
429 polygon->setExteriorRing( exterior.release() );
432 for (
const QPolygonF &ring : *rings )
435 polygon->addInteriorRing( fromRing.release() );
438 drawGeometry =
QgsGeometry( std::move( polygon ) );
454 result.
transform( mapToPixel.inverted() );
462 QgsDebugError( u
"Could no transform generated geometry to layer CRS"_s );
476 QVariant value = mExpression->evaluate( &expressionContext );
477 f.
setGeometry( coerceToExpectedType( QgsExpressionUtils::getGeometry( value, mExpression.get() ) ) );
495 QgsDebugError( u
"Could no transform generated geometry to layer CRS"_s );
505 result.
transform( mapToPixel.inverted() );
513 QgsDebugError( u
"Could no transform generated geometry to layer CRS"_s );
529 mSymbol->renderFeature( f, context.
renderContext(), -1, useSelectedColor );
533 if ( mRenderingFeature )
534 mHasRenderedFeature =
true;
539 mSymbol->setColor(
color );
Provides global constants and enumerations for use throughout the application.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes).
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ MultiPolygon
MultiPolygon.
@ MultiLineString
MultiLineString.
@ Reverse
Reverse/inverse transform (from destination to source).
Custom exception class for Coordinate Reference System related exceptions.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setGeometry(const QgsGeometry &geometry)
Convenience function for setting a geometry for the scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
Handles parsing and evaluation of expressions (formerly called "search strings").
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static std::unique_ptr< QgsFillSymbol > createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsMapUnitScale mapUnitScale() const override
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QString geometryExpression() const
Gets the expression to generate this geometry.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void setUnits(Qgis::RenderUnit units)
Sets the units for the geometry expression.
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
bool rendersIdenticallyTo(const QgsSymbolLayer *other) const override
Returns true if this symbol layer will always render identically to an other symbol layer.
void setSymbolType(Qgis::SymbolType symbolType)
Set the type of symbol which should be created.
QString layerType() const override
Returns a string that represents this layer type.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
bool isCompatibleWithSymbol(QgsSymbol *symbol) const override
Will always return true.
Qgis::SymbolType symbolType() const
Access the symbol type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
~QgsGeometryGeneratorSymbolLayer() override
static QgsSymbolLayer * create(const QVariantMap &properties)
Creates the symbol layer.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
QgsSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void render(QgsSymbolRenderContext &context, Qgis::GeometryType geometryType=Qgis::GeometryType::Unknown, const QPolygonF *points=nullptr, const QVector< QPolygonF > *rings=nullptr)
Will render this symbol layer using the context.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
QVector< QgsGeometry > coerceToType(Qgis::WkbType type, double defaultZ=0, double defaultM=0, bool avoidDuplicates=true) const
Attempts to coerce this geometry into the specified destination type.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Represents a patch shape for use in map legends.
QgsGeometry scaledGeometry(QSizeF size) const
Returns the patch shape's geometry, scaled to the given size.
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
void setScaleToOutputSize(bool scale)
Sets whether the patch shape should by resized to the desired target size when rendering.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
A line symbol type, for rendering LineString and MultiLineString geometries.
static std::unique_ptr< QgsLineSymbol > createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
Struct for storing maximum and minimum scales for measurements in map units.
A marker symbol type, for rendering Point and MultiPoint geometries.
static std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
QgsLegendPatchShape defaultPatch(Qgis::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Abstract base class for symbol layers.
void copyCommonProperties(QgsSymbolLayer *destLayer) const
Copies all common base class properties from this layer to another symbol layer.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
QgsSymbolLayer(const QgsSymbolLayer &other)
Encapsulates the context in which a symbol is being rendered.
const QgsFeature * feature() const
Returns the current feature being rendered.
Qgis::GeometryType originalGeometryType() const
Returns the geometry type for the original feature geometry being rendered.
QgsFields fields() const
Fields of the layer.
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
void setRenderHints(Qgis::SymbolRenderHints hints)
Sets rendering hint flags for the symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
#define QgsDebugError(str)