void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
{
  QString attrName = mExpressionWidget->currentField();

  int classes = spinGraduatedClasses->value();

  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();

  if ( ramp == NULL )
  {
    if ( cboGraduatedColorRamp->count() == 0 )
      QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
    else
      QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
    return;
  }

  QgsGraduatedSymbolRendererV2::Mode mode;
  if ( cboGraduatedMode->currentIndex() == 0 )
    mode = QgsGraduatedSymbolRendererV2::EqualInterval;
  else if ( cboGraduatedMode->currentIndex() == 2 )
    mode = QgsGraduatedSymbolRendererV2::Jenks;
  else if ( cboGraduatedMode->currentIndex() == 3 )
    mode = QgsGraduatedSymbolRendererV2::StdDev;
  else if ( cboGraduatedMode->currentIndex() == 4 )
    mode = QgsGraduatedSymbolRendererV2::Pretty;
  else // default should be quantile for now
    mode = QgsGraduatedSymbolRendererV2::Quantile;


  // Jenks is n^2 complexity, warn for big dataset (more than 50k records)
  // and give the user the chance to cancel
  if ( QgsGraduatedSymbolRendererV2::Jenks == mode
       && mLayer->featureCount() > 50000 )
  {
    if ( QMessageBox::Cancel == QMessageBox::question( this, tr( "Warning" ), tr( "Natural break classification (Jenks) is O(n2) complexity, your classification may take a long time.\nPress cancel to abort breaks calculation or OK to continue." ), QMessageBox::Cancel, QMessageBox::Ok ) ) return;
  }

  // create and set new renderer
  QApplication::setOverrideCursor( Qt::WaitCursor );
  QgsGraduatedSymbolRendererV2* r = QgsGraduatedSymbolRendererV2::createRenderer(
                                      mLayer, attrName, classes, mode, mGraduatedSymbol, ramp, cbxInvertedColorRamp->isChecked() );
  QApplication::restoreOverrideCursor();
  if ( !r )
  {
    QMessageBox::critical( this, tr( "Error" ), tr( "Renderer creation has failed." ) );
    return;
  }

  r->setSizeScaleField( mRenderer->sizeScaleField() );
  r->setRotationField( mRenderer->rotationField() );
  r->setScaleMethod( mRenderer->scaleMethod() );

  if ( mModel )
  {
    mModel->setRenderer( r );
  }
  delete mRenderer;
  mRenderer = r;
}
示例#2
0
void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
{
  QString attrName = cboGraduatedColumn->currentText();

  int classes = spinGraduatedClasses->value();

  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();

  if ( ramp == NULL )
  {
    if ( cboGraduatedColorRamp->count() == 0 )
      QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
    else
      QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
    return;
  }

  QgsGraduatedSymbolRendererV2::Mode mode;
  if ( cboGraduatedMode->currentIndex() == 0 )
    mode = QgsGraduatedSymbolRendererV2::EqualInterval;
  else if ( cboGraduatedMode->currentIndex() == 2 )
    mode = QgsGraduatedSymbolRendererV2::Jenks;
  else if ( cboGraduatedMode->currentIndex() == 3 )
    mode = QgsGraduatedSymbolRendererV2::StdDev;
  else if ( cboGraduatedMode->currentIndex() == 4 )
    mode = QgsGraduatedSymbolRendererV2::Pretty;
  else // default should be quantile for now
    mode = QgsGraduatedSymbolRendererV2::Quantile;

  // create and set new renderer
  QApplication::setOverrideCursor( Qt::WaitCursor );
  QgsGraduatedSymbolRendererV2* r = QgsGraduatedSymbolRendererV2::createRenderer(
                                      mLayer, attrName, classes, mode, mGraduatedSymbol, ramp );
  QApplication::restoreOverrideCursor();
  if ( !r )
  {
    QMessageBox::critical( this, tr( "Error" ), tr( "Renderer creation has failed." ) );
    return;
  }

  r->setSizeScaleField( mRenderer->sizeScaleField() );
  r->setRotationField( mRenderer->rotationField() );
  r->setScaleMethod( mRenderer->scaleMethod() );

  delete mRenderer;
  mRenderer = r;

  populateRanges();
}
static QgsFeatureRendererV2* readOldGraduatedSymbolRenderer( const QDomNode& rnode, QGis::GeometryType geomType )
{
  QDomNode modeNode = rnode.namedItem( "mode" );
  QString modeValue = modeNode.toElement().text();
  QDomNode classnode = rnode.namedItem( "classificationfield" );
  QString classificationField = classnode.toElement().text();

  QgsGraduatedSymbolRendererV2::Mode m = QgsGraduatedSymbolRendererV2::Custom;
  if ( modeValue == "Empty" )
  {
    m = QgsGraduatedSymbolRendererV2::Custom;
  }
  else if ( modeValue == "Quantile" )
  {
    m = QgsGraduatedSymbolRendererV2::Quantile;
  }
  else //default
  {
    m = QgsGraduatedSymbolRendererV2::EqualInterval;
  }

  // load ranges and symbols
  QgsRangeList ranges;
  QDomNode symbolnode = rnode.namedItem( "symbol" );
  while ( !symbolnode.isNull() )
  {
    QgsSymbolV2* symbolv2 = readOldSymbol( symbolnode, geomType );
    if ( symbolv2 )
    {
      QgsOldSymbolMeta meta = readSymbolMeta( symbolnode );
      double lowerValue = meta.lowerValue.toDouble();
      double upperValue = meta.upperValue.toDouble();
      QString label = meta.label;
      if ( label.isEmpty() )
        label = QString( "%1 - %2" ).arg( lowerValue, -1, 'f', 3 ).arg( upperValue, -1, 'f', 3 );
      ranges.append( QgsRendererRangeV2( lowerValue, upperValue, symbolv2, label ) );
    }

    symbolnode = symbolnode.nextSibling();
  }

  // create renderer
  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( classificationField, ranges );
  r->setMode( m );
  return r;
}
QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone() const
{
  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( mAttrName, mRanges );
  r->setMode( mMode );
  if ( mSourceSymbol.data() )
    r->setSourceSymbol( mSourceSymbol->clone() );
  if ( mSourceColorRamp.data() )
  {
    r->setSourceColorRamp( mSourceColorRamp->clone() );
    r->setInvertedColorRamp( mInvertedColorRamp );
  }
  r->setUsingSymbolLevels( usingSymbolLevels() );
  r->setRotationField( rotationField() );
  r->setSizeScaleField( sizeScaleField() );
  r->setScaleMethod( scaleMethod() );
  r->setLabelFormat( labelFormat() );
  return r;
}
QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone()
{
  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( mAttrName, mRanges );
  r->setMode( mMode );
  if ( mSourceSymbol )
    r->setSourceSymbol( mSourceSymbol->clone() );
  if ( mSourceColorRamp )
    r->setSourceColorRamp( mSourceColorRamp->clone() );
  r->setUsingSymbolLevels( usingSymbolLevels() );
  r->setRotationField( rotationField() );
  r->setSizeScaleField( sizeScaleField() );
  r->setScaleMethod( scaleMethod() );
  return r;
}
QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
  QgsVectorLayer* vlayer,
  QString attrName,
  int classes,
  Mode mode,
  QgsSymbolV2* symbol,
  QgsVectorColorRampV2* ramp,
  bool inverted,
  QgsRendererRangeV2LabelFormat labelFormat
)
{
  QgsRangeList ranges;
  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );
  r->setSourceSymbol( symbol->clone() );
  r->setSourceColorRamp( ramp->clone() );
  r->setInvertedColorRamp( inverted );
  r->setMode( mode );
  r->setLabelFormat( labelFormat );
  r->updateClasses( vlayer, mode, classes );
  return r;
}
QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create( QDomElement& element )
{
  QDomElement symbolsElem = element.firstChildElement( "symbols" );
  if ( symbolsElem.isNull() )
    return NULL;

  QDomElement rangesElem = element.firstChildElement( "ranges" );
  if ( rangesElem.isNull() )
    return NULL;

  QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
  QgsRangeList ranges;

  QDomElement rangeElem = rangesElem.firstChildElement();
  while ( !rangeElem.isNull() )
  {
    if ( rangeElem.tagName() == "range" )
    {
      double lowerValue = rangeElem.attribute( "lower" ).toDouble();
      double upperValue = rangeElem.attribute( "upper" ).toDouble();
      QString symbolName = rangeElem.attribute( "symbol" );
      QString label = rangeElem.attribute( "label" );
      if ( symbolMap.contains( symbolName ) )
      {
        QgsSymbolV2* symbol = symbolMap.take( symbolName );
        ranges.append( QgsRendererRangeV2( lowerValue, upperValue, symbol, label ) );
      }
    }
    rangeElem = rangeElem.nextSiblingElement();
  }

  QString attrName = element.attribute( "attr" );

  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );

  // delete symbols if there are any more
  QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );

  // try to load source symbol (optional)
  QDomElement sourceSymbolElem = element.firstChildElement( "source-symbol" );
  if ( !sourceSymbolElem.isNull() )
  {
    QgsSymbolV2Map sourceSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( sourceSymbolElem );
    if ( sourceSymbolMap.contains( "0" ) )
    {
      r->setSourceSymbol( sourceSymbolMap.take( "0" ) );
    }
    QgsSymbolLayerV2Utils::clearSymbolMap( sourceSymbolMap );
  }

  // try to load color ramp (optional)
  QDomElement sourceColorRampElem = element.firstChildElement( "colorramp" );
  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
  {
    r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
    QDomElement invertedColorRampElem = element.firstChildElement( "invertedcolorramp" );
    if ( !invertedColorRampElem.isNull() )
      r->setInvertedColorRamp( invertedColorRampElem.attribute( "value" ) == "1" );
  }

  // try to load mode
  QDomElement modeElem = element.firstChildElement( "mode" );
  if ( !modeElem.isNull() )
  {
    QString modeString = modeElem.attribute( "name" );
    if ( modeString == "equal" )
      r->setMode( EqualInterval );
    else if ( modeString == "quantile" )
      r->setMode( Quantile );
    else if ( modeString == "jenks" )
      r->setMode( Jenks );
    else if ( modeString == "stddev" )
      r->setMode( StdDev );
    else if ( modeString == "pretty" )
      r->setMode( Pretty );
  }

  QDomElement rotationElem = element.firstChildElement( "rotation" );
  if ( !rotationElem.isNull() )
    r->setRotationField( rotationElem.attribute( "field" ) );

  QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
  if ( !sizeScaleElem.isNull() )
    r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
  r->setScaleMethod( QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ) );

  // TODO: symbol levels
  return r;
}
QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
  QgsVectorLayer* vlayer,
  QString attrName,
  int classes,
  Mode mode,
  QgsSymbolV2* symbol,
  QgsVectorColorRampV2* ramp,
  bool inverted )
{
  if ( classes < 1 )
    return NULL;

  int attrNum = vlayer->fieldNameIndex( attrName );
  double minimum;
  double maximum;

  QScopedPointer<QgsExpression> expression;

  if ( attrNum == -1 )
  {
    // try to use expression
    expression.reset( new QgsExpression( attrName ) );
    if ( expression->hasParserError() || !expression->prepare( vlayer->pendingFields() ) )
      return 0; // should have a means to report errors

    QList<double> values;
    QgsFeatureIterator fit = vlayer->getFeatures();
    QgsFeature feature;
    while ( fit.nextFeature( feature ) )
    {
      values << expression->evaluate( feature ).toDouble();
    }
    qSort( values );
    minimum = values.first();
    maximum = values.last();
  }
  else
  {
    minimum = vlayer->minimumValue( attrNum ).toDouble();
    maximum = vlayer->maximumValue( attrNum ).toDouble();
  }

  QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );
  QList<double> breaks;
  QList<int> labels;
  if ( mode == EqualInterval )
  {
    breaks = _calcEqualIntervalBreaks( minimum, maximum, classes );
  }
  else if ( mode == Pretty )
  {
    breaks = _calcPrettyBreaks( minimum, maximum, classes );
  }
  else if ( mode == Quantile || mode == Jenks || mode == StdDev )
  {
    // get values from layer
    QList<double> values;
    QgsFeature f;
    QStringList lst;
    if ( expression.isNull() )
      lst.append( attrName );
    else
      lst = expression->referencedColumns();

    QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setSubsetOfAttributes( lst, vlayer->pendingFields() ) );

    // create list of non-null attribute values
    while ( fit.nextFeature( f ) )
    {
      QVariant v = expression.isNull() ? f.attribute( attrNum ) : expression->evaluate( f );
      if ( !v.isNull() )
        values.append( v.toDouble() );
    }

    // calculate the breaks
    if ( mode == Quantile )
    {
      breaks = _calcQuantileBreaks( values, classes );
    }
    else if ( mode == Jenks )
    {
      breaks = _calcJenksBreaks( values, classes, minimum, maximum );
    }
    else if ( mode == StdDev )
    {
      breaks = _calcStdDevBreaks( values, classes, labels );
    }
  }
  else
  {
    Q_ASSERT( false );
  }

  QgsRangeList ranges;
  double lower, upper = minimum;
  QString label;

  // "breaks" list contains all values at class breaks plus maximum as last break
  int i = 0;
  for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
  {
    lower = upper; // upper border from last interval
    upper = *it;
    if ( mode == StdDev )
    {
      if ( i == 0 )
      {
        label = "< " + QString::number( labels[i], 'i', 0 ) + " Std Dev";
      }
      else if ( i == labels.count() - 1 )
      {
        label = ">= " + QString::number( labels[i-1], 'i', 0 ) + " Std Dev";
      }
      else
      {
        label = QString::number( labels[i-1], 'i', 0 ) + " Std Dev" + " - " + QString::number( labels[i], 'i', 0 ) + " Std Dev";
      }
    }
    else
    {
      label = QString::number( lower, 'f', 4 ) + " - " + QString::number( upper, 'f', 4 );
    }

    QgsSymbolV2* newSymbol = symbol->clone();
    double colorValue;
    if ( inverted ) colorValue = ( breaks.count() > 1 ? ( double )( breaks.count() - i - 1 ) / ( breaks.count() - 1 ) : 0 );
    else colorValue = ( breaks.count() > 1 ? ( double ) i / ( breaks.count() - 1 ) : 0 );
    newSymbol->setColor( ramp->color( colorValue ) ); // color from (0 / cl-1) to (cl-1 / cl-1)

    ranges.append( QgsRendererRangeV2( lower, upper, newSymbol, label ) );
  }

  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );
  r->setSourceSymbol( symbol->clone() );
  r->setSourceColorRamp( ramp->clone() );
  r->setInvertedColorRamp( inverted );
  r->setMode( mode );
  return r;
}
QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
  QgsVectorLayer* vlayer,
  QString attrName,
  int classes,
  Mode mode,
  QgsSymbolV2* symbol,
  QgsVectorColorRampV2* ramp )
{
  if ( classes < 1 )
    return NULL;

  int attrNum = vlayer->fieldNameIndex( attrName );

  double minimum = vlayer->minimumValue( attrNum ).toDouble();
  double maximum = vlayer->maximumValue( attrNum ).toDouble();
  QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );

  QList<double> breaks;
  QList<int> labels;
  if ( mode == EqualInterval )
  {
    breaks = _calcEqualIntervalBreaks( minimum, maximum, classes );
  }
  else if ( mode == Pretty )
  {
    breaks = _calcPrettyBreaks( minimum, maximum, classes );
  }
  else if ( mode == Quantile || mode == Jenks || mode == StdDev )
  {
    // get values from layer
    QList<double> values;
    QgsFeature f;
    QgsAttributeList lst;
    lst.append( attrNum );

    QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setSubsetOfAttributes( lst ) );

    // create list of non-null attribute values
    while ( fit.nextFeature( f ) )
      if ( !f.attribute( attrNum ).isNull() )
        values.append( f.attribute( attrNum ).toDouble() );

    // calculate the breaks
    if ( mode == Quantile )
    {
      breaks = _calcQuantileBreaks( values, classes );
    }
    else if ( mode == Jenks )
    {
      breaks = _calcJenksBreaks( values, classes, minimum, maximum );
    }
    else if ( mode == StdDev )
    {
      breaks = _calcStdDevBreaks( values, classes, labels );
    }
  }
  else
  {
    Q_ASSERT( false );
  }

  QgsRangeList ranges;
  double lower, upper = minimum;
  QString label;

  // "breaks" list contains all values at class breaks plus maximum as last break
  int i = 0;
  for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
  {
    lower = upper; // upper border from last interval
    upper = *it;
    if ( mode == StdDev )
    {
      if ( i == 0 )
      {
        label = "< " + QString::number( labels[i], 'i', 0 ) + " Std Dev";
      }
      else if ( i == labels.count() - 1 )
      {
        label = ">= " + QString::number( labels[i-1], 'i', 0 ) + " Std Dev";
      }
      else
      {
        label = QString::number( labels[i-1], 'i', 0 ) + " Std Dev" + " - " + QString::number( labels[i], 'i', 0 ) + " Std Dev";
      }
    }
    else
    {
      label = QString::number( lower, 'f', 4 ) + " - " + QString::number( upper, 'f', 4 );
    }

    QgsSymbolV2* newSymbol = symbol->clone();
    double colorValue = ( breaks.count() > 1 ? ( double ) i / ( breaks.count() - 1 ) : 0 );
    newSymbol->setColor( ramp->color( colorValue ) ); // color from (0 / cl-1) to (cl-1 / cl-1)

    ranges.append( QgsRendererRangeV2( lower, upper, newSymbol, label ) );
  }

  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );
  r->setSourceSymbol( symbol->clone() );
  r->setSourceColorRamp( ramp->clone() );
  r->setMode( mode );
  return r;
}
QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create( QDomElement& element )
{
  QDomElement symbolsElem = element.firstChildElement( "symbols" );
  if ( symbolsElem.isNull() )
    return NULL;

  QDomElement rangesElem = element.firstChildElement( "ranges" );
  if ( rangesElem.isNull() )
    return NULL;

  QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
  QgsRangeList ranges;

  QDomElement rangeElem = rangesElem.firstChildElement();
  while ( !rangeElem.isNull() )
  {
    if ( rangeElem.tagName() == "range" )
    {
      double lowerValue = rangeElem.attribute( "lower" ).toDouble();
      double upperValue = rangeElem.attribute( "upper" ).toDouble();
      QString symbolName = rangeElem.attribute( "symbol" );
      QString label = rangeElem.attribute( "label" );
      bool render = rangeElem.attribute( "render", "true" ) != "false";
      if ( symbolMap.contains( symbolName ) )
      {
        QgsSymbolV2* symbol = symbolMap.take( symbolName );
        ranges.append( QgsRendererRangeV2( lowerValue, upperValue, symbol, label, render ) );
      }
    }
    rangeElem = rangeElem.nextSiblingElement();
  }

  QString attrName = element.attribute( "attr" );

  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );

  QString attrMethod = element.attribute( "graduatedMethod" );
  if ( attrMethod.length() )
  {
    if ( attrMethod == graduatedMethodStr( GraduatedColor ) )
      r->setGraduatedMethod( GraduatedColor );
    else if ( attrMethod == graduatedMethodStr( GraduatedSize ) )
      r->setGraduatedMethod( GraduatedSize );
  }


  // delete symbols if there are any more
  QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );

  // try to load source symbol (optional)
  QDomElement sourceSymbolElem = element.firstChildElement( "source-symbol" );
  if ( !sourceSymbolElem.isNull() )
  {
    QgsSymbolV2Map sourceSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( sourceSymbolElem );
    if ( sourceSymbolMap.contains( "0" ) )
    {
      r->setSourceSymbol( sourceSymbolMap.take( "0" ) );
    }
    QgsSymbolLayerV2Utils::clearSymbolMap( sourceSymbolMap );
  }

  // try to load color ramp (optional)
  QDomElement sourceColorRampElem = element.firstChildElement( "colorramp" );
  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
  {
    r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
    QDomElement invertedColorRampElem = element.firstChildElement( "invertedcolorramp" );
    if ( !invertedColorRampElem.isNull() )
      r->setInvertedColorRamp( invertedColorRampElem.attribute( "value" ) == "1" );
  }

  // try to load mode
  QDomElement modeElem = element.firstChildElement( "mode" );
  if ( !modeElem.isNull() )
  {
    QString modeString = modeElem.attribute( "name" );
    if ( modeString == "equal" )
      r->setMode( EqualInterval );
    else if ( modeString == "quantile" )
      r->setMode( Quantile );
    else if ( modeString == "jenks" )
      r->setMode( Jenks );
    else if ( modeString == "stddev" )
      r->setMode( StdDev );
    else if ( modeString == "pretty" )
      r->setMode( Pretty );
  }

  QDomElement rotationElem = element.firstChildElement( "rotation" );
  if ( !rotationElem.isNull() && !rotationElem.attribute( "field" ).isEmpty() )
  {
    for ( QgsRangeList::iterator it = r->mRanges.begin(); it != r->mRanges.end(); ++it )
    {
      convertSymbolRotation( it->symbol(), rotationElem.attribute( "field" ) );
    }
    if ( r->mSourceSymbol.data() )
    {
      convertSymbolRotation( r->mSourceSymbol.data(), rotationElem.attribute( "field" ) );
    }
  }

  QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
  if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( "field" ).isEmpty() )
  {
    for ( QgsRangeList::iterator it = r->mRanges.begin(); it != r->mRanges.end(); ++it )
    {
      convertSymbolSizeScale( it->symbol(),
                              QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ),
                              sizeScaleElem.attribute( "field" ) );
    }
    if ( r->mSourceSymbol.data() && r->mSourceSymbol->type() == QgsSymbolV2::Marker )
    {
      convertSymbolSizeScale( r->mSourceSymbol.data(),
                              QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ),
                              sizeScaleElem.attribute( "field" ) );
    }
  }

  QDomElement labelFormatElem = element.firstChildElement( "labelformat" );
  if ( ! labelFormatElem.isNull() )
  {
    QgsRendererRangeV2LabelFormat labelFormat;
    labelFormat.setFromDomElement( labelFormatElem );
    r->setLabelFormat( labelFormat );
  }
  // TODO: symbol levels
  return r;
}