Skip to content
Permalink
Browse files
Fix for ticket #1200 - remember state of mode in graduated symbold di…
…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@9479 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed Oct 16, 2008
1 parent b6ec053 commit 382d52b4cb9ae6cf70ad394ff7f76e201d6fe306
@@ -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/;
};
@@ -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();
@@ -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
@@ -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 );
}

}
@@ -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();
@@ -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();
@@ -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();
@@ -52,6 +53,7 @@ QgsGraduatedSymbolRenderer& QgsGraduatedSymbolRenderer::operator=( const QgsGrad
{
if ( this != &other )
{
mMode = other.mMode;
mGeometryType = other.mGeometryType;
mClassificationField = other.mClassificationField;
removeSymbols();
@@ -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;
@@ -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();

@@ -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 )
{
@@ -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();
@@ -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 )

0 comments on commit 382d52b

Please sign in to comment.