Skip to content

Commit

Permalink
Bindings for QgsCategorizedSymbolRenderer::createCategories
Browse files Browse the repository at this point in the history
also contains some code modernization
  • Loading branch information
m-kuhn committed Dec 10, 2018
1 parent f353e4e commit 8b6eaea
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 40 deletions.
Expand Up @@ -279,6 +279,19 @@ Returns the count of symbols matched.
.. versionadded:: 3.4
%End


static QgsCategoryList createCategories( const QVariantList &values, const QgsSymbol *symbol, QgsVectorLayer *layer = 0, const QString &fieldName = QString() );
%Docstring
Create categories for a list of ``values``.
The returned symbols in the category list will be a modification of ``symbol``.

If ``layer`` and ``fieldName`` are specified it will try to find nicer values
to represent the description for the categories based on the respective field
configuration.

.. versionadded:: 3.6
%End

protected:


Expand Down
39 changes: 39 additions & 0 deletions src/core/symbology/qgscategorizedsymbolrenderer.cpp
Expand Up @@ -30,6 +30,8 @@
#include "qgslogger.h"
#include "qgsproperty.h"
#include "qgsstyle.h"
#include "qgsfieldformatter.h"
#include "qgsfieldformatterregistry.h"

#include <QDomDocument>
#include <QDomElement>
Expand Down Expand Up @@ -1032,3 +1034,40 @@ int QgsCategorizedSymbolRenderer::matchToSymbols( QgsStyle *style, const QgsSymb

return matched;
}

QgsCategoryList QgsCategorizedSymbolRenderer::createCategories( const QList<QVariant> &values, const QgsSymbol *symbol, QgsVectorLayer *layer, const QString &attributeName )
{
QgsCategoryList cats;
QVariantList vals = values;
// sort the categories first
QgsSymbolLayerUtils::sortVariantList( vals, Qt::AscendingOrder );

if ( layer && !attributeName.isNull() )
{
const QgsFields fields = layer->fields();
for ( const QVariant &value : vals )
{
QgsSymbol *newSymbol = symbol->clone();
if ( !value.isNull() )
{
int fieldIdx = fields.lookupField( attributeName );
QString categoryName = value.toString();
if ( fieldIdx != -1 )
{
const QgsField field = fields.at( fieldIdx );
const QgsEditorWidgetSetup setup = field.editorWidgetSetup();
const QgsFieldFormatter *formatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
categoryName = formatter->representValue( layer, fieldIdx, setup.config(), QVariant(), value );
}
cats.append( QgsRendererCategory( value, newSymbol, categoryName, true ) );
}
}
}

// add null (default) value
QgsSymbol *newSymbol = symbol->clone();
cats.append( QgsRendererCategory( QVariant(), newSymbol, QString(), true ) );

return cats;
}

13 changes: 13 additions & 0 deletions src/core/symbology/qgscategorizedsymbolrenderer.h
Expand Up @@ -247,6 +247,19 @@ class CORE_EXPORT QgsCategorizedSymbolRenderer : public QgsFeatureRenderer
int matchToSymbols( QgsStyle *style, QgsSymbol::SymbolType type,
QVariantList &unmatchedCategories SIP_OUT, QStringList &unmatchedSymbols SIP_OUT, bool caseSensitive = true, bool useTolerantMatch = false );


/**
* Create categories for a list of \a values.
* The returned symbols in the category list will be a modification of \a symbol.
*
* If \a layer and \a fieldName are specified it will try to find nicer values
* to represent the description for the categories based on the respective field
* configuration.
*
* \since QGIS 3.6
*/
static QgsCategoryList createCategories( const QVariantList &values, const QgsSymbol *symbol, QgsVectorLayer *layer = nullptr, const QString &fieldName = QString() );

protected:
QString mAttrName;
QgsCategoryList mCategories;
Expand Down
47 changes: 7 additions & 40 deletions src/gui/symbology/qgscategorizedsymbolrendererwidget.cpp
Expand Up @@ -638,44 +638,12 @@ void QgsCategorizedSymbolRendererWidget::changeCategorySymbol()
}
}

static void _createCategories( QgsCategoryList &cats, QList<QVariant> &values, QgsSymbol *symbol, QgsVectorLayer *layer, const QString &attrName )
{
// sort the categories first
QgsSymbolLayerUtils::sortVariantList( values, Qt::AscendingOrder );

int num = values.count();

const QgsFields fields = layer->fields();
for ( int i = 0; i < num; i++ )
{
QVariant value = values[i];
QgsSymbol *newSymbol = symbol->clone();
if ( ! value.isNull() )
{
int fieldIdx = fields.lookupField( attrName );
QString categoryName = value.toString();
if ( fieldIdx != -1 )
{
QgsField field = fields.at( fieldIdx );
const QgsEditorWidgetSetup setup = field.editorWidgetSetup();
const QgsFieldFormatter *formatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
categoryName = formatter->representValue( layer, fieldIdx, setup.config(), QVariant(), value );
}
cats.append( QgsRendererCategory( value, newSymbol, categoryName, true ) );
}
}

// add null (default) value
QgsSymbol *newSymbol = symbol->clone();
cats.append( QgsRendererCategory( QVariant( "" ), newSymbol, QString(), true ) );
}


void QgsCategorizedSymbolRendererWidget::addCategories()
{
QString attrName = mExpressionWidget->currentField();
int idx = mLayer->fields().lookupField( attrName );
QList<QVariant> unique_vals;
QList<QVariant> uniqueValues;
if ( idx == -1 )
{
// Lets assume it's an expression
Expand All @@ -693,21 +661,21 @@ void QgsCategorizedSymbolRendererWidget::addCategories()
{
context.setFeature( feature );
QVariant value = expression->evaluate( &context );
if ( unique_vals.contains( value ) )
if ( uniqueValues.contains( value ) )
continue;
unique_vals << value;
uniqueValues << value;
}
}
else
{
unique_vals = mLayer->uniqueValues( idx ).toList();
uniqueValues = mLayer->uniqueValues( idx ).toList();
}

// ask to abort if too many classes
if ( unique_vals.size() >= 1000 )
if ( uniqueValues.size() >= 1000 )
{
int res = QMessageBox::warning( nullptr, tr( "Classify Categories" ),
tr( "High number of classes. Classification would yield %1 entries which might not be expected. Continue?" ).arg( unique_vals.size() ),
tr( "High number of classes. Classification would yield %1 entries which might not be expected. Continue?" ).arg( uniqueValues.size() ),
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Cancel );
if ( res == QMessageBox::Cancel )
Expand All @@ -722,8 +690,7 @@ void QgsCategorizedSymbolRendererWidget::addCategories()
return;
#endif

QgsCategoryList cats;
_createCategories( cats, unique_vals, mCategorizedSymbol.get(), mLayer, attrName );
QgsCategoryList cats = QgsCategorizedSymbolRenderer::createCategories( uniqueValues, mCategorizedSymbol.get(), mLayer, attrName );
bool deleteExisting = false;

if ( !mOldClassificationAttribute.isEmpty() &&
Expand Down

0 comments on commit 8b6eaea

Please sign in to comment.