DataDefinedRestorer::DataDefinedRestorer( QgsSymbolV2* symbol, const QgsSymbolLayerV2* symbolLayer ) : mMarker( nullptr ) , mMarkerSymbolLayer( nullptr ) , mLine( nullptr ) , mLineSymbolLayer( nullptr ) { if ( symbolLayer->type() == QgsSymbolV2::Marker && symbol->type() == QgsSymbolV2::Marker ) { Q_ASSERT( symbol->type() == QgsSymbolV2::Marker ); mMarker = static_cast<QgsMarkerSymbolV2*>( symbol ); mMarkerSymbolLayer = static_cast<const QgsMarkerSymbolLayerV2*>( symbolLayer ); mDDSize = mMarker->dataDefinedSize(); mDDAngle = mMarker->dataDefinedAngle(); // check if restore is actually needed if ( mDDSize == QgsDataDefined() && mDDAngle == QgsDataDefined() ) mMarker = nullptr; } else if ( symbolLayer->type() == QgsSymbolV2::Line && symbol->type() == QgsSymbolV2::Line ) { mLine = static_cast<QgsLineSymbolV2*>( symbol ); mLineSymbolLayer = static_cast<const QgsLineSymbolLayerV2*>( symbolLayer ); mDDWidth = mLine->dataDefinedWidth(); // check if restore is actually needed if ( mDDWidth == QgsDataDefined() ) mLine = nullptr; } save(); }
void QgsSingleSymbolRendererV2::setRotationField( const QString& fieldOrExpression ) { if ( mSymbol->type() == QgsSymbolV2::Marker ) { QgsMarkerSymbolV2 * s = static_cast<QgsMarkerSymbolV2 *>( mSymbol.data() ); s->setDataDefinedAngle( QgsDataDefined( fieldOrExpression ) ); } }
void DataDefinedRestorer::restore() { if ( mMarker ) { if ( mDDSize != QgsDataDefined() && ( mSize != mMarkerSymbolLayer->size() || mMarkerOffset != mMarkerSymbolLayer->offset() ) ) mMarker->setDataDefinedSize( mDDSize ); if ( mDDAngle != QgsDataDefined() && mAngle != mMarkerSymbolLayer->angle() ) mMarker->setDataDefinedAngle( mDDAngle ); } else if ( mLine ) { if ( mDDWidth != QgsDataDefined() && ( mWidth != mLineSymbolLayer->width() || mLineOffset != mLineSymbolLayer->offset() ) ) mLine->setDataDefinedWidth( mDDWidth ); } save(); }
QgsDataDefined QgsMarkerSymbolV2::dataDefinedAngle() const { const double symbolRotation = angle(); QgsDataDefined* symbolDD = 0; // find the base of the "en masse" pattern for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it ) { const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it ); if ( layer->angle() == symbolRotation && layer->getDataDefinedProperty( "angle" ) ) { symbolDD = layer->getDataDefinedProperty( "angle" ); break; } } if ( !symbolDD ) return QgsDataDefined(); // check that all layer's angle expressions match the "en masse" pattern for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it ) { const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it ); QgsDataDefined* layerAngleDD = layer->getDataDefinedProperty( "angle" ); if ( qgsDoubleNear( layer->angle(), symbolRotation ) ) { if ( !layerAngleDD || *layerAngleDD != *symbolDD ) return QgsDataDefined(); } else { QScopedPointer< QgsDataDefined > rotatedDD( rotateWholeSymbol( layer->angle() - symbolRotation, *symbolDD ) ); if ( !layerAngleDD || *layerAngleDD != *( rotatedDD.data() ) ) return QgsDataDefined(); } } return QgsDataDefined( *symbolDD ); }
void QgsSizeScaleWidget::updatePreview() { if ( !mSymbol || !mLayer ) return; QScopedPointer<QgsScaleExpression> expr( createExpression() ); QList<double> breaks = QgsSymbolLayerV2Utils::prettyBreaks( expr->minValue(), expr->maxValue(), 4 ); treeView->setIconSize( QSize( 512, 512 ) ); mPreviewList.clear(); int widthMax = 0; for ( int i = 0; i < breaks.length(); i++ ) { QScopedPointer< QgsMarkerSymbolV2 > symbol( dynamic_cast<QgsMarkerSymbolV2*>( mSymbol->clone() ) ); symbol->setDataDefinedSize( QgsDataDefined() ); symbol->setDataDefinedAngle( QgsDataDefined() ); // to avoid symbol not beeing drawn symbol->setSize( expr->size( breaks[i] ) ); QgsSymbolV2LegendNode node( mLayerTreeLayer, QgsLegendSymbolItemV2( symbol.data(), QString::number( i ), 0 ) ); const QSize sz( node.minimumIconSize() ); node.setIconSize( sz ); QScopedPointer< QStandardItem > item( new QStandardItem( node.data( Qt::DecorationRole ).value<QPixmap>(), QString::number( breaks[i] ) ) ); widthMax = qMax( sz.width(), widthMax ); mPreviewList.appendRow( item.take() ); } // center icon and align text left by giving icons the same width // @todo maybe add some space so that icons don't touch for ( int i = 0; i < breaks.length(); i++ ) { QPixmap img( mPreviewList.item( i )->icon().pixmap( mPreviewList.item( i )->icon().actualSize( QSize( 512, 512 ) ) ) ); QPixmap enlarged( widthMax, img.height() ); // fill transparent and add original image enlarged.fill( Qt::transparent ); QPainter p( &enlarged ); p.drawPixmap( QPoint(( widthMax - img.width() ) / 2, 0 ), img ); p.end(); mPreviewList.item( i )->setIcon( enlarged ); } }
QgsLegendSymbolListV2 QgsCategorizedSymbolRendererV2::legendSymbolItemsV2() const { QgsLegendSymbolListV2 lst; if ( mSourceSymbol.data() && mSourceSymbol->type() == QgsSymbolV2::Marker ) { // check that all symbols that have the same size expression QgsDataDefined ddSize; foreach ( QgsRendererCategoryV2 category, mCategories ) { const QgsMarkerSymbolV2 * symbol = static_cast<const QgsMarkerSymbolV2 *>( category.symbol() ); if ( !ddSize.hasDefaultValues() && symbol->dataDefinedSize() != ddSize ) { // no common size expression return QgsFeatureRendererV2::legendSymbolItemsV2(); } else { ddSize = symbol->dataDefinedSize(); } } if ( !ddSize.isActive() || !ddSize.useExpression() ) { return QgsFeatureRendererV2::legendSymbolItemsV2(); } QgsScaleExpression exp( ddSize.expressionString() ); if ( exp.type() != QgsScaleExpression::Unknown ) { QgsLegendSymbolItemV2 title( NULL, exp.baseExpression(), "" ); lst << title; foreach ( double v, QgsSymbolLayerV2Utils::prettyBreaks( exp.minValue(), exp.maxValue(), 4 ) ) { QgsLegendSymbolItemV2 si( mSourceSymbol.data(), QString::number( v ), "" ); QgsMarkerSymbolV2 * s = static_cast<QgsMarkerSymbolV2 *>( si.symbol() ); s->setDataDefinedSize( QgsDataDefined() ); s->setSize( exp.size( v ) ); lst << si; } // now list the categorized symbols const QgsLegendSymbolListV2 list2 = QgsFeatureRendererV2::legendSymbolItemsV2() ; foreach ( QgsLegendSymbolItemV2 item, list2 ) lst << item; return lst; }
QgsDataDefined QgsLineSymbolV2::dataDefinedWidth() const { const double symbolWidth = width(); QgsDataDefined* symbolDD = 0; // find the base of the "en masse" pattern for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it ) { const QgsLineSymbolLayerV2* layer = static_cast<const QgsLineSymbolLayerV2*>( *it ); if ( layer->width() == symbolWidth && layer->getDataDefinedProperty( "width" ) ) { symbolDD = layer->getDataDefinedProperty( "width" ); break; } } if ( !symbolDD ) return QgsDataDefined(); // check that all layers width expressions match the "en masse" pattern for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it ) { const QgsLineSymbolLayerV2* layer = static_cast<const QgsLineSymbolLayerV2*>( *it ); QgsDataDefined* layerWidthDD = layer->getDataDefinedProperty( "width" ); QgsDataDefined* layerOffsetDD = layer->getDataDefinedProperty( "offset" ); if ( qgsDoubleNear( layer->width(), symbolWidth ) ) { if ( !layerWidthDD || *layerWidthDD != *symbolDD ) return QgsDataDefined(); } else { if ( symbolWidth == 0 ) return QgsDataDefined(); QScopedPointer< QgsDataDefined > scaledDD( scaleWholeSymbol( layer->width() / symbolWidth, *symbolDD ) ); if ( !layerWidthDD || *layerWidthDD != *( scaledDD.data() ) ) return QgsDataDefined(); } QScopedPointer< QgsDataDefined > scaledOffsetDD( scaleWholeSymbol( layer->offset() / symbolWidth, *symbolDD ) ); if ( layerOffsetDD && *layerOffsetDD != *( scaledOffsetDD.data() ) ) return QgsDataDefined(); } return QgsDataDefined( *symbolDD ); }
void QgsMapToolRotatePointSymbols::createPixmapItem( QgsMarkerSymbolV2* markerSymbol ) { if ( !mCanvas ) { return; } //get the image that is used for that symbol, but without point rotation QImage pointImage; if ( markerSymbol ) { QgsSymbolV2* clone = markerSymbol->clone(); QgsMarkerSymbolV2* markerClone = static_cast<QgsMarkerSymbolV2*>( clone ); markerClone->setDataDefinedAngle( QgsDataDefined() ); pointImage = markerClone->bigSymbolPreviewImage(); delete clone; } mRotationItem = new QgsPointRotationItem( mCanvas ); mRotationItem->setSymbol( pointImage ); }
QgsDataDefined QgsSizeScaleWidget::dataDefined() const { QScopedPointer<QgsScaleExpression> exp( createExpression() ); return QgsDataDefined( exp.data() ); }