void QgsVectorFieldSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext& context ) { if ( !mLineSymbol ) { return; } const QgsRenderContext& ctx = context.renderContext(); const QgsFeature* f = context.feature(); if ( !f ) { //preview QPolygonF line; line << QPointF( 0, 50 ); line << QPointF( 100, 50 ); mLineSymbol->renderPolyline( line, nullptr, context.renderContext() ); } double xComponent = 0; double yComponent = 0; double xVal = 0; if ( f && mXIndex != -1 ) { xVal = f->attribute( mXIndex ).toDouble(); } double yVal = 0; if ( f && mYIndex != -1 ) { yVal = f->attribute( mYIndex ).toDouble(); } switch ( mVectorFieldType ) { case Cartesian: xComponent = QgsSymbolLayerUtils::convertToPainterUnits( ctx, xVal, mDistanceUnit, mDistanceMapUnitScale ); yComponent = QgsSymbolLayerUtils::convertToPainterUnits( ctx, yVal, mDistanceUnit, mDistanceMapUnitScale ); break; case Polar: convertPolarToCartesian( xVal, yVal, xComponent, yComponent ); xComponent = QgsSymbolLayerUtils::convertToPainterUnits( ctx, xComponent, mDistanceUnit, mDistanceMapUnitScale ); yComponent = QgsSymbolLayerUtils::convertToPainterUnits( ctx, yComponent, mDistanceUnit, mDistanceMapUnitScale ); break; case Height: xComponent = 0; yComponent = QgsSymbolLayerUtils::convertToPainterUnits( ctx, yVal, mDistanceUnit, mDistanceMapUnitScale ); break; default: break; } xComponent *= mScale; yComponent *= mScale; QPolygonF line; line << point; line << QPointF( point.x() + xComponent, point.y() - yComponent ); mLineSymbol->renderPolyline( line, f, context.renderContext() ); }
QVariant QgsSymbolLayer::evaluateDataDefinedProperty( const QString& property, const QgsSymbolRenderContext& context, const QVariant& defaultVal, bool* ok ) const { if ( ok ) *ok = false; QgsDataDefined* dd = getDataDefinedProperty( property ); if ( !dd || !dd->isActive() ) return defaultVal; if ( dd->useExpression() ) { if ( dd->expression() ) { QVariant result = dd->expression()->evaluate( &context.renderContext().expressionContext() ); if ( result.isValid() ) { if ( ok ) *ok = true; return result; } else return defaultVal; } else { return defaultVal; } } else if ( context.feature() && !dd->field().isEmpty() && !mFields.isEmpty() ) { int attributeIndex = mFields.lookupField( dd->field() ); if ( attributeIndex >= 0 ) { if ( ok ) *ok = true; return context.feature()->attribute( attributeIndex ); } } return defaultVal; }
void QgsEllipseSymbolLayer::startRender( QgsSymbolRenderContext &context ) { QgsMarkerSymbolLayer::startRender( context ); // get anchor point expressions if ( !context.feature() || !dataDefinedProperties().hasActiveProperties() ) { preparePath( mSymbolName, context ); } mPen.setColor( mStrokeColor ); mPen.setStyle( mStrokeStyle ); mPen.setJoinStyle( mPenJoinStyle ); mPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) ); mBrush.setColor( mColor ); }
void QgsEllipseSymbolLayer::calculateOffsetAndRotation( QgsSymbolRenderContext &context, double scaledWidth, double scaledHeight, bool &hasDataDefinedRotation, QPointF &offset, double &angle ) const { double offsetX = 0; double offsetY = 0; markerOffset( context, scaledWidth, scaledHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY, mSymbolWidthMapUnitScale, mSymbolHeightMapUnitScale ); offset = QPointF( offsetX, offsetY ); //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle) bool ok = true; angle = mAngle + mLineAngle; bool usingDataDefinedRotation = false; if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyAngle ) ) { context.setOriginalValueVariable( angle ); angle = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyAngle, context.renderContext().expressionContext(), 0 ) + mLineAngle; usingDataDefinedRotation = ok; } hasDataDefinedRotation = context.renderHints() & QgsSymbol::DynamicRotation || usingDataDefinedRotation; if ( hasDataDefinedRotation ) { // For non-point markers, "dataDefinedRotation" means following the // shape (shape-data defined). For them, "field-data defined" does // not work at all. TODO: if "field-data defined" ever gets implemented // we'll need a way to distinguish here between the two, possibly // using another flag in renderHints() const QgsFeature *f = context.feature(); if ( f ) { const QgsGeometry g = f->geometry(); if ( !g.isNull() && g.type() == QgsWkbTypes::PointGeometry ) { const QgsMapToPixel &m2p = context.renderContext().mapToPixel(); angle += m2p.mapRotation(); } } } if ( angle ) offset = _rotatedOffset( offset, angle ); }
void QgsEllipseSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext &context ) { double scaledWidth = mSymbolWidth; double scaledHeight = mSymbolHeight; if ( mDataDefinedProperties.hasActiveProperties() ) { bool ok; context.setOriginalValueVariable( mStrokeWidth ); QVariant exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { double width = exprVal.toDouble( &ok ); if ( ok ) { width = context.renderContext().convertToPainterUnits( width, mStrokeWidthUnit, mStrokeWidthMapUnitScale ); mPen.setWidthF( width ); } } context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePenStyle( mStrokeStyle ) ); exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyStrokeStyle, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { mPen.setStyle( QgsSymbolLayerUtils::decodePenStyle( exprVal.toString() ) ); } context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePenJoinStyle( mPenJoinStyle ) ); exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyJoinStyle, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { mPen.setJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( exprVal.toString() ) ); } context.setOriginalValueVariable( QgsSymbolLayerUtils::encodeColor( mColor ) ); mBrush.setColor( mDataDefinedProperties.valueAsColor( QgsSymbolLayer::PropertyFillColor, context.renderContext().expressionContext(), mColor ) ); context.setOriginalValueVariable( QgsSymbolLayerUtils::encodeColor( mStrokeColor ) ); mPen.setColor( mDataDefinedProperties.valueAsColor( QgsSymbolLayer::PropertyStrokeColor, context.renderContext().expressionContext(), mStrokeColor ) ); if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyWidth ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyHeight ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyName ) ) { QString symbolName = mSymbolName; context.setOriginalValueVariable( mSymbolName ); exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyName, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { symbolName = exprVal.toString(); } preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() ); } } //offset and rotation bool hasDataDefinedRotation = false; QPointF offset; double angle = 0; calculateOffsetAndRotation( context, scaledWidth, scaledHeight, hasDataDefinedRotation, offset, angle ); QPainter *p = context.renderContext().painter(); if ( !p ) { return; } QMatrix transform; transform.translate( point.x() + offset.x(), point.y() + offset.y() ); if ( !qgsDoubleNear( angle, 0.0 ) ) { transform.rotate( angle ); } p->setPen( mPen ); p->setBrush( mBrush ); p->drawPath( transform.map( mPainterPath ) ); }