示例#1
0
bool QgsPalLabeling::willUseLayer( QgsVectorLayer* layer )
{
  QgsPalLayerSettings lyrTmp;
  lyrTmp.readFromLayer( layer );
  return lyrTmp.enabled;
}
示例#2
0
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 );
}