QgsSingleSymbolRenderer *QgsSingleSymbolRenderer::clone() const
{
  QgsSingleSymbolRenderer *r = new QgsSingleSymbolRenderer( mSymbol->clone() );
  r->setUsingSymbolLevels( usingSymbolLevels() );
  r->setDataDefinedSizeLegend( mDataDefinedSizeLegend ? new QgsDataDefinedSizeLegend( *mDataDefinedSizeLegend ) : nullptr );
  copyRendererData( r );
  return r;
}
void QgsDataDefinedSizeLegendWidget::updatePreview()
{
  QgsMarkerSymbol *symbol = mSourceSymbol->clone();
  symbol->setDataDefinedSize( mSizeProperty );
  QgsSingleSymbolRenderer *r = new QgsSingleSymbolRenderer( symbol );
  r->setDataDefinedSizeLegend( dataDefinedSizeLegend() );
  mPreviewLayer->setRenderer( r );
  mPreviewModel->refreshLayerLegend( mPreviewLayerNode );
  viewLayerTree->expandAll();
}
void QgsSingleSymbolDialog::apply()
{
  QgsSymbol* sy = new QgsSymbol( mVectorLayer->geometryType() );
  apply( sy );

  QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer( mVectorLayer->geometryType() );
  renderer->addSymbol( sy );
  renderer->updateSymbolAttributes();

  mVectorLayer->setRenderer( renderer );
}
Beispiel #4
0
static QString _getLayerSvgMarkerPath( const QgsProject &prj, const QString &layerName )
{
  QList<QgsMapLayer *> layers = prj.mapLayersByName( layerName );
  Q_ASSERT( layers.count() == 1 );
  Q_ASSERT( layers[0]->type() == QgsMapLayerType::VectorLayer );
  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( layers[0] );
  Q_ASSERT( layer->renderer() );
  Q_ASSERT( layer->renderer()->type() == "singleSymbol" );
  QgsSingleSymbolRenderer *r = static_cast<QgsSingleSymbolRenderer *>( layer->renderer() );
  QgsSymbol *s = r->symbol();
  Q_ASSERT( s && s->symbolLayerCount() == 1 );
  Q_ASSERT( s->symbolLayer( 0 )->layerType() == "SvgMarker" );
  QgsSvgMarkerSymbolLayer *sl = static_cast<QgsSvgMarkerSymbolLayer *>( s->symbolLayer( 0 ) );
  return sl->path();
}
QgsSingleSymbolRenderer *QgsSingleSymbolRenderer::convertFromRenderer( const QgsFeatureRenderer *renderer )
{
  QgsSingleSymbolRenderer *r = nullptr;
  if ( renderer->type() == QLatin1String( "singleSymbol" ) )
  {
    r = dynamic_cast<QgsSingleSymbolRenderer *>( renderer->clone() );
  }
  else if ( renderer->type() == QLatin1String( "pointDisplacement" ) || renderer->type() == QLatin1String( "pointCluster" ) )
  {
    const QgsPointDistanceRenderer *pointDistanceRenderer = dynamic_cast<const QgsPointDistanceRenderer *>( renderer );
    if ( pointDistanceRenderer )
      r = convertFromRenderer( pointDistanceRenderer->embeddedRenderer() );
  }
  else if ( renderer->type() == QLatin1String( "invertedPolygonRenderer" ) )
  {
    const QgsInvertedPolygonRenderer *invertedPolygonRenderer = dynamic_cast<const QgsInvertedPolygonRenderer *>( renderer );
    if ( invertedPolygonRenderer )
      r = convertFromRenderer( invertedPolygonRenderer->embeddedRenderer() );
  }

  if ( !r )
  {
    QgsRenderContext context;
    QgsSymbolList symbols = const_cast<QgsFeatureRenderer *>( renderer )->symbols( context );
    if ( !symbols.isEmpty() )
    {
      r = new QgsSingleSymbolRenderer( symbols.at( 0 )->clone() );
    }
  }

  if ( r )
  {
    r->setOrderBy( renderer->orderBy() );
    r->setOrderByEnabled( renderer->orderByEnabled() );
  }

  return r;
}
void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureIterator &fit )
{
  QHash< QgsSymbol *, QList<QgsFeature> > features; // key = symbol, value = array of features

  QgsSingleSymbolRenderer *selRenderer = nullptr;
  if ( !mSelectedFeatureIds.isEmpty() )
  {
    selRenderer = new QgsSingleSymbolRenderer( QgsSymbol::defaultSymbol( mGeometryType ) );
    selRenderer->symbol()->setColor( mContext.selectionColor() );
    selRenderer->setVertexMarkerAppearance( mVertexMarkerStyle, mVertexMarkerSize );
    selRenderer->startRender( mContext, mFields );
  }

  QgsExpressionContextScope *symbolScope = QgsExpressionContextUtils::updateSymbolScope( nullptr, new QgsExpressionContextScope() );
  mContext.expressionContext().appendScope( symbolScope );

  // 1. fetch features
  QgsFeature fet;
  while ( fit.nextFeature( fet ) )
  {
    if ( mContext.renderingStopped() )
    {
      qDebug( "rendering stop!" );
      stopRenderer( selRenderer );
      delete mContext.expressionContext().popScope();
      return;
    }

    if ( !fet.hasGeometry() )
      continue; // skip features without geometry

    mContext.expressionContext().setFeature( fet );
    QgsSymbol *sym = mRenderer->symbolForFeature( fet, mContext );
    if ( !sym )
    {
      continue;
    }

    if ( !features.contains( sym ) )
    {
      features.insert( sym, QList<QgsFeature>() );
    }
    features[sym].append( fet );

    // new labeling engine
    if ( mContext.labelingEngine() )
    {
      QgsGeometry obstacleGeometry;
      QgsSymbolList symbols = mRenderer->originalSymbolsForFeature( fet, mContext );

      if ( !symbols.isEmpty() && fet.geometry().type() == QgsWkbTypes::PointGeometry )
      {
        obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, mContext, symbols );
      }

      if ( !symbols.isEmpty() )
      {
        QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
      }

      if ( mLabelProvider )
      {
        mLabelProvider->registerFeature( fet, mContext, obstacleGeometry );
      }
      if ( mDiagramProvider )
      {
        mDiagramProvider->registerFeature( fet, mContext, obstacleGeometry );
      }
    }
  }

  delete mContext.expressionContext().popScope();

  if ( features.empty() )
  {
    // nothing to draw
    stopRenderer( selRenderer );
    return;
  }

  // find out the order
  QgsSymbolLevelOrder levels;
  QgsSymbolList symbols = mRenderer->symbols( mContext );
  for ( int i = 0; i < symbols.count(); i++ )
  {
    QgsSymbol *sym = symbols[i];
    for ( int j = 0; j < sym->symbolLayerCount(); j++ )
    {
      int level = sym->symbolLayer( j )->renderingPass();
      if ( level < 0 || level >= 1000 ) // ignore invalid levels
        continue;
      QgsSymbolLevelItem item( sym, j );
      while ( level >= levels.count() ) // append new empty levels
        levels.append( QgsSymbolLevel() );
      levels[level].append( item );
    }
  }

  // 2. draw features in correct order
  for ( int l = 0; l < levels.count(); l++ )
  {
    QgsSymbolLevel &level = levels[l];
    for ( int i = 0; i < level.count(); i++ )
    {
      QgsSymbolLevelItem &item = level[i];
      if ( !features.contains( item.symbol() ) )
      {
        QgsDebugMsg( QStringLiteral( "level item's symbol not found!" ) );
        continue;
      }
      int layer = item.layer();
      QList<QgsFeature> &lst = features[item.symbol()];
      QList<QgsFeature>::iterator fit;
      for ( fit = lst.begin(); fit != lst.end(); ++fit )
      {
        if ( mContext.renderingStopped() )
        {
          stopRenderer( selRenderer );
          return;
        }

        bool sel = mContext.showSelection() && mSelectedFeatureIds.contains( fit->id() );
        // maybe vertex markers should be drawn only during the last pass...
        bool drawMarker = ( mDrawVertexMarkers && mContext.drawEditingInformation() && ( !mVertexMarkerOnlyForSelection || sel ) );

        mContext.expressionContext().setFeature( *fit );

        try
        {
          mRenderer->renderFeature( *fit, mContext, layer, sel, drawMarker );
        }
        catch ( const QgsCsException &cse )
        {
          Q_UNUSED( cse );
          QgsDebugMsg( QStringLiteral( "Failed to transform a point while drawing a feature with ID '%1'. Ignoring this feature. %2" )
                       .arg( fet.id() ).arg( cse.what() ) );
        }
      }
    }
  }

  stopRenderer( selRenderer );
}
void QgsSingleSymbolDialog::refreshMarkers()
{
  QgsMarkerListModel *m = new QgsMarkerListModel( lstSymbols );
  lstSymbols->setModel( m );

  connect( lstSymbols->selectionModel(), SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
           this, SLOT( symbolChanged( const QModelIndex &, const QModelIndex & ) ) );

  // Find out the numerical fields of mVectorLayer, and populate the ComboBoxes
  QgsVectorDataProvider *provider = mVectorLayer->dataProvider();
  if ( provider )
  {
    const QgsFieldMap & fields = provider->fields();
    QString str;

    mRotationClassificationComboBox->addItem( DO_NOT_USE_STR, -1 );
    mScaleClassificationComboBox->addItem( DO_NOT_USE_STR, -1 );
    mSymbolComboBox->addItem( DO_NOT_USE_STR, -1 );
    for ( QgsFieldMap::const_iterator it = fields.begin();
          it != fields.end();
          ++it )
    {
      QVariant::Type type = ( *it ).type();
      if ( type == QVariant::Int || type == QVariant::Double )
      {
        mRotationClassificationComboBox->addItem( it->name(), it.key() );
        mScaleClassificationComboBox->addItem( it->name(), it.key() );
      }
      else if ( type == QVariant::String )
      {
        mSymbolComboBox->addItem( it->name(), it.key() );
      }
    }
  }
  else
  {
    QgsDebugMsg( "Warning, data provider is null" );
    return;
  }
  //
  //set outline / line style
  //
  cboOutlineStyle->addItem( QIcon( QgsSymbologyUtils::char2LinePixmap( "SolidLine" ) ), "", "SolidLine" );
  cboOutlineStyle->addItem( QIcon( QgsSymbologyUtils::char2LinePixmap( "NoPen" ) ), tr( "None" ), "NoPen" );
  cboOutlineStyle->addItem( QIcon( QgsSymbologyUtils::char2LinePixmap( "DashLine" ) ), "", "DashLine" );
  cboOutlineStyle->addItem( QIcon( QgsSymbologyUtils::char2LinePixmap( "DotLine" ) ), "", "DotLine" );
  cboOutlineStyle->addItem( QIcon( QgsSymbologyUtils::char2LinePixmap( "DashDotLine" ) ), "" , "DashDotLine" );
  cboOutlineStyle->addItem( QIcon( QgsSymbologyUtils::char2LinePixmap( "DashDotDotLine" ) ), "", "DashDotDotLine" );

  //
  //set pattern icons and state
  //
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "SolidPattern" ) ), "", "SolidPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "NoBrush" ) ), tr( "None" ), "NoBrush" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "HorPattern" ) ), "", "HorPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "VerPattern" ) ), "", "VerPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "CrossPattern" ) ), "", "CrossPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "BDiagPattern" ) ), "", "BDiagPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "FDiagPattern" ) ), "", "FDiagPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "DiagCrossPattern" ) ), "", "DiagCrossPattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense1Pattern" ) ), "", "Dense1Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense2Pattern" ) ), "", "Dense2Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense3Pattern" ) ), "", "Dense3Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense4Pattern" ) ), "", "Dense4Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense5Pattern" ) ), "", "Dense5Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense6Pattern" ) ), "", "Dense6Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "Dense7Pattern" ) ), "", "Dense7Pattern" );
  cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "TexturePattern" ) ), tr( "Texture" ), "TexturePattern" );

  if ( mVectorLayer && mVectorLayer->geometryType() != QGis::Point )
  {
    mGroupPoint->setVisible( false );
    mGroupPoint->setEnabled( false );
    mGroupDrawingByField->setVisible( false );
    mGroupDrawingByField->setEnabled( false );
  }

  if ( mDisabled )
  {
    unset();
  }
  else
  {
    if ( mVectorLayer )
    {
      const QgsSingleSymbolRenderer *renderer = dynamic_cast<const QgsSingleSymbolRenderer *>( mVectorLayer->renderer() );

      if ( renderer )
      {
        // Set from the existing renderer
        set( renderer->symbols().first() );
      }
      else
      {
        // Take values from an example instance
        QgsSingleSymbolRenderer exampleRenderer = QgsSingleSymbolRenderer( mVectorLayer->geometryType() );
        set( exampleRenderer.symbols().first() );
      }
    }
    else
    {
      QgsDebugMsg( "Warning, layer is a null pointer" );
    }
  }

  lstSymbols->blockSignals( false );
}