QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone() { 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() ); 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->setSizeScaleField( sizeScaleField() ); r->setLabelFormat( labelFormat() ); r->setGraduatedMethod( graduatedMethod() ); copyPaintEffect( r ); 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; }
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; }