29 #include <QDomDocument> 30 #include <QDomElement> 115 if ( !
mSymbol.data() || props.value(
"attribute",
"" ).isEmpty() )
118 QString attrName = props[
"attribute" ];
120 QDomElement ruleElem = doc.createElement(
"se:Rule" );
121 element.appendChild( ruleElem );
123 QDomElement nameElem = doc.createElement(
"se:Name" );
124 nameElem.appendChild( doc.createTextNode(
mLabel ) );
125 ruleElem.appendChild( nameElem );
127 QDomElement descrElem = doc.createElement(
"se:Description" );
128 QDomElement titleElem = doc.createElement(
"se:Title" );
129 QString descrStr = QString(
"%1 is '%2'" ).arg( attrName ).arg(
mValue.toString() );
130 titleElem.appendChild( doc.createTextNode( !
mLabel.isEmpty() ?
mLabel : descrStr ) );
131 descrElem.appendChild( titleElem );
132 ruleElem.appendChild( descrElem );
135 QString filterFunc = QString(
"%1 = '%2'" )
136 .arg( attrName.replace(
"\"",
"\"\"" ) )
137 .arg(
mValue.toString().replace(
"'",
"''" ) );
140 mSymbol->toSld( doc, ruleElem, props );
147 , mAttrName( attrName )
148 , mCategories( categories )
149 , mInvertedColorRamp( false )
157 if ( cat.
symbol() == NULL )
159 QgsDebugMsg(
"invalid symbol in a category! ignoring..." );
184 QHash<QString, QgsSymbolV2*>::iterator it =
mSymbolHash.find( value.isNull() ?
"" : value.toString() );
211 const double rotation =
mRotation.data() ?
mRotation->evaluate( feature ).toDouble() : 0;
222 markerSymbol->
setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
228 lineSymbol->
setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
292 if ( catIndex < 0 || catIndex >=
mCategories.size() )
300 if ( catIndex < 0 || catIndex >=
mCategories.size() )
308 if ( catIndex < 0 || catIndex >=
mCategories.size() )
316 if ( catIndex < 0 || catIndex >=
mCategories.size() )
326 QgsDebugMsg(
"invalid symbol in a category! ignoring..." );
335 if ( catIndex < 0 || catIndex >=
mCategories.size() )
364 if ( order == Qt::AscendingOrder )
376 return QString::localeAwareCompare( c1.
label(), c2.
label() ) < 0;
386 if ( order == Qt::AscendingOrder )
411 QgsCategoryList::iterator it =
mCategories.begin();
414 it->symbol()->startRender( context, &fields );
429 QgsCategoryList::iterator it =
mCategories.begin();
431 it->symbol()->stopRender( context );
434 QHash<QgsSymbolV2*, QgsSymbolV2*>::iterator it2 =
mTempSymbols.begin();
437 it2.value()->stopRender( context );
446 QSet<QString> attributes;
461 QgsCategoryList::const_iterator catIt =
mCategories.constBegin();
470 return attributes.toList();
475 QString s = QString(
"CATEGORIZED: idx %1\n" ).arg(
mAttrName );
503 props[
"angle" ] =
mRotation->expression();
511 it->toSld( doc, element, catProps );
525 QDomElement symbolsElem = element.firstChildElement(
"symbols" );
526 if ( symbolsElem.isNull() )
529 QDomElement catsElem = element.firstChildElement(
"categories" );
530 if ( catsElem.isNull() )
536 QDomElement catElem = catsElem.firstChildElement();
537 while ( !catElem.isNull() )
539 if ( catElem.tagName() ==
"category" )
541 QVariant value = QVariant( catElem.attribute(
"value" ) );
542 QString symbolName = catElem.attribute(
"symbol" );
543 QString label = catElem.attribute(
"label" );
544 bool render = catElem.attribute(
"render" ) !=
"false";
545 if ( symbolMap.contains( symbolName ) )
547 QgsSymbolV2* symbol = symbolMap.take( symbolName );
551 catElem = catElem.nextSiblingElement();
554 QString attrName = element.attribute(
"attr" );
562 QDomElement sourceSymbolElem = element.firstChildElement(
"source-symbol" );
563 if ( !sourceSymbolElem.isNull() )
566 if ( sourceSymbolMap.contains(
"0" ) )
574 QDomElement sourceColorRampElem = element.firstChildElement(
"colorramp" );
575 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute(
"name" ) ==
"[source]" )
578 QDomElement invertedColorRampElem = element.firstChildElement(
"invertedcolorramp" );
579 if ( !invertedColorRampElem.isNull() )
583 QDomElement rotationElem = element.firstChildElement(
"rotation" );
584 if ( !rotationElem.isNull() )
587 QDomElement sizeScaleElem = element.firstChildElement(
"sizescale" );
588 if ( !sizeScaleElem.isNull() )
601 rendererElem.setAttribute(
"type",
"categorizedSymbol" );
603 rendererElem.setAttribute(
"attr",
mAttrName );
608 QDomElement catsElem = doc.createElement(
"categories" );
609 QgsCategoryList::const_iterator it =
mCategories.constBegin();
613 QString symbolName = QString::number( i );
614 symbols.insert( symbolName, cat.
symbol() );
616 QDomElement catElem = doc.createElement(
"category" );
617 catElem.setAttribute(
"value", cat.
value().toString() );
618 catElem.setAttribute(
"symbol", symbolName );
619 catElem.setAttribute(
"label", cat.
label() );
620 catElem.setAttribute(
"render", cat.
renderState() ?
"true" :
"false" );
621 catsElem.appendChild( catElem );
625 rendererElem.appendChild( catsElem );
629 rendererElem.appendChild( symbolsElem );
637 rendererElem.appendChild( sourceSymbolElem );
644 rendererElem.appendChild( colorRampElem );
645 QDomElement invertedElem = doc.createElement(
"invertedcolorramp" );
647 rendererElem.appendChild( invertedElem );
650 QDomElement rotationElem = doc.createElement(
"rotation" );
653 rendererElem.appendChild( rotationElem );
655 QDomElement sizeScaleElem = doc.createElement(
"sizescale" );
659 rendererElem.appendChild( sizeScaleElem );
668 for (
int i = 0; i < count; i++ )
672 lst << qMakePair( cat.
label(), pix );
679 Q_UNUSED( scaleDenominator );
684 if ( rule.isEmpty() || cat.
label() == rule )
729 double value = count / num;
771 QgsCategoryList::const_iterator catIt =
mCategories.constBegin();
786 int index = key.toInt( &ok );
787 if ( ok && index >= 0 && index <
mCategories.size() )
796 int index = key.toInt( &ok );
805 if ( renderer->
type() ==
"categorizedSymbol" )
809 if ( renderer->
type() ==
"pointDisplacement" )
812 if ( pointDisplacementRenderer )
815 if ( renderer->
type() ==
"invertedPolygonRenderer" )
818 if ( invertedPolygonRenderer )
827 if ( symbols.size() > 0 )
829 r->setSourceSymbol( symbols.at( 0 )->clone() );
QMap< QString, QgsSymbolV2 * > QgsSymbolV2Map
Class for parsing and evaluation of expressions (formerly called "search strings").
static QgsSymbolV2Map loadSymbols(QDomElement &element)
void setValue(const QVariant &value)
void setLabel(const QString &label)
#define RENDERER_TAG_NAME
QgsSymbolV2::ScaleMethod mScaleMethod
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
virtual void stopRender(QgsRenderContext &context) override
virtual QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feature) override
Return symbol for feature.
QStringList referencedColumns() const
Get list of columns referenced by the expression.
virtual bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
const QgsCategoryList & categories() const
static QgsVectorColorRampV2 * loadColorRamp(QDomElement &element)
QgsVectorColorRampV2 * sourceColorRamp()
QList< QgsSymbolV2 * > QgsSymbolV2List
QSet< QString > usedAttributes() const
void setSourceSymbol(QgsSymbolV2 *sym)
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
double rendererScale() const
virtual QgsSymbolV2 * clone() const =0
int categoryIndexForLabel(QString val)
return index of category with specified label (-1 if not found or not unique)
QScopedPointer< QgsSymbolV2 > mSourceSymbol
bool updateCategoryRenderState(int catIndex, bool render)
QScopedPointer< QgsExpression > mRotation
Container of fields for a vector layer.
virtual void setTotalColorCount(const int colorCount)
void moveCategory(int from, int to)
Moves the category at index position from to index position to.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
void setSizeScaleField(QString fieldOrExpression)
QScopedPointer< QgsSymbolV2 > mSymbol
QMap< QString, QString > QgsStringMap
void setSourceColorRamp(QgsVectorColorRampV2 *ramp)
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
void setWidth(double width)
QHash< QString, QgsSymbolV2 * > mSymbolHash
hashtable for faster access to symbols
virtual QDomElement save(QDomDocument &doc) override
store renderer info to XML element
QString rotationField() const override
return rotation field name (or empty string if not set or not supported by renderer) ...
QScopedPointer< QgsExpression > mSizeScale
QgsCategoryList mCategories
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
void updateSymbols(QgsSymbolV2 *sym)
void setColor(const QColor &color)
void deleteAllCategories()
virtual QgsFeatureRendererV2 * clone() const =0
QList< QgsRendererCategoryV2 > QgsCategoryList
static QDomElement saveColorRamp(QString name, QgsVectorColorRampV2 *ramp, QDomDocument &doc)
virtual void toSld(QDomDocument &doc, QDomElement &element) const override
used from subclasses to create SLD Rule elements following SLD v1.1 specs
QScopedPointer< QgsVectorColorRampV2 > mSourceColorRamp
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted...
#define QgsDebugMsgLevel(str, level)
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule=QString()) override
return a list of item text / symbol
bool labelGreaterThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
#define DEFAULT_SCALE_METHOD
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, QString function)
QgsSymbolV2 * symbolForValue(QVariant value)
virtual ~QgsCategorizedSymbolRendererV2()
static QDomElement saveSymbols(QgsSymbolV2Map &symbols, QString tagName, QDomDocument &doc)
static QgsFeatureRendererV2 * create(QDomElement &element)
create renderer from XML element
int categoryIndexForValue(QVariant val)
return index of category with specified value (-1 if not found)
void setAngle(double angle)
const QgsAttributes & attributes() const
static QgsMarkerSymbolV2 sSkipRender
virtual void startRender(QgsRenderContext &context, const QgsFields &fields) override
void setSize(double size)
virtual void checkLegendSymbolItem(QString key, bool state=true) override
item in symbology was checked
virtual QgsFeatureRendererV2 * clone() const override
void setRenderState(bool render)
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
bool labelLessThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
static QgsCategorizedSymbolRendererV2 * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsCategorizedSymbolRendererV2 from an existing renderer.
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
QgsFeatureRendererV2 * embeddedRenderer() const
void updateColorRamp(QgsVectorColorRampV2 *ramp, bool inverted=false)
QHash< QgsSymbolV2 *, QgsSymbolV2 * > mTempSymbols
temporary symbols, used for data-defined rotation and scaling
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props) const
virtual bool legendSymbolItemChecked(QString key) override
item in symbology was checked
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature) override
to be overridden
A renderer that automatically displaces points with the same position.
bool updateCategoryLabel(int catIndex, QString label)
void setUsingSymbolLevels(bool usingSymbolLevels)
void setSymbol(QgsSymbolV2 *s)
bool valueLessThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
Contains information about the context of a rendering operation.
const QgsFeatureRendererV2 * embeddedRenderer() const
QgsSymbolV2 * sourceSymbol()
virtual QList< QString > usedAttributes() override
QgsCategorizedSymbolRendererV2(QString attrName=QString(), QgsCategoryList categories=QgsCategoryList())
static QgsExpression * fieldOrExpressionToExpression(const QString &fieldOrExpression)
Return a new valid expression instance for given field or expression string.
static QString encodeScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
bool updateCategoryValue(int catIndex, const QVariant &value)
bool deleteCategory(int catIndex)
bool valueGreaterThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
static QString fieldOrExpressionFromExpression(QgsExpression *expression)
Return a field name if the whole expression is just a name of the field .
bool usingSymbolLevels() const
void setScaleMethodToSymbol(QgsSymbolV2 *symbol, int scaleMethod)
QString sizeScaleField() const
bool updateCategorySymbol(int catIndex, QgsSymbolV2 *symbol)
int mAttrNum
attribute index (derived from attribute name in startRender)
void setRenderHints(int hints)
static void clearSymbolMap(QgsSymbolV2Map &symbols)
void setRotationField(QString fieldOrExpression) override
sets rotation field of renderer (if supported by the renderer)
static QgsSymbolV2::ScaleMethod decodeScaleMethod(QString str)
void swap(QgsRendererCategoryV2 &other)
QgsRendererCategoryV2 & operator=(QgsRendererCategoryV2 cat)
QgsSymbolV2::ScaleMethod scaleMethod() const
virtual QgsSymbolV2List symbols() override
for symbol levels
static QPixmap symbolPreviewPixmap(QgsSymbolV2 *symbol, QSize size, QgsRenderContext *customContext=0)
void addCategory(const QgsRendererCategoryV2 &category)
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
QgsSymbolV2 * symbol() const
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize) override
return a list of symbology items for the legend
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
QScopedPointer< QgsExpression > mExpression
void setInvertedColorRamp(bool inverted)
virtual QString dump() const override
for debugging