bool QgsPalLabeling::willUseLayer( QgsVectorLayer* layer ) { QgsPalLayerSettings lyrTmp; lyrTmp.readFromLayer( layer ); return lyrTmp.enabled; }
int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices, QgsRenderContext& ctx ) { Q_ASSERT( mMapRenderer != NULL ); // start with a temporary settings class, find out labeling info QgsPalLayerSettings lyrTmp; lyrTmp.readFromLayer( layer ); if ( !lyrTmp.enabled ) return 0; // find out which field will be needed int fldIndex = layer->fieldNameIndex( lyrTmp.fieldName ); if ( fldIndex == -1 ) return 0; attrIndices.insert( fldIndex ); //add indices of data defined fields QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator dIt = lyrTmp.dataDefinedProperties.constBegin(); for ( ; dIt != lyrTmp.dataDefinedProperties.constEnd(); ++dIt ) { attrIndices.insert( dIt.value() ); } // add layer settings to the pallabeling hashtable: <QgsVectorLayer*, QgsPalLayerSettings> mActiveLayers.insert( layer, lyrTmp ); // start using the reference to the layer in hashtable instead of local instance QgsPalLayerSettings& lyr = mActiveLayers[layer]; // how to place the labels Arrangement arrangement; switch ( lyr.placement ) { case QgsPalLayerSettings::AroundPoint: arrangement = P_POINT; break; case QgsPalLayerSettings::OverPoint: arrangement = P_POINT_OVER; break; case QgsPalLayerSettings::Line: arrangement = P_LINE; break; case QgsPalLayerSettings::Curved: arrangement = P_CURVED; break; case QgsPalLayerSettings::Horizontal: arrangement = P_HORIZ; break; case QgsPalLayerSettings::Free: arrangement = P_FREE; break; default: Q_ASSERT( "unsupported placement" && 0 ); return 0; } // create the pal layer double priority = 1 - lyr.priority / 10.0; // convert 0..10 --> 1..0 double min_scale = -1, max_scale = -1; if ( lyr.scaleMin != 0 && lyr.scaleMax != 0 ) { min_scale = lyr.scaleMin; max_scale = lyr.scaleMax; } Layer* l = mPal->addLayer( layer->id().toLocal8Bit().data(), min_scale, max_scale, arrangement, METER, priority, lyr.obstacle, true, true ); if ( lyr.placementFlags ) l->setArrangementFlags( lyr.placementFlags ); // set label mode (label per feature is the default) l->setLabelMode( lyr.labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature ); // set whether adjacent lines should be merged l->setMergeConnectedLines( lyr.mergeLines ); lyr.textFont.setPixelSize( lyr.sizeToPixel( lyr.textFont.pointSizeF(), ctx ) ); //raster and vector scale factors lyr.vectorScaleFactor = ctx.scaleFactor(); lyr.rasterCompressFactor = ctx.rasterScaleFactor(); // save the pal layer to our layer context (with some additional info) lyr.palLayer = l; lyr.fieldIndex = fldIndex; lyr.fontMetrics = new QFontMetricsF( lyr.textFont ); lyr.xform = mMapRenderer->coordinateTransform(); if ( mMapRenderer->hasCrsTransformEnabled() ) lyr.ct = new QgsCoordinateTransform( layer->crs(), mMapRenderer->destinationCrs() ); else lyr.ct = NULL; lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 ); lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 ); return 1; // init successful }
void QgsLabelPropertyDialog::setDataDefinedValues( const QgsPalLayerSettings &layerSettings, QgsVectorLayer* vlayer ) { //loop through data defined properties and set all the GUI widget values. We can do this //even if the data defined property is set to an expression, as it's useful to show //users what the evaluated property is... QgsExpressionContext context; context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope() << QgsExpressionContextUtils::atlasScope( nullptr ) << QgsExpressionContextUtils::mapSettingsScope( QgisApp::instance()->mapCanvas()->mapSettings() ) << QgsExpressionContextUtils::layerScope( vlayer ); context.setFeature( mCurLabelFeat ); QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator propIt = mDataDefinedProperties.constBegin(); for ( ; propIt != mDataDefinedProperties.constEnd(); ++propIt ) { QgsDataDefined* dd = propIt.value(); if ( !dd || !dd->isActive() ) { continue; } if ( !dd->expressionIsPrepared() ) { dd->prepareExpression( context ); } //TODO - pass expression context QVariant result = layerSettings.dataDefinedValue( propIt.key(), mCurLabelFeat, vlayer->fields(), &context ); if ( !result.isValid() || result.isNull() ) { //could not evaluate data defined value continue; } bool ok = false; switch ( propIt.key() ) { case QgsPalLayerSettings::Show: { int showLabel = result.toInt( &ok ); mShowLabelChkbx->setChecked( !ok || showLabel != 0 ); break; } case QgsPalLayerSettings::AlwaysShow: mAlwaysShowChkbx->setChecked( result.toBool() ); break; case QgsPalLayerSettings::MinScale: { int minScale = result.toInt( &ok ); if ( ok ) { mMinScaleSpinBox->setValue( minScale ); } break; } case QgsPalLayerSettings::MaxScale: { int maxScale = result.toInt( &ok ); if ( ok ) { mMaxScaleSpinBox->setValue( maxScale ); } break; } case QgsPalLayerSettings::BufferSize: { double bufferSize = result.toDouble( &ok ); if ( ok ) { mBufferSizeSpinBox->setValue( bufferSize ); } break; } case QgsPalLayerSettings::PositionX: { double posX = result.toDouble( &ok ); if ( ok ) { mXCoordSpinBox->setValue( posX ); } break; } case QgsPalLayerSettings::PositionY: { double posY = result.toDouble( &ok ); if ( ok ) { mYCoordSpinBox->setValue( posY ); } break; } case QgsPalLayerSettings::LabelDistance: { double labelDist = result.toDouble( &ok ); if ( ok ) { mLabelDistanceSpinBox->setValue( labelDist ); } break; } case QgsPalLayerSettings::Hali: mHaliComboBox->setCurrentIndex( mHaliComboBox->findData( result.toString() ) ); break; case QgsPalLayerSettings::Vali: mValiComboBox->setCurrentIndex( mValiComboBox->findData( result.toString() ) ); break; case QgsPalLayerSettings::BufferColor: mBufferColorButton->setColor( QColor( result.toString() ) ); break; case QgsPalLayerSettings::Color: mFontColorButton->setColor( QColor( result.toString() ) ); break; case QgsPalLayerSettings::Rotation: { double rot = result.toDouble( &ok ); if ( ok ) { mRotationSpinBox->setValue( rot ); } break; } case QgsPalLayerSettings::Size: { double size = result.toDouble( &ok ); if ( ok ) { mFontSizeSpinBox->setValue( size ); } else { mFontSizeSpinBox->setValue( 0 ); } break; } default: break; } } }
void QgsLabelPropertyDialog::init( const QString &layerId, const QString &providerId, int featureId, const QString &labelText ) { //get feature attributes QgsVectorLayer *vlayer = QgsProject::instance()->mapLayer<QgsVectorLayer *>( layerId ); if ( !vlayer ) { return; } if ( !vlayer->labeling() ) { return; } if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( mCurLabelFeat ) ) { return; } QgsAttributes attributeValues = mCurLabelFeat.attributes(); //get layerproperties. Problem: only for pallabeling... blockElementSignals( true ); QgsPalLayerSettings layerSettings = vlayer->labeling()->settings( providerId ); //get label field and fill line edit if ( layerSettings.isExpression && !labelText.isNull() ) { mLabelTextLineEdit->setText( labelText ); mLabelTextLineEdit->setEnabled( false ); mLabelTextLabel->setText( tr( "Expression result" ) ); } else { QString labelFieldName = layerSettings.fieldName; if ( !labelFieldName.isEmpty() ) { mCurLabelField = vlayer->fields().lookupField( labelFieldName ); if ( mCurLabelField >= 0 ) { mLabelTextLineEdit->setText( attributeValues.at( mCurLabelField ).toString() ); if ( vlayer->isEditable() ) mLabelTextLineEdit->setEnabled( true ); else mLabelTextLineEdit->setEnabled( false ); const QgsFields &layerFields = vlayer->fields(); switch ( layerFields.at( mCurLabelField ).type() ) { case QVariant::Double: mLabelTextLineEdit->setValidator( new QDoubleValidator( this ) ); break; case QVariant::Int: case QVariant::UInt: case QVariant::LongLong: mLabelTextLineEdit->setValidator( new QIntValidator( this ) ); break; default: break; } } else { mLabelTextLineEdit->setEnabled( false ); } } } //get attributes of the feature and fill data defined values // font is set directly from QgsLabelPosition updateFont( mLabelFont, false ); QgsTextFormat format = layerSettings.format(); QgsTextBufferSettings buffer = format.buffer(); //set all the gui elements to the default layer-level values mLabelDistanceSpinBox->clear(); mLabelDistanceSpinBox->setSpecialValueText( tr( "Layer default (%1)" ).arg( QString::number( layerSettings.dist, 'f', mLabelDistanceSpinBox->decimals() ) ) ); mBufferSizeSpinBox->clear(); mBufferSizeSpinBox->setSpecialValueText( tr( "Layer default (%1)" ).arg( QString::number( buffer.size(), 'f', mBufferSizeSpinBox->decimals() ) ) ); mRotationSpinBox->clear(); mXCoordSpinBox->clear(); mYCoordSpinBox->clear(); mShowLabelChkbx->setChecked( true ); mFontColorButton->setColor( format.color() ); mBufferColorButton->setColor( buffer.color() ); mMinScaleWidget->setScale( layerSettings.minimumScale ); mMaxScaleWidget->setScale( layerSettings.maximumScale ); mHaliComboBox->setCurrentIndex( mHaliComboBox->findData( "Left" ) ); mValiComboBox->setCurrentIndex( mValiComboBox->findData( "Bottom" ) ); mFontColorButton->setColorDialogTitle( tr( "Font Color" ) ); mBufferColorButton->setColorDialogTitle( tr( "Buffer Color" ) ); disableGuiElements(); mDataDefinedProperties = layerSettings.dataDefinedProperties(); //set widget values from data defined results setDataDefinedValues( vlayer ); //enable widgets connected to data defined fields enableDataDefinedWidgets( vlayer ); blockElementSignals( false ); }