Skip to content

Commit

Permalink
Fix for ticket #1200 - remember state of mode in graduated symbold di…
Browse files Browse the repository at this point in the history
…alog. Also fixes symbol preview update issues. Note there still seems to be a general bug in quantile computation which is not addressed yet.

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@9479 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed Oct 16, 2008
1 parent 874a7c2 commit 24452c8
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 8 deletions.
39 changes: 38 additions & 1 deletion python/core/qgsgraduatedsymbolrenderer.sip
Expand Up @@ -6,42 +6,79 @@ class QgsGraduatedSymbolRenderer : QgsRenderer
%End

public:

enum Mode
{
EqualInterval,
Quantile,
Empty
};

QgsGraduatedSymbolRenderer(QGis::GeometryType type);

QgsGraduatedSymbolRenderer(const QgsGraduatedSymbolRenderer& other);

virtual ~QgsGraduatedSymbolRenderer();

/** Get the mode - which is only really used to be able to reinstate
* the graduated dialog properties properly, so we
* dont do anything else besides accessors and mutators in
* this class.
*/
const Mode mode() const;

/** Set the mode - which is only really used to be able to reinstate
* the graduated dialog properties properly, so we
* dont do anything else besides accessors and mutators in
* this class.
*/
void setMode( Mode theMode );

/**Adds a new item
\param sy a pointer to the QgsSymbol to be inserted. It has to be created using the new operator and is automatically destroyed when 'removeItems' is called or when this object is destroyed*/
void addSymbol(QgsSymbol* sy /Transfer/);

/**Returns the number of the classification field*/
int classificationField() const;

/**Removes all symbols*/
void removeSymbols();

/** Determines if a feature will be rendered or not
@param f a pointer to the feature to determine if rendering will happen*/
@param f a pointer to the feature to determine if rendering will happen*/
bool willRenderFeature(QgsFeature *f);

/**Renders an OGRFeature
\param p a painter (usually the one from the current map canvas)
\param f a pointer to a feature to render
\param t the transform object containing the information how to transform the map coordinates to screen coordinates*/
void renderFeature(QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0);

/**Sets the number of the classicifation field
\param field the number of the field to classify*/
void setClassificationField(int field);

/**Reads the renderer configuration from an XML file
@param rnode the Dom node to read
@param vl the vector layer which will be associated with the renderer*/
virtual int readXML(const QDomNode& rnode, QgsVectorLayer& vl);

/**Writes the contents of the renderer to a configuration file
@ return true in case of success*/
virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, QgsVectorLayer& vl ) const;

/** Returns true*/
bool needsAttributes() const;

/**Returns a list with the index to the classification field*/
QList<int> classificationAttributes() const;

/**Returns the renderers name*/
QString name() const;

/**Returns the symbols of the items*/
const QList<QgsSymbol*> symbols() const;

/**Returns a copy of the renderer (a deep copy on the heap)*/
QgsRenderer* clone() const /Factory/;
};
Expand Down
57 changes: 52 additions & 5 deletions src/app/qgsgraduatedsymboldialog.cpp
Expand Up @@ -60,13 +60,38 @@ QgsGraduatedSymbolDialog::QgsGraduatedSymbolDialog( QgsVectorLayer * layer ): QD
return;
}

//restore the correct settings
const QgsGraduatedSymbolRenderer* renderer = dynamic_cast < const QgsGraduatedSymbolRenderer * >( layer->renderer() );

//
// Set up the mode combo
//
modeComboBox->addItem( tr( "Equal Interval" ) );
modeComboBox->addItem( tr( "Quantiles" ) );
modeComboBox->addItem( tr( "Empty" ) );

//restore the correct settings
const QgsGraduatedSymbolRenderer* renderer = dynamic_cast < const QgsGraduatedSymbolRenderer * >( layer->renderer() );
if ( renderer )
{
QString myMode = "";
if ( renderer->mode() == QgsGraduatedSymbolRenderer::Empty )
{
myMode = tr( "Empty" );
}
else if ( renderer->mode() == QgsGraduatedSymbolRenderer::Quantile )
{
myMode = tr( "Quantiles" );
}
else
{
myMode = tr( "Equal Interval" );
}
modeComboBox->setCurrentIndex( modeComboBox->findText( myMode ) );
}


//
// Set up the classfield combo
//
if ( renderer )
{
QList < QgsSymbol * >list = renderer->symbols();
Expand All @@ -81,7 +106,7 @@ QgsGraduatedSymbolDialog::QgsGraduatedSymbolDialog( QgsVectorLayer * layer ): QD
break;
}
}
classificationComboBox->setItemText( classificationComboBox->currentIndex(), classfield );
classificationComboBox->setCurrentIndex( classificationComboBox->findText( classfield ) );

numberofclassesspinbox->setValue( list.size() );
//fill the items of the renderer into mValues
Expand All @@ -98,7 +123,9 @@ QgsGraduatedSymbolDialog::QgsGraduatedSymbolDialog( QgsVectorLayer * layer ): QD
sym->setScaleClassificationField(( *it )->scaleClassificationField() );
sym->setRotationClassificationField(( *it )->rotationClassificationField() );
mEntries.insert( std::make_pair( classbreak, sym ) );
mClassListWidget->addItem( classbreak );
QListWidgetItem * mypItem = new QListWidgetItem( classbreak );
updateEntryIcon( sym , mypItem );
mClassListWidget->addItem( mypItem );
}

}
Expand Down Expand Up @@ -149,6 +176,25 @@ void QgsGraduatedSymbolDialog::apply()
}

QgsGraduatedSymbolRenderer* renderer = new QgsGraduatedSymbolRenderer( mVectorLayer->type() );

//
// First the mode
//
if ( modeComboBox->currentText() == tr( "Empty" ) )
{
renderer->setMode( QgsGraduatedSymbolRenderer::Empty );
}
else if ( modeComboBox->currentText() == tr( "Quantiles" ) )
{
renderer->setMode( QgsGraduatedSymbolRenderer::Quantile );
}
else //equal interval by default//equal interval by default
{
renderer->setMode( QgsGraduatedSymbolRenderer::EqualInterval );
}
//
// Now the class breaks
//
for ( int item = 0;item < mClassListWidget->count();++item )
{
QString classbreak = mClassListWidget->item( item )->text();
Expand Down Expand Up @@ -251,7 +297,8 @@ void QgsGraduatedSymbolDialog::adjustClassification()

if ( provider )
{
if ( modeComboBox->currentText() == tr( "Equal Interval" ) )
if ( modeComboBox->currentText() == tr( "Equal Interval" ) ||
modeComboBox->currentText() == tr( "Quantiles" ) )
{
minimum = provider->minimumValue( field ).toDouble();
maximum = provider->maximumValue( field ).toDouble();
Expand Down
67 changes: 66 additions & 1 deletion src/core/renderer/qgsgraduatedsymbolrenderer.cpp
Expand Up @@ -31,13 +31,14 @@
#include <QPainter>


QgsGraduatedSymbolRenderer::QgsGraduatedSymbolRenderer( QGis::GeometryType type )
QgsGraduatedSymbolRenderer::QgsGraduatedSymbolRenderer( QGis::GeometryType type, Mode mode )
{
mGeometryType = type;
}

QgsGraduatedSymbolRenderer::QgsGraduatedSymbolRenderer( const QgsGraduatedSymbolRenderer& other )
{
mMode = other.mMode;
mGeometryType = other.mGeometryType;
mClassificationField = other.mClassificationField;
const QList<QgsSymbol*> s = other.symbols();
Expand All @@ -52,6 +53,7 @@ QgsGraduatedSymbolRenderer& QgsGraduatedSymbolRenderer::operator=( const QgsGrad
{
if ( this != &other )
{
mMode = other.mMode;
mGeometryType = other.mGeometryType;
mClassificationField = other.mClassificationField;
removeSymbols();
Expand All @@ -71,6 +73,25 @@ QgsGraduatedSymbolRenderer::~QgsGraduatedSymbolRenderer()

}


const QgsGraduatedSymbolRenderer::Mode QgsGraduatedSymbolRenderer::mode() const
{
//mode is only really used to be able to reinstate
//the graduated dialog properties properly, so we
//dont do anything else besides accessors and mutators in
//this class
return mMode;
}

void QgsGraduatedSymbolRenderer::setMode( QgsGraduatedSymbolRenderer::Mode theMode )
{
//mode is only really used to be able to reinstate
//the graduated dialog properties properly, so we
//dont do anything else besides accessors and mutators in
//this class
mMode = theMode;
}

const QList<QgsSymbol*> QgsGraduatedSymbolRenderer::symbols() const
{
return mSymbols;
Expand Down Expand Up @@ -197,6 +218,8 @@ QgsSymbol *QgsGraduatedSymbolRenderer::symbolForFeature( const QgsFeature* f )
int QgsGraduatedSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
{
mGeometryType = vl.type();
QDomNode modeNode = rnode.namedItem( "mode" );
QString modeValue = modeNode.toElement().text();
QDomNode classnode = rnode.namedItem( "classificationfield" );
QString classificationField = classnode.toElement().text();

Expand All @@ -205,6 +228,19 @@ int QgsGraduatedSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer&
{
return 1;
}
if ( modeValue == "Empty" )
{
mMode = QgsGraduatedSymbolRenderer::Empty;
}
else if ( modeValue == "Quantile" )
{
mMode = QgsGraduatedSymbolRenderer::Quantile;
}
else //default
{
mMode = QgsGraduatedSymbolRenderer::EqualInterval;
}

int classificationId = theProvider->fieldNameIndex( classificationField );
if ( classificationId == -1 )
{
Expand Down Expand Up @@ -269,6 +305,35 @@ bool QgsGraduatedSymbolRenderer::writeXML( QDomNode & layer_node, QDomDocument &
bool returnval = true;
QDomElement graduatedsymbol = document.createElement( "graduatedsymbol" );
layer_node.appendChild( graduatedsymbol );

//
// Mode field first ...
//

QString modeValue="";
if ( mMode == QgsGraduatedSymbolRenderer::Empty )
{
modeValue == "Empty";
}
else if ( QgsGraduatedSymbolRenderer::Quantile )
{
modeValue = "Quantile";
}
else //default
{
modeValue = "Equal Interval";
}
QDomElement modeElement = document.createElement( "mode" );
QDomText modeText = document.createTextNode( modeValue );
modeElement.appendChild( modeText );
graduatedsymbol.appendChild( modeElement );



//
// classification field now ...
//

QDomElement classificationfield = document.createElement( "classificationfield" );

const QgsVectorDataProvider* theProvider = vl.dataProvider();
Expand Down
44 changes: 43 additions & 1 deletion src/core/renderer/qgsgraduatedsymbolrenderer.h
Expand Up @@ -27,57 +27,99 @@ class QgsVectorLayer;
class CORE_EXPORT QgsGraduatedSymbolRenderer: public QgsRenderer
{
public:
QgsGraduatedSymbolRenderer( QGis::GeometryType type );
enum Mode
{
EqualInterval,
Quantile,
Empty
};
QgsGraduatedSymbolRenderer( QGis::GeometryType type, Mode theMode = EqualInterval );
QgsGraduatedSymbolRenderer( const QgsGraduatedSymbolRenderer& other );
QgsGraduatedSymbolRenderer& operator=( const QgsGraduatedSymbolRenderer& other );
virtual ~QgsGraduatedSymbolRenderer();

/** Get the mode - which is only really used to be able to reinstate
* the graduated dialog properties properly, so we
* dont do anything else besides accessors and mutators in
* this class.
*/
const Mode mode() const;

/** Set the mode - which is only really used to be able to reinstate
* the graduated dialog properties properly, so we
* dont do anything else besides accessors and mutators in
* this class.
*/
void setMode( Mode theMode );

/**Adds a new item
\param sy a pointer to the QgsSymbol to be inserted. It has to be created using the new operator and is automatically destroyed when 'removeItems' is called or when this object is destroyed*/
void addSymbol( QgsSymbol* sy );

/**Returns the indes of the classification field*/
int classificationField() const;

/**Removes all symbols*/
void removeSymbols();

/** Determines if a feature will be rendered or not
@param f a pointer to the feature to determine if rendering will happen*/
virtual bool willRenderFeature( QgsFeature *f );

/**Renders an OGRFeature
\param p a painter (usually the one from the current map canvas)
\param f a pointer to a feature to render
\param t the transform object containing the information how to transform the map coordinates to screen coordinates*/
void renderFeature( QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0 );

/**Sets the classicifation field by index
\param field the number of the field to classify*/
void setClassificationField( int );

/**Reads the renderer configuration from an XML file
@param rnode the Dom node to read
@param vl the vector layer which will be associated with the renderer
@return 0 in case of success, 1 if vector layer has no renderer, 2 if classification field not found
*/
virtual int readXML( const QDomNode& rnode, QgsVectorLayer& vl );

/**Writes the contents of the renderer to a configuration file
@ return true in case of success*/
virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const;

/** Returns true*/
bool needsAttributes() const;

/**Returns a list of all needed attributes*/
QgsAttributeList classificationAttributes() const;

void updateSymbolAttributes();

/**Returns the renderers name*/
QString name() const;

/**Returns the symbols of the items*/
const QList<QgsSymbol*> symbols() const;

/**Returns a copy of the renderer (a deep copy on the heap)*/
QgsRenderer* clone() const;

protected:
/** The graduation mode */
Mode mMode;

/**Index of the classification field (it must be a numerical field)*/
int mClassificationField;

/**List holding the symbols for the individual classes*/
QList<QgsSymbol*> mSymbols;

QgsSymbol *symbolForFeature( const QgsFeature* f );

/**Cached copy of all underlying symbols required attribute fields*/
QgsAttributeList mSymbolAttributes;


};

inline void QgsGraduatedSymbolRenderer::addSymbol( QgsSymbol* sy )
Expand Down

0 comments on commit 24452c8

Please sign in to comment.