[QGIS Commit] r11909 - in branches/symbology-ng-branch: python/core
src/app/legend src/core src/core/symbology-ng src/gui/symbology-ng
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Tue Nov 3 12:32:39 EST 2009
Author: wonder
Date: 2009-11-03 12:32:36 -0500 (Tue, 03 Nov 2009)
New Revision: 11909
Added:
branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h
branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.h
Modified:
branches/symbology-ng-branch/python/core/symbology-ng-core.sip
branches/symbology-ng-branch/src/app/legend/qgslegendlayer.cpp
branches/symbology-ng-branch/src/core/CMakeLists.txt
branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h
branches/symbology-ng-branch/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp
Log:
split code of renderers into several files
Modified: branches/symbology-ng-branch/python/core/symbology-ng-core.sip
===================================================================
--- branches/symbology-ng-branch/python/core/symbology-ng-core.sip 2009-11-03 16:18:14 UTC (rev 11908)
+++ branches/symbology-ng-branch/python/core/symbology-ng-core.sip 2009-11-03 17:32:36 UTC (rev 11909)
@@ -78,7 +78,7 @@
class QgsSingleSymbolRendererV2 : QgsFeatureRendererV2
{
%TypeHeaderCode
-#include <qgsrendererv2.h>
+#include <qgssinglesymbolrendererv2.h>
%End
public:
@@ -108,7 +108,7 @@
class QgsRendererCategoryV2
{
%TypeHeaderCode
-#include <qgsrendererv2.h>
+#include <qgscategorizedsymbolrendererv2.h>
%End
public:
@@ -135,7 +135,7 @@
class QgsCategorizedSymbolRendererV2 : QgsFeatureRendererV2
{
%TypeHeaderCode
-#include <qgsrendererv2.h>
+#include <qgscategorizedsymbolrendererv2.h>
%End
public:
@@ -180,7 +180,7 @@
class QgsRendererRangeV2
{
%TypeHeaderCode
-#include <qgsrendererv2.h>
+#include <qgsgraduatedsymbolrendererv2.h>
%End
public:
@@ -206,7 +206,7 @@
class QgsGraduatedSymbolRendererV2 : QgsFeatureRendererV2
{
%TypeHeaderCode
-#include <qgsrendererv2.h>
+#include <qgsgraduatedsymbolrendererv2.h>
%End
public:
Modified: branches/symbology-ng-branch/src/app/legend/qgslegendlayer.cpp
===================================================================
--- branches/symbology-ng-branch/src/app/legend/qgslegendlayer.cpp 2009-11-03 16:18:14 UTC (rev 11908)
+++ branches/symbology-ng-branch/src/app/legend/qgslegendlayer.cpp 2009-11-03 17:32:36 UTC (rev 11909)
@@ -39,6 +39,10 @@
#include "qgsrendererv2.h"
#include "qgssymbolv2.h"
+#include "qgssinglesymbolrendererv2.h"
+#include "qgscategorizedsymbolrendererv2.h"
+#include "qgsgraduatedsymbolrendererv2.h"
+
#include <iostream>
#include <QAction>
#include <QCoreApplication>
Modified: branches/symbology-ng-branch/src/core/CMakeLists.txt
===================================================================
--- branches/symbology-ng-branch/src/core/CMakeLists.txt 2009-11-03 16:18:14 UTC (rev 11908)
+++ branches/symbology-ng-branch/src/core/CMakeLists.txt 2009-11-03 17:32:36 UTC (rev 11909)
@@ -13,6 +13,9 @@
symbology-ng/qgsmarkersymbollayerv2.cpp
symbology-ng/qgsfillsymbollayerv2.cpp
symbology-ng/qgsrendererv2.cpp
+ symbology-ng/qgssinglesymbolrendererv2.cpp
+ symbology-ng/qgscategorizedsymbolrendererv2.cpp
+ symbology-ng/qgsgraduatedsymbolrendererv2.cpp
symbology-ng/qgsvectorcolorrampv2.cpp
symbology-ng/qgsstylev2.cpp
Added: branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp (rev 0)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp 2009-11-03 17:32:36 UTC (rev 11909)
@@ -0,0 +1,290 @@
+
+#include "qgscategorizedsymbolrendererv2.h"
+
+#include "qgssymbolv2.h"
+#include "qgssymbollayerv2utils.h"
+
+#include "qgsfeature.h"
+#include "qgslogger.h"
+
+#include <QDomDocument>
+#include <QDomElement>
+
+QgsRendererCategoryV2::QgsRendererCategoryV2(QVariant value, QgsSymbolV2* symbol, QString label)
+ : mValue(value), mSymbol(symbol), mLabel(label)
+{
+}
+
+QgsRendererCategoryV2::QgsRendererCategoryV2(const QgsRendererCategoryV2& cat)
+ : mValue(cat.mValue), mLabel(cat.mLabel)
+{
+ mSymbol = cat.mSymbol->clone();
+}
+
+
+QgsRendererCategoryV2::~QgsRendererCategoryV2()
+{
+ delete mSymbol;
+}
+
+QVariant QgsRendererCategoryV2::value() const
+{
+ return mValue;
+}
+
+QgsSymbolV2* QgsRendererCategoryV2::symbol() const
+{
+ return mSymbol;
+}
+
+QString QgsRendererCategoryV2::label() const
+{
+ return mLabel;
+}
+
+void QgsRendererCategoryV2::setSymbol(QgsSymbolV2* s)
+{
+ if (mSymbol == s)
+ return;
+ delete mSymbol;
+ mSymbol = s;
+}
+
+void QgsRendererCategoryV2::setLabel(QString label)
+{
+ mLabel = label;
+}
+
+QString QgsRendererCategoryV2::dump()
+{
+ return QString("%1::%2::%3\n").arg(mValue.toString()).arg(mLabel).arg(mSymbol->dump());
+}
+
+///////////////////
+
+QgsCategorizedSymbolRendererV2::QgsCategorizedSymbolRendererV2(QString attrName, QgsCategoryList categories)
+ : QgsFeatureRendererV2(RendererCategorizedSymbol), mAttrName(attrName), mCategories(categories)
+{
+ for (int i = 0; i < mCategories.count(); ++i)
+ {
+ QgsRendererCategoryV2& cat = mCategories[i];
+ if (cat.symbol() == NULL)
+ {
+ QgsDebugMsg("invalid symbol in a category! ignoring...");
+ mCategories.removeAt(i--);
+ }
+ //mCategories.insert(cat.value().toString(), cat);
+ }
+}
+
+QgsCategorizedSymbolRendererV2::~QgsCategorizedSymbolRendererV2()
+{
+ mCategories.clear(); // this should also call destructors of symbols
+}
+
+void QgsCategorizedSymbolRendererV2::rebuildHash()
+{
+ mSymbolHash.clear();
+
+ for (int i = 0; i < mCategories.count(); ++i)
+ {
+ QgsRendererCategoryV2& cat = mCategories[i];
+ mSymbolHash.insert(cat.value().toString(), cat.symbol());
+ }
+}
+
+QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue(QVariant value)
+{
+ // TODO: special case for int, double
+
+ QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find(value.toString());
+ if (it == mSymbolHash.end())
+ {
+ if (mSymbolHash.count() == 0)
+ QgsDebugMsg("there are no hashed symbols!!!");
+ else
+ QgsDebugMsg("attribute value not found: " + value.toString());
+ return NULL;
+ }
+ else
+ return *it;
+}
+
+QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature(QgsFeature& feature)
+{
+ const QgsAttributeMap& attrMap = feature.attributeMap();
+ QgsAttributeMap::const_iterator ita = attrMap.find(mAttrNum);
+ if (ita == attrMap.end())
+ {
+ QgsDebugMsg("attribute '"+mAttrName+"' (index "+QString::number(mAttrNum)+") required by renderer not found");
+ return NULL;
+ }
+
+ // find the right category
+ return symbolForValue(*ita);
+}
+
+int QgsCategorizedSymbolRendererV2::categoryIndexForValue(QVariant val)
+{
+ for (int i = 0; i < mCategories.count(); i++)
+ {
+ if (mCategories[i].value() == val)
+ return i;
+ }
+ return -1;
+}
+
+bool QgsCategorizedSymbolRendererV2::updateCategorySymbol(int catIndex, QgsSymbolV2* symbol)
+{
+ if (catIndex < 0 || catIndex >= mCategories.size())
+ return false;
+ mCategories[catIndex].setSymbol(symbol);
+ return true;
+}
+
+bool QgsCategorizedSymbolRendererV2::updateCategoryLabel(int catIndex, QString label)
+{
+ if (catIndex < 0 || catIndex >= mCategories.size())
+ return false;
+ mCategories[catIndex].setLabel(label);
+ return true;
+}
+
+bool QgsCategorizedSymbolRendererV2::deleteCategory(int catIndex)
+{
+ if (catIndex < 0 || catIndex >= mCategories.size())
+ return false;
+
+ mCategories.removeAt(catIndex);
+ return true;
+}
+
+void QgsCategorizedSymbolRendererV2::deleteAllCategories()
+{
+ mCategories.clear();
+}
+
+void QgsCategorizedSymbolRendererV2::startRender(QgsRenderContext& context, const QgsFieldMap& fields)
+{
+ // make sure that the hash table is up to date
+ rebuildHash();
+
+ // find out classification attribute index from name
+ mAttrNum = fieldNameIndex(fields, mAttrName);
+
+ QgsCategoryList::iterator it = mCategories.begin();
+ for ( ; it != mCategories.end(); ++it)
+ it->symbol()->startRender(context);
+}
+
+void QgsCategorizedSymbolRendererV2::stopRender(QgsRenderContext& context)
+{
+ QgsCategoryList::iterator it = mCategories.begin();
+ for ( ; it != mCategories.end(); ++it)
+ it->symbol()->stopRender(context);
+}
+
+QList<QString> QgsCategorizedSymbolRendererV2::usedAttributes()
+{
+ QList<QString> lst;
+ lst.append(mAttrName);
+ return lst;
+}
+
+QString QgsCategorizedSymbolRendererV2::dump()
+{
+ QString s = QString("CATEGORIZED: idx %1\n").arg(mAttrName);
+ for (int i=0; i<mCategories.count();i++)
+ s += mCategories[i].dump();
+ return s;
+}
+
+QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
+{
+ QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( mAttrName, mCategories );
+ r->setUsingSymbolLevels( usingSymbolLevels() );
+ return r;
+}
+
+QgsSymbolV2List QgsCategorizedSymbolRendererV2::symbols()
+{
+ QgsSymbolV2List lst;
+ for (int i = 0; i < mCategories.count(); i++)
+ lst.append(mCategories[i].symbol());
+ return lst;
+}
+
+QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create(QDomElement& element)
+{
+ QDomElement symbolsElem = element.firstChildElement("symbols");
+ if (symbolsElem.isNull())
+ return NULL;
+
+ QDomElement catsElem = element.firstChildElement("categories");
+ if (catsElem.isNull())
+ return NULL;
+
+ QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
+ QgsCategoryList cats;
+
+ QDomElement catElem = catsElem.firstChildElement();
+ while (!catElem.isNull())
+ {
+ if (catElem.tagName() == "category")
+ {
+ QVariant value = QVariant(catElem.attribute("value"));
+ QString symbolName = catElem.attribute("symbol");
+ QString label = catElem.attribute("label");
+ if (symbolMap.contains(symbolName))
+ {
+ QgsSymbolV2* symbol = symbolMap.take(symbolName);
+ cats.append( QgsRendererCategoryV2(value, symbol, label) );
+ }
+ }
+ catElem = catElem.nextSiblingElement();
+ }
+
+ QString attrName = element.attribute("attr");
+
+ QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2(attrName, cats);
+
+ // delete symbols if there are any more
+ QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
+
+ // TODO: symbol levels
+ return r;
+}
+
+QDomElement QgsCategorizedSymbolRendererV2::save(QDomDocument& doc)
+{
+ QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
+ rendererElem.setAttribute("type", "categorizedSymbol");
+ rendererElem.setAttribute("attr", mAttrName);
+
+ // categories
+ int i = 0;
+ QgsSymbolV2Map symbols;
+ QDomElement catsElem = doc.createElement("categories");
+ QgsCategoryList::const_iterator it = mCategories.constBegin();
+ for ( ; it != mCategories.end(); it++)
+ {
+ const QgsRendererCategoryV2& cat = *it;
+ QString symbolName = QString::number(i);
+ symbols.insert(symbolName, cat.symbol());
+
+ QDomElement catElem = doc.createElement("category");
+ catElem.setAttribute("value", cat.value().toString());
+ catElem.setAttribute("symbol", symbolName);
+ catElem.setAttribute("label", cat.label());
+ catsElem.appendChild(catElem);
+ i++;
+ }
+
+ rendererElem.appendChild(catsElem);
+
+ // save symbols
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
+ rendererElem.appendChild(symbolsElem);
+
+ return rendererElem;
+}
Added: branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h (rev 0)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h 2009-11-03 17:32:36 UTC (rev 11909)
@@ -0,0 +1,97 @@
+#ifndef QGSCATEGORIZEDSYMBOLRENDERERV2_H
+#define QGSCATEGORIZEDSYMBOLRENDERERV2_H
+
+#include "qgsrendererv2.h"
+
+#include <QHash>
+
+
+class QgsRendererCategoryV2
+{
+public:
+
+ //! takes ownership of symbol
+ QgsRendererCategoryV2(QVariant value, QgsSymbolV2* symbol, QString label);
+
+ //! copy constructor
+ QgsRendererCategoryV2(const QgsRendererCategoryV2& cat);
+
+ ~QgsRendererCategoryV2();
+
+ QVariant value() const;
+ QgsSymbolV2* symbol() const;
+ QString label() const;
+
+ void setSymbol(QgsSymbolV2* s);
+ void setLabel(QString label);
+
+ // debugging
+ QString dump();
+
+protected:
+ QVariant mValue;
+ QgsSymbolV2* mSymbol;
+ QString mLabel;
+};
+
+typedef QList<QgsRendererCategoryV2> QgsCategoryList;
+
+class QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
+{
+public:
+
+ QgsCategorizedSymbolRendererV2(QString attrName = QString(), QgsCategoryList categories = QgsCategoryList());
+
+ virtual ~QgsCategorizedSymbolRendererV2();
+
+ virtual QgsSymbolV2* symbolForFeature(QgsFeature& feature);
+
+ virtual void startRender(QgsRenderContext& context, const QgsFieldMap& fields);
+
+ virtual void stopRender(QgsRenderContext& context);
+
+ virtual QList<QString> usedAttributes();
+
+ virtual QString dump();
+
+ virtual QgsFeatureRendererV2* clone();
+
+ virtual QgsSymbolV2List symbols();
+
+ const QgsCategoryList& categories() { return mCategories; }
+
+ //! return index of category with specified value (-1 if not found)
+ int categoryIndexForValue(QVariant val);
+
+ bool updateCategorySymbol(int catIndex, QgsSymbolV2* symbol);
+ bool updateCategoryLabel(int catIndex, QString label);
+
+ bool deleteCategory(int catIndex);
+ void deleteAllCategories();
+
+ QString classAttribute() const { return mAttrName; }
+ void setClassAttribute(QString attr) { mAttrName = attr; }
+
+ //! create renderer from XML element
+ static QgsFeatureRendererV2* create(QDomElement& element);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
+
+protected:
+ QgsCategoryList mCategories;
+ QString mAttrName;
+
+ //! attribute index (derived from attribute name in startRender)
+ int mAttrNum;
+
+ //! hashtable for faster access to symbols
+ QHash<QString, QgsSymbolV2*> mSymbolHash;
+
+ void rebuildHash();
+
+ QgsSymbolV2* symbolForValue(QVariant value);
+};
+
+
+#endif // QGSCATEGORIZEDSYMBOLRENDERERV2_H
Added: branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp (rev 0)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp 2009-11-03 17:32:36 UTC (rev 11909)
@@ -0,0 +1,358 @@
+
+#include "qgsgraduatedsymbolrendererv2.h"
+
+#include "qgssymbolv2.h"
+#include "qgssymbollayerv2utils.h"
+
+#include "qgsfeature.h"
+#include "qgslogger.h"
+
+#include <QDomDocument>
+#include <QDomElement>
+
+QgsRendererRangeV2::QgsRendererRangeV2(double lowerValue, double upperValue, QgsSymbolV2* symbol, QString label)
+ : mLowerValue(lowerValue), mUpperValue(upperValue), mSymbol(symbol), mLabel(label)
+{
+}
+
+QgsRendererRangeV2::QgsRendererRangeV2(const QgsRendererRangeV2& range)
+ : mLowerValue(range.mLowerValue), mUpperValue(range.mUpperValue), mLabel(range.mLabel)
+{
+ mSymbol = range.mSymbol->clone();
+}
+
+QgsRendererRangeV2::~QgsRendererRangeV2()
+{
+ delete mSymbol;
+}
+
+double QgsRendererRangeV2::lowerValue() const
+{
+ return mLowerValue;
+}
+
+double QgsRendererRangeV2::upperValue() const
+{
+ return mUpperValue;
+}
+
+QgsSymbolV2* QgsRendererRangeV2::symbol() const
+{
+ return mSymbol;
+}
+
+QString QgsRendererRangeV2::label() const
+{
+ return mLabel;
+}
+
+void QgsRendererRangeV2::setSymbol(QgsSymbolV2* s)
+{
+ if (mSymbol == s)
+ return;
+ delete mSymbol;
+ mSymbol = s;
+}
+
+void QgsRendererRangeV2::setLabel(QString label)
+{
+ mLabel = label;
+}
+
+QString QgsRendererRangeV2::dump()
+{
+ return QString("%1 - %2::%3::%4\n").arg(mLowerValue).arg(mUpperValue).arg(mLabel).arg(mSymbol->dump());
+}
+
+///////////
+
+
+QgsGraduatedSymbolRendererV2::QgsGraduatedSymbolRendererV2(QString attrName, QgsRangeList ranges)
+ : QgsFeatureRendererV2(RendererGraduatedSymbol), mAttrName(attrName), mRanges(ranges), mMode(Custom)
+{
+ // TODO: check ranges for sanity (NULL symbols, invalid ranges)
+}
+
+QgsGraduatedSymbolRendererV2::~QgsGraduatedSymbolRendererV2()
+{
+ mRanges.clear(); // should delete all the symbols
+}
+
+QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForValue(double value)
+{
+ for (QgsRangeList::iterator it = mRanges.begin(); it != mRanges.end(); ++it)
+ {
+ if (it->lowerValue() <= value && it->upperValue() >= value)
+ return it->symbol();
+ }
+ // the value is out of the range: return NULL instead of symbol
+ return NULL;
+}
+
+QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature(QgsFeature& feature)
+{
+ const QgsAttributeMap& attrMap = feature.attributeMap();
+ QgsAttributeMap::const_iterator ita = attrMap.find(mAttrNum);
+ if (ita == attrMap.end())
+ {
+ QgsDebugMsg("attribute required by renderer not found: "+mAttrName+"(index "+QString::number(mAttrNum)+")");
+ return NULL;
+ }
+
+ // find the right category
+ return symbolForValue(ita->toDouble());
+
+}
+
+void QgsGraduatedSymbolRendererV2::startRender(QgsRenderContext& context, const QgsFieldMap& fields)
+{
+ // find out classification attribute index from name
+ mAttrNum = fieldNameIndex(fields, mAttrName);
+
+ QgsRangeList::iterator it = mRanges.begin();
+ for ( ; it != mRanges.end(); ++it)
+ it->symbol()->startRender(context);
+}
+
+void QgsGraduatedSymbolRendererV2::stopRender(QgsRenderContext& context)
+{
+ QgsRangeList::iterator it = mRanges.begin();
+ for ( ; it != mRanges.end(); ++it)
+ it->symbol()->startRender(context);
+}
+
+QList<QString> QgsGraduatedSymbolRendererV2::usedAttributes()
+{
+ QList<QString> lst;
+ lst.append( mAttrName );
+ return lst;
+}
+
+bool QgsGraduatedSymbolRendererV2::updateRangeSymbol(int rangeIndex, QgsSymbolV2* symbol)
+{
+ if (rangeIndex < 0 || rangeIndex >= mRanges.size())
+ return false;
+ mRanges[rangeIndex].setSymbol(symbol);
+ return true;
+}
+
+bool QgsGraduatedSymbolRendererV2::updateRangeLabel(int rangeIndex, QString label)
+{
+ if (rangeIndex < 0 || rangeIndex >= mRanges.size())
+ return false;
+ mRanges[rangeIndex].setLabel(label);
+ return true;
+}
+
+QString QgsGraduatedSymbolRendererV2::dump()
+{
+ QString s = QString("GRADUATED: attr %1\n").arg(mAttrName);
+ for (int i=0; i<mRanges.count();i++)
+ s += mRanges[i].dump();
+ return s;
+}
+
+QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone()
+{
+ QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( mAttrName, mRanges );
+ r->setUsingSymbolLevels( usingSymbolLevels() );
+ return r;
+}
+
+QgsSymbolV2List QgsGraduatedSymbolRendererV2::symbols()
+{
+ QgsSymbolV2List lst;
+ for (int i = 0; i < mRanges.count(); i++)
+ lst.append(mRanges[i].symbol());
+ return lst;
+}
+
+static QList<double> _calcEqualIntervalBreaks(double minimum, double maximum, int classes)
+{
+ double step = (maximum - minimum) / classes;
+
+ QList<double> breaks;
+ double value = minimum;
+ for (int i = 0; i < classes; i++)
+ {
+ value += step;
+ breaks.append( value );
+ }
+ return breaks;
+}
+
+static QList<double> _calcQuantileBreaks(QList<double> values, int classes)
+{
+ // sort the values first
+ qSort(values);
+
+ QList<double> breaks;
+
+ // q-th quantile of a data set:
+ // value where q fraction of data is below and (1-q) fraction is above this value
+ // Xq = (1 - r) * X_NI1 + r * X_NI2
+ // NI1 = (int) (q * (n+1))
+ // NI2 = NI1 + 1
+ // r = q * (n+1) - (int) (q * (n+1))
+ // (indices of X: 1...n)
+
+ int n = values.count();
+ double q,a,aa,r,Xq;
+ for (int i = 0; i < (classes-1); i++)
+ {
+ q = (i+1) / (double) classes;
+ a = q * n;
+ aa = (int) (q * n);
+
+ r = a - aa;
+ Xq = (1-r)* values[aa] + r * values[aa+1];
+
+ breaks.append( Xq );
+ }
+
+ breaks.append( values[ n-1 ] );
+
+ return breaks;
+}
+
+#include "qgsvectordataprovider.h"
+#include "qgsvectorcolorrampv2.h"
+
+QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
+ QgsVectorLayer* vlayer,
+ QString attrName,
+ int classes,
+ Mode mode,
+ QgsSymbolV2* symbol,
+ QgsVectorColorRampV2* ramp)
+{
+ QgsVectorDataProvider* provider = vlayer->dataProvider();
+
+ int attrNum = fieldNameIndex(vlayer->pendingFields(), attrName);
+
+ double minimum = provider->minimumValue( attrNum ).toDouble();
+ double maximum = provider->maximumValue( attrNum ).toDouble();
+ QgsDebugMsg(QString("min %1 // max %2").arg(minimum).arg(maximum));
+
+ QList<double> breaks;
+ if (mode == EqualInterval)
+ {
+ breaks = _calcEqualIntervalBreaks(minimum, maximum, classes);
+ }
+ else if (mode == Quantile)
+ {
+ // get values from layer
+ QList<double> values;
+ QgsFeature f;
+ QgsAttributeList lst;
+ lst.append(attrNum);
+ provider->select(lst, QgsRectangle(), false);
+ while (provider->nextFeature(f))
+ values.append(f.attributeMap()[attrNum].toDouble());
+ // calculate the breaks
+ breaks = _calcQuantileBreaks(values, classes);
+ }
+ 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;
+ label = QString::number(lower,'f',4) + " - " + QString::number(upper,'f',4);
+
+ QgsSymbolV2* newSymbol = symbol->clone();
+ newSymbol->setColor( ramp->color( (double) i / (classes-1) ) ); // color from (0 / cl-1) to (cl-1 / cl-1)
+
+ ranges.append( QgsRendererRangeV2(lower, upper, newSymbol, label) );
+ }
+
+ return new QgsGraduatedSymbolRendererV2( attrName, ranges );
+}
+
+
+
+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);
+
+ // TODO: symbol levels
+ return r;
+}
+
+QDomElement QgsGraduatedSymbolRendererV2::save(QDomDocument& doc)
+{
+ QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
+ rendererElem.setAttribute("type", "graduatedSymbol");
+ rendererElem.setAttribute("attr", mAttrName);
+
+ // ranges
+ int i = 0;
+ QgsSymbolV2Map symbols;
+ QDomElement rangesElem = doc.createElement("ranges");
+ QgsRangeList::const_iterator it = mRanges.constBegin();
+ for ( ; it != mRanges.end(); it++)
+ {
+ const QgsRendererRangeV2& range = *it;
+ QString symbolName = QString::number(i);
+ symbols.insert(symbolName, range.symbol());
+
+ QDomElement rangeElem = doc.createElement("range");
+ rangeElem.setAttribute("lower", range.lowerValue());
+ rangeElem.setAttribute("upper", range.upperValue());
+ rangeElem.setAttribute("symbol", symbolName);
+ rangeElem.setAttribute("label", range.label());
+ rangesElem.appendChild(rangeElem);
+ i++;
+ }
+
+ rendererElem.appendChild(rangesElem);
+
+ // save symbols
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
+ rendererElem.appendChild(symbolsElem);
+
+ return rendererElem;
+}
Added: branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h (rev 0)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h 2009-11-03 17:32:36 UTC (rev 11909)
@@ -0,0 +1,101 @@
+#ifndef QGSGRADUATEDSYMBOLRENDERERV2_H
+#define QGSGRADUATEDSYMBOLRENDERERV2_H
+
+#include "qgsrendererv2.h"
+
+class QgsRendererRangeV2
+{
+public:
+ QgsRendererRangeV2(double lowerValue, double upperValue, QgsSymbolV2* symbol, QString label);
+ QgsRendererRangeV2(const QgsRendererRangeV2& range);
+
+ ~QgsRendererRangeV2();
+
+ double lowerValue() const;
+ double upperValue() const;
+
+ QgsSymbolV2* symbol() const;
+ QString label() const;
+
+ void setSymbol(QgsSymbolV2* s);
+ void setLabel(QString label);
+
+ // debugging
+ QString dump();
+
+protected:
+ double mLowerValue, mUpperValue;
+ QgsSymbolV2* mSymbol;
+ QString mLabel;
+};
+
+typedef QList<QgsRendererRangeV2> QgsRangeList;
+
+class QgsVectorLayer;
+class QgsVectorColorRampV2;
+
+class QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
+{
+public:
+ QgsGraduatedSymbolRendererV2(QString attrName = QString(), QgsRangeList ranges = QgsRangeList());
+
+ virtual ~QgsGraduatedSymbolRendererV2();
+
+ virtual QgsSymbolV2* symbolForFeature(QgsFeature& feature);
+
+ virtual void startRender(QgsRenderContext& context, const QgsFieldMap& fields);
+
+ virtual void stopRender(QgsRenderContext& context);
+
+ virtual QList<QString> usedAttributes();
+
+ virtual QString dump();
+
+ virtual QgsFeatureRendererV2* clone();
+
+ virtual QgsSymbolV2List symbols();
+
+ QString classAttribute() const { return mAttrName; }
+ void setClassAttribute(QString attr) { mAttrName = attr; }
+
+ const QgsRangeList& ranges() { return mRanges; }
+
+ bool updateRangeSymbol(int rangeIndex, QgsSymbolV2* symbol);
+ bool updateRangeLabel(int rangeIndex, QString label);
+
+ enum Mode
+ {
+ EqualInterval,
+ Quantile,
+ Custom
+ };
+
+ Mode mode() const { return mMode; }
+ void setMode(Mode mode) { mMode = mode; }
+
+ static QgsGraduatedSymbolRendererV2* createRenderer(
+ QgsVectorLayer* vlayer,
+ QString attrName,
+ int classes,
+ Mode mode,
+ QgsSymbolV2* symbol,
+ QgsVectorColorRampV2* ramp);
+
+ //! create renderer from XML element
+ static QgsFeatureRendererV2* create(QDomElement& element);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
+
+protected:
+ QgsRangeList mRanges;
+ QString mAttrName;
+ Mode mMode;
+
+ //! attribute index (derived from attribute name in startRender)
+ int mAttrNum;
+
+ QgsSymbolV2* symbolForValue(double value);
+};
+
+#endif // QGSGRADUATEDSYMBOLRENDERERV2_H
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp 2009-11-03 16:18:14 UTC (rev 11908)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp 2009-11-03 17:32:36 UTC (rev 11909)
@@ -1,3 +1,4 @@
+
#include "qgsrendererv2.h"
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
@@ -2,2 +3,8 @@
+#include "qgssinglesymbolrendererv2.h" // for default renderer
+
+// TODO: to be removed once renderer registry is in place
+#include "qgscategorizedsymbolrendererv2.h"
+#include "qgsgraduatedsymbolrendererv2.h"
+
#include "qgsrendercontext.h"
@@ -294,731 +301,3 @@
}
return -1;
}
-
-///////////////////
-
-QgsSingleSymbolRendererV2::QgsSingleSymbolRendererV2(QgsSymbolV2* symbol)
- : QgsFeatureRendererV2(RendererSingleSymbol)
-{
- mSymbol = symbol;
-}
-
-QgsSingleSymbolRendererV2::~QgsSingleSymbolRendererV2()
-{
- delete mSymbol;
-}
-
-QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature(QgsFeature& feature)
-{
- return mSymbol;
-}
-
-void QgsSingleSymbolRendererV2::startRender(QgsRenderContext& context, const QgsFieldMap& fields)
-{
- mSymbol->startRender(context);
-}
-
-void QgsSingleSymbolRendererV2::stopRender(QgsRenderContext& context)
-{
- mSymbol->stopRender(context);
-}
-
-QList<QString> QgsSingleSymbolRendererV2::usedAttributes()
-{
- return QList<QString>();
-}
-
-QgsSymbolV2* QgsSingleSymbolRendererV2::symbol() const
-{
- return mSymbol;
-}
-
-void QgsSingleSymbolRendererV2::setSymbol(QgsSymbolV2* s)
-{
- delete mSymbol;
- mSymbol = s;
-}
-
-QString QgsSingleSymbolRendererV2::dump()
-{
- return QString("SINGLE: %1").arg(mSymbol->dump());
-}
-
-QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone()
-{
- QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
- r->setUsingSymbolLevels( usingSymbolLevels() );
- return r;
-}
-
-QgsSymbolV2List QgsSingleSymbolRendererV2::symbols()
-{
- QgsSymbolV2List lst;
- lst.append(mSymbol);
- return lst;
-}
-
-QgsFeatureRendererV2* QgsSingleSymbolRendererV2::create(QDomElement& element)
-{
- QDomElement symbolsElem = element.firstChildElement("symbols");
- if (symbolsElem.isNull())
- return NULL;
-
- QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
-
- if (!symbolMap.contains("0"))
- return NULL;
-
- QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( symbolMap.take("0") );
-
- // delete symbols if there are any more
- QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
-
- // TODO: symbol levels
- return r;
-}
-
-QDomElement QgsSingleSymbolRendererV2::save(QDomDocument& doc)
-{
- QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
- rendererElem.setAttribute("type", "singleSymbol");
-
- QgsSymbolV2Map symbols;
- symbols["0"] = mSymbol;
- QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
- rendererElem.appendChild(symbolsElem);
-
- return rendererElem;
-}
-
-///////////////////
-
-QgsRendererCategoryV2::QgsRendererCategoryV2(QVariant value, QgsSymbolV2* symbol, QString label)
- : mValue(value), mSymbol(symbol), mLabel(label)
-{
-}
-
-QgsRendererCategoryV2::QgsRendererCategoryV2(const QgsRendererCategoryV2& cat)
- : mValue(cat.mValue), mLabel(cat.mLabel)
-{
- mSymbol = cat.mSymbol->clone();
-}
-
-
-QgsRendererCategoryV2::~QgsRendererCategoryV2()
-{
- delete mSymbol;
-}
-
-QVariant QgsRendererCategoryV2::value() const
-{
- return mValue;
-}
-
-QgsSymbolV2* QgsRendererCategoryV2::symbol() const
-{
- return mSymbol;
-}
-
-QString QgsRendererCategoryV2::label() const
-{
- return mLabel;
-}
-
-void QgsRendererCategoryV2::setSymbol(QgsSymbolV2* s)
-{
- if (mSymbol == s)
- return;
- delete mSymbol;
- mSymbol = s;
-}
-
-void QgsRendererCategoryV2::setLabel(QString label)
-{
- mLabel = label;
-}
-
-QString QgsRendererCategoryV2::dump()
-{
- return QString("%1::%2::%3\n").arg(mValue.toString()).arg(mLabel).arg(mSymbol->dump());
-}
-
-///////////////////
-
-QgsCategorizedSymbolRendererV2::QgsCategorizedSymbolRendererV2(QString attrName, QgsCategoryList categories)
- : QgsFeatureRendererV2(RendererCategorizedSymbol), mAttrName(attrName), mCategories(categories)
-{
- for (int i = 0; i < mCategories.count(); ++i)
- {
- QgsRendererCategoryV2& cat = mCategories[i];
- if (cat.symbol() == NULL)
- {
- QgsDebugMsg("invalid symbol in a category! ignoring...");
- mCategories.removeAt(i--);
- }
- //mCategories.insert(cat.value().toString(), cat);
- }
-}
-
-QgsCategorizedSymbolRendererV2::~QgsCategorizedSymbolRendererV2()
-{
- mCategories.clear(); // this should also call destructors of symbols
-}
-
-void QgsCategorizedSymbolRendererV2::rebuildHash()
-{
- mSymbolHash.clear();
-
- for (int i = 0; i < mCategories.count(); ++i)
- {
- QgsRendererCategoryV2& cat = mCategories[i];
- mSymbolHash.insert(cat.value().toString(), cat.symbol());
- }
-}
-
-QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue(QVariant value)
-{
- // TODO: special case for int, double
-
- QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find(value.toString());
- if (it == mSymbolHash.end())
- {
- if (mSymbolHash.count() == 0)
- QgsDebugMsg("there are no hashed symbols!!!");
- else
- QgsDebugMsg("attribute value not found: " + value.toString());
- return NULL;
- }
- else
- return *it;
-}
-
-QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature(QgsFeature& feature)
-{
- const QgsAttributeMap& attrMap = feature.attributeMap();
- QgsAttributeMap::const_iterator ita = attrMap.find(mAttrNum);
- if (ita == attrMap.end())
- {
- QgsDebugMsg("attribute '"+mAttrName+"' (index "+QString::number(mAttrNum)+") required by renderer not found");
- return NULL;
- }
-
- // find the right category
- return symbolForValue(*ita);
-}
-
-int QgsCategorizedSymbolRendererV2::categoryIndexForValue(QVariant val)
-{
- for (int i = 0; i < mCategories.count(); i++)
- {
- if (mCategories[i].value() == val)
- return i;
- }
- return -1;
-}
-
-bool QgsCategorizedSymbolRendererV2::updateCategorySymbol(int catIndex, QgsSymbolV2* symbol)
-{
- if (catIndex < 0 || catIndex >= mCategories.size())
- return false;
- mCategories[catIndex].setSymbol(symbol);
- return true;
-}
-
-bool QgsCategorizedSymbolRendererV2::updateCategoryLabel(int catIndex, QString label)
-{
- if (catIndex < 0 || catIndex >= mCategories.size())
- return false;
- mCategories[catIndex].setLabel(label);
- return true;
-}
-
-bool QgsCategorizedSymbolRendererV2::deleteCategory(int catIndex)
-{
- if (catIndex < 0 || catIndex >= mCategories.size())
- return false;
-
- mCategories.removeAt(catIndex);
- return true;
-}
-
-void QgsCategorizedSymbolRendererV2::deleteAllCategories()
-{
- mCategories.clear();
-}
-
-void QgsCategorizedSymbolRendererV2::startRender(QgsRenderContext& context, const QgsFieldMap& fields)
-{
- // make sure that the hash table is up to date
- rebuildHash();
-
- // find out classification attribute index from name
- mAttrNum = fieldNameIndex(fields, mAttrName);
-
- QgsCategoryList::iterator it = mCategories.begin();
- for ( ; it != mCategories.end(); ++it)
- it->symbol()->startRender(context);
-}
-
-void QgsCategorizedSymbolRendererV2::stopRender(QgsRenderContext& context)
-{
- QgsCategoryList::iterator it = mCategories.begin();
- for ( ; it != mCategories.end(); ++it)
- it->symbol()->stopRender(context);
-}
-
-QList<QString> QgsCategorizedSymbolRendererV2::usedAttributes()
-{
- QList<QString> lst;
- lst.append(mAttrName);
- return lst;
-}
-
-QString QgsCategorizedSymbolRendererV2::dump()
-{
- QString s = QString("CATEGORIZED: idx %1\n").arg(mAttrName);
- for (int i=0; i<mCategories.count();i++)
- s += mCategories[i].dump();
- return s;
-}
-
-QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
-{
- QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( mAttrName, mCategories );
- r->setUsingSymbolLevels( usingSymbolLevels() );
- return r;
-}
-
-QgsSymbolV2List QgsCategorizedSymbolRendererV2::symbols()
-{
- QgsSymbolV2List lst;
- for (int i = 0; i < mCategories.count(); i++)
- lst.append(mCategories[i].symbol());
- return lst;
-}
-
-QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create(QDomElement& element)
-{
- QDomElement symbolsElem = element.firstChildElement("symbols");
- if (symbolsElem.isNull())
- return NULL;
-
- QDomElement catsElem = element.firstChildElement("categories");
- if (catsElem.isNull())
- return NULL;
-
- QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
- QgsCategoryList cats;
-
- QDomElement catElem = catsElem.firstChildElement();
- while (!catElem.isNull())
- {
- if (catElem.tagName() == "category")
- {
- QVariant value = QVariant(catElem.attribute("value"));
- QString symbolName = catElem.attribute("symbol");
- QString label = catElem.attribute("label");
- if (symbolMap.contains(symbolName))
- {
- QgsSymbolV2* symbol = symbolMap.take(symbolName);
- cats.append( QgsRendererCategoryV2(value, symbol, label) );
- }
- }
- catElem = catElem.nextSiblingElement();
- }
-
- QString attrName = element.attribute("attr");
-
- QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2(attrName, cats);
-
- // delete symbols if there are any more
- QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
-
- // TODO: symbol levels
- return r;
-}
-
-QDomElement QgsCategorizedSymbolRendererV2::save(QDomDocument& doc)
-{
- QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
- rendererElem.setAttribute("type", "categorizedSymbol");
- rendererElem.setAttribute("attr", mAttrName);
-
- // categories
- int i = 0;
- QgsSymbolV2Map symbols;
- QDomElement catsElem = doc.createElement("categories");
- QgsCategoryList::const_iterator it = mCategories.constBegin();
- for ( ; it != mCategories.end(); it++)
- {
- const QgsRendererCategoryV2& cat = *it;
- QString symbolName = QString::number(i);
- symbols.insert(symbolName, cat.symbol());
-
- QDomElement catElem = doc.createElement("category");
- catElem.setAttribute("value", cat.value().toString());
- catElem.setAttribute("symbol", symbolName);
- catElem.setAttribute("label", cat.label());
- catsElem.appendChild(catElem);
- i++;
- }
-
- rendererElem.appendChild(catsElem);
-
- // save symbols
- QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
- rendererElem.appendChild(symbolsElem);
-
- return rendererElem;
-}
-
-/////////////////////////
-// graduated
-
-
-QgsRendererRangeV2::QgsRendererRangeV2(double lowerValue, double upperValue, QgsSymbolV2* symbol, QString label)
- : mLowerValue(lowerValue), mUpperValue(upperValue), mSymbol(symbol), mLabel(label)
-{
-}
-
-QgsRendererRangeV2::QgsRendererRangeV2(const QgsRendererRangeV2& range)
- : mLowerValue(range.mLowerValue), mUpperValue(range.mUpperValue), mLabel(range.mLabel)
-{
- mSymbol = range.mSymbol->clone();
-}
-
-QgsRendererRangeV2::~QgsRendererRangeV2()
-{
- delete mSymbol;
-}
-
-double QgsRendererRangeV2::lowerValue() const
-{
- return mLowerValue;
-}
-
-double QgsRendererRangeV2::upperValue() const
-{
- return mUpperValue;
-}
-
-QgsSymbolV2* QgsRendererRangeV2::symbol() const
-{
- return mSymbol;
-}
-
-QString QgsRendererRangeV2::label() const
-{
- return mLabel;
-}
-
-void QgsRendererRangeV2::setSymbol(QgsSymbolV2* s)
-{
- if (mSymbol == s)
- return;
- delete mSymbol;
- mSymbol = s;
-}
-
-void QgsRendererRangeV2::setLabel(QString label)
-{
- mLabel = label;
-}
-
-QString QgsRendererRangeV2::dump()
-{
- return QString("%1 - %2::%3::%4\n").arg(mLowerValue).arg(mUpperValue).arg(mLabel).arg(mSymbol->dump());
-}
-
-///////////
-
-
-QgsGraduatedSymbolRendererV2::QgsGraduatedSymbolRendererV2(QString attrName, QgsRangeList ranges)
- : QgsFeatureRendererV2(RendererGraduatedSymbol), mAttrName(attrName), mRanges(ranges), mMode(Custom)
-{
- // TODO: check ranges for sanity (NULL symbols, invalid ranges)
-}
-
-QgsGraduatedSymbolRendererV2::~QgsGraduatedSymbolRendererV2()
-{
- mRanges.clear(); // should delete all the symbols
-}
-
-QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForValue(double value)
-{
- for (QgsRangeList::iterator it = mRanges.begin(); it != mRanges.end(); ++it)
- {
- if (it->lowerValue() <= value && it->upperValue() >= value)
- return it->symbol();
- }
- // the value is out of the range: return NULL instead of symbol
- return NULL;
-}
-
-QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature(QgsFeature& feature)
-{
- const QgsAttributeMap& attrMap = feature.attributeMap();
- QgsAttributeMap::const_iterator ita = attrMap.find(mAttrNum);
- if (ita == attrMap.end())
- {
- QgsDebugMsg("attribute required by renderer not found: "+mAttrName+"(index "+QString::number(mAttrNum)+")");
- return NULL;
- }
-
- // find the right category
- return symbolForValue(ita->toDouble());
-
-}
-
-void QgsGraduatedSymbolRendererV2::startRender(QgsRenderContext& context, const QgsFieldMap& fields)
-{
- // find out classification attribute index from name
- mAttrNum = fieldNameIndex(fields, mAttrName);
-
- QgsRangeList::iterator it = mRanges.begin();
- for ( ; it != mRanges.end(); ++it)
- it->symbol()->startRender(context);
-}
-
-void QgsGraduatedSymbolRendererV2::stopRender(QgsRenderContext& context)
-{
- QgsRangeList::iterator it = mRanges.begin();
- for ( ; it != mRanges.end(); ++it)
- it->symbol()->startRender(context);
-}
-
-QList<QString> QgsGraduatedSymbolRendererV2::usedAttributes()
-{
- QList<QString> lst;
- lst.append( mAttrName );
- return lst;
-}
-
-bool QgsGraduatedSymbolRendererV2::updateRangeSymbol(int rangeIndex, QgsSymbolV2* symbol)
-{
- if (rangeIndex < 0 || rangeIndex >= mRanges.size())
- return false;
- mRanges[rangeIndex].setSymbol(symbol);
- return true;
-}
-
-bool QgsGraduatedSymbolRendererV2::updateRangeLabel(int rangeIndex, QString label)
-{
- if (rangeIndex < 0 || rangeIndex >= mRanges.size())
- return false;
- mRanges[rangeIndex].setLabel(label);
- return true;
-}
-
-QString QgsGraduatedSymbolRendererV2::dump()
-{
- QString s = QString("GRADUATED: attr %1\n").arg(mAttrName);
- for (int i=0; i<mRanges.count();i++)
- s += mRanges[i].dump();
- return s;
-}
-
-QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone()
-{
- QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( mAttrName, mRanges );
- r->setUsingSymbolLevels( usingSymbolLevels() );
- return r;
-}
-
-QgsSymbolV2List QgsGraduatedSymbolRendererV2::symbols()
-{
- QgsSymbolV2List lst;
- for (int i = 0; i < mRanges.count(); i++)
- lst.append(mRanges[i].symbol());
- return lst;
-}
-
-static QList<double> _calcEqualIntervalBreaks(double minimum, double maximum, int classes)
-{
- double step = (maximum - minimum) / classes;
-
- QList<double> breaks;
- double value = minimum;
- for (int i = 0; i < classes; i++)
- {
- value += step;
- breaks.append( value );
- }
- return breaks;
-}
-
-static QList<double> _calcQuantileBreaks(QList<double> values, int classes)
-{
- // sort the values first
- qSort(values);
-
- QList<double> breaks;
-
- // q-th quantile of a data set:
- // value where q fraction of data is below and (1-q) fraction is above this value
- // Xq = (1 - r) * X_NI1 + r * X_NI2
- // NI1 = (int) (q * (n+1))
- // NI2 = NI1 + 1
- // r = q * (n+1) - (int) (q * (n+1))
- // (indices of X: 1...n)
-
- int n = values.count();
- double q,a,aa,r,Xq;
- for (int i = 0; i < (classes-1); i++)
- {
- q = (i+1) / (double) classes;
- a = q * n;
- aa = (int) (q * n);
-
- r = a - aa;
- Xq = (1-r)* values[aa] + r * values[aa+1];
-
- breaks.append( Xq );
- }
-
- breaks.append( values[ n-1 ] );
-
- return breaks;
-}
-
-#include "qgsvectordataprovider.h"
-#include "qgsvectorcolorrampv2.h"
-
-QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
- QgsVectorLayer* vlayer,
- QString attrName,
- int classes,
- Mode mode,
- QgsSymbolV2* symbol,
- QgsVectorColorRampV2* ramp)
-{
- QgsVectorDataProvider* provider = vlayer->dataProvider();
-
- int attrNum = fieldNameIndex(vlayer->pendingFields(), attrName);
-
- double minimum = provider->minimumValue( attrNum ).toDouble();
- double maximum = provider->maximumValue( attrNum ).toDouble();
- QgsDebugMsg(QString("min %1 // max %2").arg(minimum).arg(maximum));
-
- QList<double> breaks;
- if (mode == EqualInterval)
- {
- breaks = _calcEqualIntervalBreaks(minimum, maximum, classes);
- }
- else if (mode == Quantile)
- {
- // get values from layer
- QList<double> values;
- QgsFeature f;
- QgsAttributeList lst;
- lst.append(attrNum);
- provider->select(lst, QgsRectangle(), false);
- while (provider->nextFeature(f))
- values.append(f.attributeMap()[attrNum].toDouble());
- // calculate the breaks
- breaks = _calcQuantileBreaks(values, classes);
- }
- 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;
- label = QString::number(lower,'f',4) + " - " + QString::number(upper,'f',4);
-
- QgsSymbolV2* newSymbol = symbol->clone();
- newSymbol->setColor( ramp->color( (double) i / (classes-1) ) ); // color from (0 / cl-1) to (cl-1 / cl-1)
-
- ranges.append( QgsRendererRangeV2(lower, upper, newSymbol, label) );
- }
-
- return new QgsGraduatedSymbolRendererV2( attrName, ranges );
-}
-
-
-
-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);
-
- // TODO: symbol levels
- return r;
-}
-
-QDomElement QgsGraduatedSymbolRendererV2::save(QDomDocument& doc)
-{
- QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
- rendererElem.setAttribute("type", "graduatedSymbol");
- rendererElem.setAttribute("attr", mAttrName);
-
- // ranges
- int i = 0;
- QgsSymbolV2Map symbols;
- QDomElement rangesElem = doc.createElement("ranges");
- QgsRangeList::const_iterator it = mRanges.constBegin();
- for ( ; it != mRanges.end(); it++)
- {
- const QgsRendererRangeV2& range = *it;
- QString symbolName = QString::number(i);
- symbols.insert(symbolName, range.symbol());
-
- QDomElement rangeElem = doc.createElement("range");
- rangeElem.setAttribute("lower", range.lowerValue());
- rangeElem.setAttribute("upper", range.upperValue());
- rangeElem.setAttribute("symbol", symbolName);
- rangeElem.setAttribute("label", range.label());
- rangesElem.appendChild(rangeElem);
- i++;
- }
-
- rendererElem.appendChild(rangesElem);
-
- // save symbols
- QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
- rendererElem.appendChild(symbolsElem);
-
- return rendererElem;
-}
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h 2009-11-03 16:18:14 UTC (rev 11908)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h 2009-11-03 17:32:36 UTC (rev 11909)
@@ -6,7 +6,6 @@
#include "qgsfield.h" // for QgsFieldMap
#include <QList>
-#include <QHash>
#include <QString>
#include <QVariant>
@@ -108,226 +107,5 @@
bool mUsingSymbolLevels;
};
-class QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
-{
-public:
-
- QgsSingleSymbolRendererV2(QgsSymbolV2* symbol);
-
- virtual ~QgsSingleSymbolRendererV2();
-
- virtual QgsSymbolV2* symbolForFeature(QgsFeature& feature);
-
- virtual void startRender(QgsRenderContext& context, const QgsFieldMap& fields);
-
- virtual void stopRender(QgsRenderContext& context);
-
- virtual QList<QString> usedAttributes();
-
- QgsSymbolV2* symbol() const;
- void setSymbol(QgsSymbolV2* s);
- virtual QString dump();
-
- virtual QgsFeatureRendererV2* clone();
-
- virtual QgsSymbolV2List symbols();
-
- //! create renderer from XML element
- static QgsFeatureRendererV2* create(QDomElement& element);
-
- //! store renderer info to XML element
- virtual QDomElement save(QDomDocument& doc);
-
-protected:
- QgsSymbolV2* mSymbol;
-};
-
-
-class QgsRendererCategoryV2
-{
-public:
-
- //! takes ownership of symbol
- QgsRendererCategoryV2(QVariant value, QgsSymbolV2* symbol, QString label);
-
- //! copy constructor
- QgsRendererCategoryV2(const QgsRendererCategoryV2& cat);
-
- ~QgsRendererCategoryV2();
-
- QVariant value() const;
- QgsSymbolV2* symbol() const;
- QString label() const;
-
- void setSymbol(QgsSymbolV2* s);
- void setLabel(QString label);
-
- // debugging
- QString dump();
-
-protected:
- QVariant mValue;
- QgsSymbolV2* mSymbol;
- QString mLabel;
-};
-
-typedef QList<QgsRendererCategoryV2> QgsCategoryList;
-
-class QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
-{
-public:
-
- QgsCategorizedSymbolRendererV2(QString attrName = QString(), QgsCategoryList categories = QgsCategoryList());
-
- virtual ~QgsCategorizedSymbolRendererV2();
-
- virtual QgsSymbolV2* symbolForFeature(QgsFeature& feature);
-
- virtual void startRender(QgsRenderContext& context, const QgsFieldMap& fields);
-
- virtual void stopRender(QgsRenderContext& context);
-
- virtual QList<QString> usedAttributes();
-
- virtual QString dump();
-
- virtual QgsFeatureRendererV2* clone();
-
- virtual QgsSymbolV2List symbols();
-
- const QgsCategoryList& categories() { return mCategories; }
-
- //! return index of category with specified value (-1 if not found)
- int categoryIndexForValue(QVariant val);
-
- bool updateCategorySymbol(int catIndex, QgsSymbolV2* symbol);
- bool updateCategoryLabel(int catIndex, QString label);
-
- bool deleteCategory(int catIndex);
- void deleteAllCategories();
-
- QString classAttribute() const { return mAttrName; }
- void setClassAttribute(QString attr) { mAttrName = attr; }
-
- //! create renderer from XML element
- static QgsFeatureRendererV2* create(QDomElement& element);
-
- //! store renderer info to XML element
- virtual QDomElement save(QDomDocument& doc);
-
-protected:
- QgsCategoryList mCategories;
- QString mAttrName;
-
- //! attribute index (derived from attribute name in startRender)
- int mAttrNum;
-
- //! hashtable for faster access to symbols
- QHash<QString, QgsSymbolV2*> mSymbolHash;
-
- void rebuildHash();
-
- QgsSymbolV2* symbolForValue(QVariant value);
-};
-
-
-//////////////////
-
-class QgsRendererRangeV2
-{
-public:
- QgsRendererRangeV2(double lowerValue, double upperValue, QgsSymbolV2* symbol, QString label);
- QgsRendererRangeV2(const QgsRendererRangeV2& range);
-
- ~QgsRendererRangeV2();
-
- double lowerValue() const;
- double upperValue() const;
-
- QgsSymbolV2* symbol() const;
- QString label() const;
-
- void setSymbol(QgsSymbolV2* s);
- void setLabel(QString label);
-
- // debugging
- QString dump();
-
-protected:
- double mLowerValue, mUpperValue;
- QgsSymbolV2* mSymbol;
- QString mLabel;
-};
-
-typedef QList<QgsRendererRangeV2> QgsRangeList;
-
-class QgsVectorLayer;
-class QgsVectorColorRampV2;
-
-class QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
-{
-public:
- QgsGraduatedSymbolRendererV2(QString attrName = QString(), QgsRangeList ranges = QgsRangeList());
-
- virtual ~QgsGraduatedSymbolRendererV2();
-
- virtual QgsSymbolV2* symbolForFeature(QgsFeature& feature);
-
- virtual void startRender(QgsRenderContext& context, const QgsFieldMap& fields);
-
- virtual void stopRender(QgsRenderContext& context);
-
- virtual QList<QString> usedAttributes();
-
- virtual QString dump();
-
- virtual QgsFeatureRendererV2* clone();
-
- virtual QgsSymbolV2List symbols();
-
- QString classAttribute() const { return mAttrName; }
- void setClassAttribute(QString attr) { mAttrName = attr; }
-
- const QgsRangeList& ranges() { return mRanges; }
-
- bool updateRangeSymbol(int rangeIndex, QgsSymbolV2* symbol);
- bool updateRangeLabel(int rangeIndex, QString label);
-
- enum Mode
- {
- EqualInterval,
- Quantile,
- Custom
- };
-
- Mode mode() const { return mMode; }
- void setMode(Mode mode) { mMode = mode; }
-
- static QgsGraduatedSymbolRendererV2* createRenderer(
- QgsVectorLayer* vlayer,
- QString attrName,
- int classes,
- Mode mode,
- QgsSymbolV2* symbol,
- QgsVectorColorRampV2* ramp);
-
- //! create renderer from XML element
- static QgsFeatureRendererV2* create(QDomElement& element);
-
- //! store renderer info to XML element
- virtual QDomElement save(QDomDocument& doc);
-
-protected:
- QgsRangeList mRanges;
- QString mAttrName;
- Mode mMode;
-
- //! attribute index (derived from attribute name in startRender)
- int mAttrNum;
-
- QgsSymbolV2* symbolForValue(double value);
-};
-
-
#endif
Added: branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp (rev 0)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp 2009-11-03 17:32:36 UTC (rev 11909)
@@ -0,0 +1,102 @@
+
+#include "qgssinglesymbolrendererv2.h"
+
+#include "qgssymbolv2.h"
+#include "qgssymbollayerv2utils.h"
+
+#include <QDomDocument>
+#include <QDomElement>
+
+QgsSingleSymbolRendererV2::QgsSingleSymbolRendererV2(QgsSymbolV2* symbol)
+ : QgsFeatureRendererV2(RendererSingleSymbol)
+{
+ mSymbol = symbol;
+}
+
+QgsSingleSymbolRendererV2::~QgsSingleSymbolRendererV2()
+{
+ delete mSymbol;
+}
+
+QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature(QgsFeature& feature)
+{
+ return mSymbol;
+}
+
+void QgsSingleSymbolRendererV2::startRender(QgsRenderContext& context, const QgsFieldMap& fields)
+{
+ mSymbol->startRender(context);
+}
+
+void QgsSingleSymbolRendererV2::stopRender(QgsRenderContext& context)
+{
+ mSymbol->stopRender(context);
+}
+
+QList<QString> QgsSingleSymbolRendererV2::usedAttributes()
+{
+ return QList<QString>();
+}
+
+QgsSymbolV2* QgsSingleSymbolRendererV2::symbol() const
+{
+ return mSymbol;
+}
+
+void QgsSingleSymbolRendererV2::setSymbol(QgsSymbolV2* s)
+{
+ delete mSymbol;
+ mSymbol = s;
+}
+
+QString QgsSingleSymbolRendererV2::dump()
+{
+ return QString("SINGLE: %1").arg(mSymbol->dump());
+}
+
+QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone()
+{
+ QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
+ r->setUsingSymbolLevels( usingSymbolLevels() );
+ return r;
+}
+
+QgsSymbolV2List QgsSingleSymbolRendererV2::symbols()
+{
+ QgsSymbolV2List lst;
+ lst.append(mSymbol);
+ return lst;
+}
+
+QgsFeatureRendererV2* QgsSingleSymbolRendererV2::create(QDomElement& element)
+{
+ QDomElement symbolsElem = element.firstChildElement("symbols");
+ if (symbolsElem.isNull())
+ return NULL;
+
+ QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
+
+ if (!symbolMap.contains("0"))
+ return NULL;
+
+ QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( symbolMap.take("0") );
+
+ // delete symbols if there are any more
+ QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
+
+ // TODO: symbol levels
+ return r;
+}
+
+QDomElement QgsSingleSymbolRendererV2::save(QDomDocument& doc)
+{
+ QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
+ rendererElem.setAttribute("type", "singleSymbol");
+
+ QgsSymbolV2Map symbols;
+ symbols["0"] = mSymbol;
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
+ rendererElem.appendChild(symbolsElem);
+
+ return rendererElem;
+}
Added: branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.h (rev 0)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgssinglesymbolrendererv2.h 2009-11-03 17:32:36 UTC (rev 11909)
@@ -0,0 +1,42 @@
+#ifndef QGSSINGLESYMBOLRENDERERV2_H
+#define QGSSINGLESYMBOLRENDERERV2_H
+
+#include "qgsrendererv2.h"
+
+class QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
+{
+public:
+
+ QgsSingleSymbolRendererV2(QgsSymbolV2* symbol);
+
+ virtual ~QgsSingleSymbolRendererV2();
+
+ virtual QgsSymbolV2* symbolForFeature(QgsFeature& feature);
+
+ virtual void startRender(QgsRenderContext& context, const QgsFieldMap& fields);
+
+ virtual void stopRender(QgsRenderContext& context);
+
+ virtual QList<QString> usedAttributes();
+
+ QgsSymbolV2* symbol() const;
+ void setSymbol(QgsSymbolV2* s);
+
+ virtual QString dump();
+
+ virtual QgsFeatureRendererV2* clone();
+
+ virtual QgsSymbolV2List symbols();
+
+ //! create renderer from XML element
+ static QgsFeatureRendererV2* create(QDomElement& element);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
+
+protected:
+ QgsSymbolV2* mSymbol;
+};
+
+
+#endif // QGSSINGLESYMBOLRENDERERV2_H
Modified: branches/symbology-ng-branch/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp
===================================================================
--- branches/symbology-ng-branch/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp 2009-11-03 16:18:14 UTC (rev 11908)
+++ branches/symbology-ng-branch/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp 2009-11-03 17:32:36 UTC (rev 11909)
@@ -7,6 +7,11 @@
#include "qgsvectorcolorrampv2.h"
#include "qgsstylev2.h"
+#include "qgssinglesymbolrendererv2.h"
+#include "qgscategorizedsymbolrendererv2.h"
+#include "qgsgraduatedsymbolrendererv2.h"
+
+
#include "qgssymbolv2selectordialog.h"
#include "qgssymbollevelsv2dialog.h"
More information about the QGIS-commit
mailing list