Skip to content

Commit 984dde1

Browse files
committed
qgscategorizedchunkloader: Add support for filter expression in request
This prevents fetching features that won't be rendered.
1 parent ca80e7f commit 984dde1

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/3d/qgscategorizedchunkloader_p.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "qgseventtracing.h"
2525
#include "qgsexpressioncontextutils.h"
2626
#include "qgsfeature3dhandler_p.h"
27+
#include "qgsfields.h"
2728
#include "qgsline3dsymbol.h"
2829
#include "qgspoint3dsymbol.h"
2930
#include "qgspolygon3dsymbol.h"
@@ -132,6 +133,107 @@ void QgsCategorizedChunkLoader::processFeature( const QgsFeature &feature ) cons
132133
handler->processFeature( feature, mContext );
133134
}
134135

136+
QString QgsCategorizedChunkLoader::filter() const
137+
{
138+
const QgsVectorLayer *layer = mFactory->mLayer;
139+
const QgsFields fields = layer->fields();
140+
const int attributeNumber = fields.lookupField( mFactory->mAttributeName );
141+
const bool isExpression = ( attributeNumber == -1 );
142+
143+
bool hasDefault = false;
144+
bool defaultActive = false;
145+
bool allActive = true;
146+
bool noneActive = true;
147+
148+
//we need to build lists of both inactive and active values, as either list may be required
149+
//depending on whether the default category is active or not
150+
QString activeValues;
151+
QString inactiveValues;
152+
153+
for ( const Qgs3DRendererCategory &category : std::as_const( mFactory->mCategories ) )
154+
{
155+
if ( category.value() == "" || QgsVariantUtils::isNull( category.value() ) )
156+
{
157+
hasDefault = true;
158+
defaultActive = category.renderState();
159+
}
160+
161+
noneActive = noneActive && !category.renderState();
162+
allActive = allActive && category.renderState();
163+
164+
const bool isList = category.value().userType() == QMetaType::Type::QVariantList;
165+
QString value = QgsExpression::quotedValue( category.value(), static_cast<QMetaType::Type>( category.value().userType() ) );
166+
167+
if ( !category.renderState() )
168+
{
169+
if ( value != "" )
170+
{
171+
if ( isList )
172+
{
173+
const QVariantList list = category.value().toList();
174+
for ( const QVariant &variant : list )
175+
{
176+
if ( !inactiveValues.isEmpty() )
177+
inactiveValues.append( ',' );
178+
179+
inactiveValues.append( QgsExpression::quotedValue( variant, isExpression ? static_cast<QMetaType::Type>( variant.userType() ) : fields.at( attributeNumber ).type() ) );
180+
}
181+
}
182+
else
183+
{
184+
if ( !inactiveValues.isEmpty() )
185+
inactiveValues.append( ',' );
186+
187+
inactiveValues.append( value );
188+
}
189+
}
190+
}
191+
else
192+
{
193+
if ( value != "" )
194+
{
195+
if ( isList )
196+
{
197+
const QVariantList list = category.value().toList();
198+
for ( const QVariant &variant : list )
199+
{
200+
if ( !activeValues.isEmpty() )
201+
activeValues.append( ',' );
202+
203+
activeValues.append( QgsExpression::quotedValue( variant, isExpression ? static_cast<QMetaType::Type>( variant.userType() ) : fields.at( attributeNumber ).type() ) );
204+
}
205+
}
206+
else
207+
{
208+
if ( !activeValues.isEmpty() )
209+
activeValues.append( ',' );
210+
211+
activeValues.append( value );
212+
}
213+
}
214+
}
215+
}
216+
217+
QString attr = isExpression ? mFactory->mAttributeName : u"\"%1\""_s.arg( mFactory->mAttributeName );
218+
219+
if ( allActive && hasDefault )
220+
{
221+
return QString();
222+
}
223+
else if ( noneActive )
224+
{
225+
return u"FALSE"_s;
226+
}
227+
else if ( defaultActive )
228+
{
229+
return u"(%1) NOT IN (%2) OR (%1) IS NULL"_s.arg( attr, inactiveValues );
230+
}
231+
else
232+
{
233+
return u"(%1) IN (%2)"_s.arg( attr, activeValues );
234+
}
235+
}
236+
135237
void QgsCategorizedChunkLoader::start()
136238
{
137239
QgsChunkNode *node = chunk();
@@ -153,6 +255,7 @@ void QgsCategorizedChunkLoader::start()
153255
request.setDestinationCrs( mContext.crs(), mContext.transformContext() );
154256
request.setSubsetOfAttributes( attributesNames, layer->fields() );
155257
request.setFilterRect( rect );
258+
request.setFilterExpression( filter() );
156259

157260
//
158261
// this will be run in a background thread

src/3d/qgscategorizedchunkloader_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class QgsCategorizedChunkLoader : public QgsChunkLoader
102102
private:
103103
const QSet<QString> prepareHandlers( const QgsBox3D &chunkExtent );
104104
void processFeature( const QgsFeature &feature ) const;
105+
QString filter() const;
105106

106107
private:
107108
const QgsCategorizedChunkLoaderFactory *mFactory = nullptr;

0 commit comments

Comments
 (0)