Skip to content

Commit

Permalink
When a vector tile style rule is set to "(all layers)", ensure
Browse files Browse the repository at this point in the history
that we correctly fetch the attributes required for the style's
filter and labeling for all layers

Fixes broken rendering of vector tile style rules set to (all layers)
which use attribute filters
  • Loading branch information
nyalldawson committed Oct 25, 2023
1 parent 6ce7645 commit 7b2d4a9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/core/vectortile/qgsvectortilemvtdecoder.cpp
Expand Up @@ -110,7 +110,20 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap<QString
continue;

QVector<QgsFeature> layerFeatures;
const QgsFields layerFields = perLayerFields[layerName];
QgsFields layerFields = perLayerFields[layerName];

const auto allLayerFields = perLayerFields.find( QString() );
if ( allLayerFields != perLayerFields.end() )
{
// need to add the fields from any "all layer" rules to every layer
for ( const QgsField &field : allLayerFields.value() )
{
if ( layerFields.lookupField( field.name() ) == -1 )
{
layerFields.append( field );
}
}
}

// figure out how field indexes in MVT encoding map to field indexes in QgsFields (we may not use all available fields)
QHash<int, int> tagKeyIndexToFieldIndex;
Expand Down
42 changes: 42 additions & 0 deletions tests/src/core/testqgsvectortilelayer.cpp
Expand Up @@ -77,6 +77,7 @@ class TestQgsVectorTileLayer : public QgsTest
void test_polygonWithMarker();

void test_styleMinZoomBeyondTileMaxZoom();
void test_filterRuleAllLayers();
};


Expand Down Expand Up @@ -637,6 +638,47 @@ void TestQgsVectorTileLayer::test_styleMinZoomBeyondTileMaxZoom()
QStringLiteral( "render_test_style_min_zoom" ), *mMapSettings, 0, 15 ) );
}

void TestQgsVectorTileLayer::test_filterRuleAllLayers()
{
// test using a filter with field access for an "all layers" rule
QgsDataSourceUri ds;
ds.setParam( "type", "mbtiles" );
ds.setParam( "url", QString( "/%1/mbtiles_vt.mbtiles" ).arg( mDataDir ) );
std::unique_ptr< QgsVectorTileLayer > layer = std::make_unique< QgsVectorTileLayer >( ds.encodedUri(), "Vector Tiles Test" );
QVERIFY( layer->isValid() );

mMapSettings->setLayers( QList<QgsMapLayer *>() << layer.get() );

const QColor lineStrokeColor = Qt::blue;
const double lineStrokeWidth = DEFAULT_LINE_WIDTH * 4;

QgsSimpleLineSymbolLayer *lineSymbolLayer = new QgsSimpleLineSymbolLayer;
lineSymbolLayer->setColor( lineStrokeColor );
lineSymbolLayer->setWidth( lineStrokeWidth );
QgsLineSymbol *lineSymbol = new QgsLineSymbol( QgsSymbolLayerList() << lineSymbolLayer );

QgsVectorTileBasicRendererStyle st( QStringLiteral( "Lines" ), QString(), Qgis::GeometryType::Line );
st.setFilterExpression( QStringLiteral( "\"Name\"='Highway'" ) );
st.setSymbol( lineSymbol );

QgsSimpleFillSymbolLayer *fillSymbolLayer = new QgsSimpleFillSymbolLayer;
fillSymbolLayer->setColor( Qt::white );
fillSymbolLayer->setStrokeStyle( Qt::NoPen );
QgsFillSymbol *fillSymbol = new QgsFillSymbol( QgsSymbolLayerList() << fillSymbolLayer );

QgsVectorTileBasicRendererStyle bgst( QStringLiteral( "background" ), QStringLiteral( "background" ), Qgis::GeometryType::Polygon );
bgst.setSymbol( fillSymbol );

QgsVectorTileBasicRenderer *rend = new QgsVectorTileBasicRenderer;
rend->setStyles( QList<QgsVectorTileBasicRendererStyle>() << bgst << st );
layer->setRenderer( rend ); // takes ownership

mMapSettings->setExtent( layer->extent() );
mMapSettings->setDestinationCrs( layer->crs() );
QVERIFY( renderMapSettingsCheck( QStringLiteral( "render_test_filter_all_layers" ),
QStringLiteral( "render_test_filter_all_layers" ), *mMapSettings, 0, 15 ) );
}


QGSTEST_MAIN( TestQgsVectorTileLayer )
#include "testqgsvectortilelayer.moc"
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7b2d4a9

Please sign in to comment.