Skip to content
Permalink
Browse files

[FEATURE] Allow definition of rendering order for renderers

This allows defining the order in which features are processed by
renderers.
  • Loading branch information
m-kuhn committed Dec 21, 2015
1 parent a5f8818 commit 73ba0e805ac720e245a5e4308a52e8bd19d11f03
@@ -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();
};
@@ -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;

@@ -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 )
@@ -498,7 +498,7 @@ QgsCategorizedSymbolRendererV2* QgsCategorizedSymbolRendererV2::clone() const
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setSizeScaleField( sizeScaleField() );

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

@@ -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;
}

@@ -529,7 +529,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::clone() const
r->setSizeScaleField( sizeScaleField() );
r->setLabelFormat( labelFormat() );
r->setGraduatedMethod( graduatedMethod() );
copyPaintEffect( r );
copyRendererData( r );
return r;
}

@@ -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;
}

@@ -297,7 +297,7 @@ QgsHeatmapRenderer* QgsHeatmapRenderer::clone() const
newRenderer->setMaximumValue( mExplicitMax );
newRenderer->setRenderQuality( mRenderQuality );
newRenderer->setWeightExpression( mWeightExpressionString );
copyPaintEffect( newRenderer );
copyRendererData( newRenderer );

return newRenderer;
}
@@ -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;
}

@@ -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 )
@@ -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;
}
@@ -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;
}

@@ -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 )
@@ -21,6 +21,7 @@
#include "qgsrendercontext.h"
#include "qgssymbolv2.h"
#include "qgsfield.h"
#include "qgsfeaturerequest.h"

#include <QList>
#include <QString>
@@ -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 );

@@ -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;

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

QgsFeatureRequest::OrderBy mOrderBy;

private:
Q_DISABLE_COPY( QgsFeatureRendererV2 )
};
@@ -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;
}

@@ -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;
}

@@ -238,6 +238,7 @@ SET(QGIS_GUI_SRCS
qgsnewvectorlayerdialog.cpp
qgsnumericsortlistviewitem.cpp
qgsoptionsdialogbase.cpp
qgsorderbydialog.cpp
qgsowssourceselect.cpp
qgspixmaplabel.cpp
qgspluginmanagerinterface.cpp
@@ -367,6 +368,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsnewnamedialog.h
qgsnewvectorlayerdialog.h
qgsoptionsdialogbase.h
qgsorderbydialog.h
qgsowssourceselect.h
qgspixmaplabel.h
qgspluginmanagerinterface.h

1 comment on commit 73ba0e8

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn commented on 73ba0e8 Jan 25, 2016

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

Please sign in to comment.
You can’t perform that action at this time.