QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource( source, ownSource, request ) , mEditGeometrySimplifier( 0 ) { // prepare joins: may add more attributes to fetch (in order to allow join) if ( mSource->mJoinBuffer->containsJoins() ) prepareJoins(); prepareExpressions(); // by default provider's request is the same mProviderRequest = mRequest; if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // prepare list of attributes to match provider fields QgsAttributeList providerSubset; QgsAttributeList subset = mProviderRequest.subsetOfAttributes(); int nPendingFields = mSource->mFields.count(); for ( int i = 0; i < subset.count(); ++i ) { int attrIndex = subset[i]; if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue; if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider ) providerSubset << mSource->mFields.fieldOriginIndex( attrIndex ); } mProviderRequest.setSubsetOfAttributes( providerSubset ); } if ( mSource->mHasEditBuffer ) { mChangedFeaturesRequest = mProviderRequest; mChangedFeaturesRequest.setFilterFids( mSource->mChangedAttributeValues.keys().toSet() ); } if ( request.filterType() == QgsFeatureRequest::FilterFid ) { mFetchedFid = false; } else // no filter or filter by rect { if ( mSource->mHasEditBuffer ) { mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest ); } else { mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest ); } rewindEditBuffer(); } if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression ) { mRequest.filterExpression()->prepare( mSource->mFields ); } }
void QgsEllipseSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { if ( !context.feature() || !hasDataDefinedProperty() ) { preparePath( mSymbolName, context ); } mPen.setColor( mOutlineColor ); mPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ) ); mBrush.setColor( mFillColor ); prepareExpressions( context.layer(), context.renderContext().rendererScale() ); }
void QgsEllipseSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QgsMarkerSymbolLayerV2::startRender( context ); // get anchor point expressions if ( !context.feature() || !hasDataDefinedProperties() ) { preparePath( mSymbolName, context ); } mPen.setColor( mOutlineColor ); mPen.setStyle( mOutlineStyle ); mPen.setWidthF( QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), mOutlineWidth, mOutlineWidthUnit, mOutlineWidthMapUnitScale ) ); mBrush.setColor( mFillColor ); prepareExpressions( context ); }
void QgsMarkerLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { mMarker->setAlpha( context.alpha() ); // if being rotated, it gets initialized with every line segment int hints = 0; if ( mRotateMarker ) hints |= QgsSymbolV2::DataDefinedRotation; if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) hints |= QgsSymbolV2::DataDefinedSizeScale; mMarker->setRenderHints( hints ); mMarker->startRender( context.renderContext(), context.fields() ); //prepare expressions for data defined properties prepareExpressions( context.fields(), context.renderContext().rendererScale() ); }
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( mColor.alphaF() * context.alpha() ); mPen.setColor( penColor ); double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale ); mPen.setWidthF( scaledWidth ); if ( mUseCustomDashPattern && scaledWidth != 0 ) { mPen.setStyle( Qt::CustomDashLine ); //scale pattern vector double dashWidthDiv = scaledWidth; //fix dash pattern width in Qt 4.8 QStringList versionSplit = QString( qVersion() ).split( "." ); if ( versionSplit.size() > 1 && versionSplit.at( 1 ).toInt() >= 8 && ( scaledWidth * context.renderContext().rasterScaleFactor() ) < 1.0 ) { dashWidthDiv = 1.0; } QVector<qreal> scaledVector; QVector<qreal>::const_iterator it = mCustomDashVector.constBegin(); for ( ; it != mCustomDashVector.constEnd(); ++it ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << ( *it ) * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv; } mPen.setDashPattern( scaledVector ); } else { mPen.setStyle( mPenStyle ); } mPen.setJoinStyle( mPenJoinStyle ); mPen.setCapStyle( mPenCapStyle ); mSelPen = mPen; QColor selColor = context.renderContext().selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setColor( selColor ); //prepare expressions for data defined properties prepareExpressions( context.fields(), context.renderContext().rendererScale() ); }
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource>( source, ownSource, request ) , mFetchedFid( false ) , mEditGeometrySimplifier( 0 ) { prepareExpressions(); // prepare joins: may add more attributes to fetch (in order to allow join) if ( mSource->mJoinBuffer->containsJoins() ) prepareJoins(); mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty(); // by default provider's request is the same mProviderRequest = mRequest; if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // prepare list of attributes to match provider fields QgsAttributeList providerSubset; QgsAttributeList subset = mProviderRequest.subsetOfAttributes(); int nPendingFields = mSource->mFields.count(); for ( int i = 0; i < subset.count(); ++i ) { int attrIndex = subset[i]; if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue; if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider ) providerSubset << mSource->mFields.fieldOriginIndex( attrIndex ); } mProviderRequest.setSubsetOfAttributes( providerSubset ); } if ( mProviderRequest.filterType() == QgsFeatureRequest::FilterExpression ) { Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() ) { int idx = source->mFields.fieldNameIndex( field ); // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them. // In this case we disable the expression filter. if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider ) { mProviderRequest.disableFilter(); } } }
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource>( source, ownSource, request ) , mFetchedFid( false ) , mEditGeometrySimplifier( nullptr ) , mInterruptionChecker( nullptr ) { prepareExpressions(); // prepare joins: may add more attributes to fetch (in order to allow join) if ( mSource->mJoinBuffer->containsJoins() ) prepareJoins(); mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty(); // by default provider's request is the same mProviderRequest = mRequest; if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // prepare list of attributes to match provider fields QSet<int> providerSubset; QgsAttributeList subset = mProviderRequest.subsetOfAttributes(); int nPendingFields = mSource->mFields.count(); Q_FOREACH ( int attrIndex, subset ) { if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue; if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider ) providerSubset << mSource->mFields.fieldOriginIndex( attrIndex ); } // This is done in order to be prepared to do fallback order bys // and be sure we have the required columns. // TODO: // It would be nicer to first check if we can compile the order by // and only modify the subset if we cannot. if ( !mProviderRequest.orderBy().isEmpty() ) { Q_FOREACH ( const QString& attr, mProviderRequest.orderBy().usedAttributes() ) { providerSubset << mSource->mFields.fieldNameIndex( attr ); } }
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( mColor.alphaF() * context.alpha() ); mPen.setColor( penColor ); double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit ); mPen.setWidthF( scaledWidth ); if ( mUseCustomDashPattern && scaledWidth != 0 ) { mPen.setStyle( Qt::CustomDashLine ); //scale pattern vector QVector<qreal> scaledVector; QVector<qreal>::const_iterator it = mCustomDashVector.constBegin(); for ( ; it != mCustomDashVector.constEnd(); ++it ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << ( *it ) * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit ) / scaledWidth; } mPen.setDashPattern( scaledVector ); } else { mPen.setStyle( mPenStyle ); } mPen.setJoinStyle( mPenJoinStyle ); mPen.setCapStyle( mPenCapStyle ); mSelPen = mPen; QColor selColor = context.renderContext().selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setColor( selColor ); //prepare expressions for data defined properties prepareExpressions( context.layer() ); }
void QgsSvgMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { mOrigSize = mSize; // save in case the size would be data defined Q_UNUSED( context ); prepareExpressions( context.layer(), context.renderContext().rendererScale() ); }
void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor brushColor = mColor; QColor penColor = mBorderColor; brushColor.setAlphaF( mColor.alphaF() * context.alpha() ); penColor.setAlphaF( mBorderColor.alphaF() * context.alpha() ); mBrush = QBrush( brushColor ); mPen = QPen( penColor ); mPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ) ); QColor selBrushColor = context.renderContext().selectionColor(); QColor selPenColor = selBrushColor == mColor ? selBrushColor : mBorderColor; if ( context.alpha() < 1 ) { selBrushColor.setAlphaF( context.alpha() ); selPenColor.setAlphaF( context.alpha() ); } mSelBrush = QBrush( selBrushColor ); mSelPen = QPen( selPenColor ); mSelPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ) ); bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || dataDefinedProperty( "angle" ); bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || dataDefinedProperty( "size" ); // use caching only when: // - size, rotation, shape, color, border color is not data-defined // - drawing to screen (not printer) mUsingCache = !hasDataDefinedRotation && !hasDataDefinedSize && !context.renderContext().forceVectorOutput() && !dataDefinedProperty( "name" ) && !dataDefinedProperty( "color" ) && !dataDefinedProperty( "color_border" ) && !dataDefinedProperty( "outline_width" ) && !dataDefinedProperty( "size" ); // use either QPolygonF or QPainterPath for drawing // TODO: find out whether drawing directly doesn't bring overhead - if not, use it for all shapes if ( !prepareShape() ) // drawing as a polygon { if ( preparePath() ) // drawing as a painter path { // some markers can't be drawn as a polygon (circle, cross) // For these set the selected border color to the selected color if ( mName != "circle" ) mSelPen.setColor( selBrushColor ); } else { QgsDebugMsg( "unknown symbol" ); return; } } QMatrix transform; // scale the shape (if the size is not going to be modified) if ( !hasDataDefinedSize ) { double scaledSize = mSize * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit ); if ( mUsingCache ) scaledSize *= context.renderContext().rasterScaleFactor(); double half = scaledSize / 2.0; transform.scale( half, half ); } // rotate if the rotation is not going to be changed during the rendering if ( !hasDataDefinedRotation && mAngle != 0 ) { transform.rotate( mAngle ); } if ( !mPolygon.isEmpty() ) mPolygon = transform.map( mPolygon ); else mPath = transform.map( mPath ); if ( mUsingCache ) { if ( !prepareCache( context ) ) { mUsingCache = false; } } else { mCache = QImage(); mSelCache = QImage(); } prepareExpressions( context.layer(), context.renderContext().rendererScale() ); mAngleExpression = expression( "angle" ); mNameExpression = expression( "name" ); QgsMarkerSymbolLayerV2::startRender( context ); }