Skip to content

Commit

Permalink
[FEATURE] Allow definition of rendering order for renderers
Browse files Browse the repository at this point in the history
This allows defining the order in which features are processed by
renderers.
  • Loading branch information
m-kuhn committed Dec 22, 2015
1 parent a5f8818 commit 73ba0e8
Show file tree
Hide file tree
Showing 16 changed files with 545 additions and 31 deletions.
34 changes: 34 additions & 0 deletions python/gui/qgsorderbydialog.sip
@@ -0,0 +1,34 @@
/***************************************************************************
qgsorderbydialog.h

---------------------
begin : 20.12.2015
copyright : (C) 2015 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

class QgsOrderByDialog : QDialog
{
%TypeHeaderCode
#include "qgsorderbydialog.h"
%End
public:
QgsOrderByDialog( QgsVectorLayer* layer, QWidget* parent = nullptr );

/**
* Set the order by to manage
*/
void setOrderBys( const QList<QgsFeatureRequest::OrderByClause>& orderBys );

/**
* Get the order by defined in the dialog
*/
QgsFeatureRequest::OrderBy orderBys();
};
2 changes: 1 addition & 1 deletion src/core/qgsfeaturerequest.cpp
Expand Up @@ -346,7 +346,7 @@ void QgsFeatureRequest::OrderBy::load( const QDomElement& elem )
for ( int i = 0; i < clauses.size(); ++i )
{
QDomElement clauseElem = clauses.at( i ).toElement();
QString expression = clauseElem.toText().data();
QString expression = clauseElem.text();
bool asc = clauseElem.attribute( "asc" ).toInt() != 0;
bool nullsFirst = clauseElem.attribute( "nullsFirst" ).toInt() != 0;

Expand Down
5 changes: 4 additions & 1 deletion src/core/qgsvectorlayerrenderer.cpp
Expand Up @@ -150,10 +150,13 @@ bool QgsVectorLayerRenderer::render()
QgsRectangle requestExtent = mContext.extent();
mRendererV2->modifyRequestExtent( requestExtent, mContext );

QgsFeatureRequest::OrderBy orderBy = mRendererV2->orderBy();

QgsFeatureRequest featureRequest = QgsFeatureRequest()
.setFilterRect( requestExtent )
.setSubsetOfAttributes( mAttrNames, mFields )
.setExpressionContext( mContext.expressionContext() );
.setExpressionContext( mContext.expressionContext() )
.setOrderBys( orderBy );

const QgsFeatureFilterProvider* featureFilterProvider = mContext.featureFilterProvider();
if ( featureFilterProvider )
Expand Down
9 changes: 8 additions & 1 deletion src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
Expand Up @@ -498,7 +498,7 @@ QgsCategorizedSymbolRendererV2* QgsCategorizedSymbolRendererV2::clone() const
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setSizeScaleField( sizeScaleField() );

copyPaintEffect( r );
copyRendererData( r );
return r;
}

Expand Down Expand Up @@ -761,6 +761,13 @@ QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( "orderby" );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}

return rendererElem;
}

Expand Down
9 changes: 8 additions & 1 deletion src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Expand Up @@ -529,7 +529,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::clone() const
r->setSizeScaleField( sizeScaleField() );
r->setLabelFormat( labelFormat() );
r->setGraduatedMethod( graduatedMethod() );
copyPaintEffect( r );
copyRendererData( r );
return r;
}

Expand Down Expand Up @@ -1171,6 +1171,13 @@ QDomElement QgsGraduatedSymbolRendererV2::save( QDomDocument& doc )
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( "orderby" );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}

return rendererElem;
}

Expand Down
9 changes: 8 additions & 1 deletion src/core/symbology-ng/qgsheatmaprenderer.cpp
Expand Up @@ -297,7 +297,7 @@ QgsHeatmapRenderer* QgsHeatmapRenderer::clone() const
newRenderer->setMaximumValue( mExplicitMax );
newRenderer->setRenderQuality( mRenderQuality );
newRenderer->setWeightExpression( mWeightExpressionString );
copyPaintEffect( newRenderer );
copyRendererData( newRenderer );

return newRenderer;
}
Expand Down Expand Up @@ -365,6 +365,13 @@ QDomElement QgsHeatmapRenderer::save( QDomDocument& doc )
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( "orderby" );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}

return rendererElem;
}

Expand Down
30 changes: 29 additions & 1 deletion src/core/symbology-ng/qgsrendererv2.cpp
Expand Up @@ -204,14 +204,22 @@ void QgsFeatureRendererV2::setScaleMethodToSymbol( QgsSymbolV2* symbol, int scal
}
}

void QgsFeatureRendererV2::copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const
void QgsFeatureRendererV2::copyRendererData( QgsFeatureRendererV2* destRenderer ) const
{
if ( !destRenderer || !mPaintEffect )
return;

destRenderer->setPaintEffect( mPaintEffect->clone() );
destRenderer->mOrderBy = mOrderBy;
}

void QgsFeatureRendererV2::copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const
{
if ( !destRenderer || !mPaintEffect )
return;

destRenderer->setPaintEffect( mPaintEffect->clone() );
}

QgsFeatureRendererV2::QgsFeatureRendererV2( const QString& type )
: mType( type )
Expand Down Expand Up @@ -331,6 +339,10 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::load( QDomElement& element )
{
r->setPaintEffect( QgsPaintEffectRegistry::instance()->createEffect( effectElem ) );
}

// restore order by
QDomElement orderByElem = element.firstChildElement( "orderby" );
r->mOrderBy.load( orderByElem );
}
return r;
}
Expand All @@ -344,6 +356,12 @@ QDomElement QgsFeatureRendererV2::save( QDomDocument& doc )
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( "orderby" );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
return rendererElem;
}

Expand Down Expand Up @@ -598,6 +616,16 @@ void QgsFeatureRendererV2::setPaintEffect( QgsPaintEffect *effect )
mPaintEffect = effect;
}

QgsFeatureRequest::OrderBy QgsFeatureRendererV2::orderBy()
{
return mOrderBy;
}

void QgsFeatureRendererV2::setOrderBy( const QgsFeatureRequest::OrderBy& orderBys )
{
mOrderBy = orderBys;
}

void QgsFeatureRendererV2::convertSymbolSizeScale( QgsSymbolV2 * symbol, QgsSymbolV2::ScaleMethod method, const QString & field )
{
if ( symbol->type() == QgsSymbolV2::Marker )
Expand Down
28 changes: 27 additions & 1 deletion src/core/symbology-ng/qgsrendererv2.h
Expand Up @@ -21,6 +21,7 @@
#include "qgsrendercontext.h"
#include "qgssymbolv2.h"
#include "qgsfield.h"
#include "qgsfeaturerequest.h"

#include <QList>
#include <QString>
Expand Down Expand Up @@ -343,6 +344,18 @@ class CORE_EXPORT QgsFeatureRendererV2
*/
void setForceRasterRender( bool forceRaster ) { mForceRaster = forceRaster; }

/**
* Get the order in which features shall be processed by this renderer.
* @note added in QGIS 2.14
*/
QgsFeatureRequest::OrderBy orderBy();

/**
* Define the order in which features shall be processed by this renderer.
* @note added in QGIS 2.14
*/
void setOrderBy( const QgsFeatureRequest::OrderBy& orderBys );

protected:
QgsFeatureRendererV2( const QString& type );

Expand All @@ -366,10 +379,21 @@ class CORE_EXPORT QgsFeatureRendererV2

void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );

/**
* Clones generic renderer data to another renderer.
* Currently clones
* * Order By
* * Paint Effect
*
* @param destRenderer destination renderer for copied effect
*/
void copyRendererData( QgsFeatureRendererV2 *destRenderer ) const;

/** Copies paint effect of this renderer to another renderer
* @param destRenderer destination renderer for copied effect
* @deprecated use copyRendererData instead
*/
void copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const;
Q_DECL_DEPRECATED void copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const;

QString mType;

Expand All @@ -393,6 +417,8 @@ class CORE_EXPORT QgsFeatureRendererV2
*/
static void convertSymbolRotation( QgsSymbolV2 * symbol, const QString & field );

QgsFeatureRequest::OrderBy mOrderBy;

private:
Q_DISABLE_COPY( QgsFeatureRendererV2 )
};
Expand Down
8 changes: 7 additions & 1 deletion src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
Expand Up @@ -201,7 +201,7 @@ QgsSingleSymbolRendererV2* QgsSingleSymbolRendererV2::clone() const
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setSizeScaleField( sizeScaleField() );
copyPaintEffect( r );
copyRendererData( r );
return r;
}

Expand Down Expand Up @@ -381,6 +381,12 @@ QDomElement QgsSingleSymbolRendererV2::save( QDomDocument& doc )
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( "orderby" );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
return rendererElem;
}

Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -238,6 +238,7 @@ SET(QGIS_GUI_SRCS
qgsnewvectorlayerdialog.cpp
qgsnumericsortlistviewitem.cpp
qgsoptionsdialogbase.cpp
qgsorderbydialog.cpp
qgsowssourceselect.cpp
qgspixmaplabel.cpp
qgspluginmanagerinterface.cpp
Expand Down Expand Up @@ -367,6 +368,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsnewnamedialog.h
qgsnewvectorlayerdialog.h
qgsoptionsdialogbase.h
qgsorderbydialog.h
qgsowssourceselect.h
qgspixmaplabel.h
qgspluginmanagerinterface.h
Expand Down

1 comment on commit 73ba0e8

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 73ba0e8 Jan 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-kuhn spotted an order by related crasher: http://hub.qgis.org/issues/14164

Please sign in to comment.