[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