Don't export features for layers set to skip

This commit is contained in:
Nyall Dawson 2019-08-21 08:00:18 +10:00
parent d014d63ede
commit 94921f483b
2 changed files with 76 additions and 2 deletions

View File

@ -38,9 +38,10 @@ class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface
{
public:
QgsGeoPdfRenderedFeatureHandler( QgsLayoutItemMap *map, QgsLayoutGeoPdfExporter *exporter )
QgsGeoPdfRenderedFeatureHandler( QgsLayoutItemMap *map, QgsLayoutGeoPdfExporter *exporter, const QStringList &layerIds )
: mExporter( exporter )
, mMap( map )
, mLayerIds( layerIds )
{
// get page size
const QgsLayoutSize pageSize = map->layout()->pageCollection()->page( map->page() )->pageSize();
@ -72,6 +73,9 @@ class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface
// the alternative is adding a layer ID member to QgsRenderContext, and that's just asking for people to abuse it
// and use it to retrieve QgsMapLayers mid-way through a render operation. Lesser of two evils it is!
const QString layerId = context.renderContext.expressionContext().variable( QStringLiteral( "layer_id" ) ).toString();
if ( !mLayerIds.contains( layerId ) )
return;
const QString theme = ( mMap->mExportThemes.isEmpty() || mMap->mExportThemeIt == mMap->mExportThemes.end() ) ? QString() : *mMap->mExportThemeIt;
// transform from pixels to map item coordinates
@ -99,18 +103,34 @@ class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface
QTransform mLayoutToPdfTransform;
QgsLayoutGeoPdfExporter *mExporter = nullptr;
QgsLayoutItemMap *mMap = nullptr;
QStringList mLayerIds;
};
///@endcond
QgsLayoutGeoPdfExporter::QgsLayoutGeoPdfExporter( QgsLayout *layout )
: mLayout( layout )
{
// build a list of exportable feature layers in advance
QStringList exportableLayerIds;
const QMap< QString, QgsMapLayer * > layers = mLayout->project()->mapLayers( true );
for ( auto it = layers.constBegin(); it != layers.constEnd(); ++it )
{
if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
{
const QVariant v = vl->customProperty( QStringLiteral( "geopdf/includeFeatures" ) );
if ( !v.isValid() || v.toBool() )
{
exportableLayerIds << vl->id();
}
}
}
// on construction, we install a rendered feature handler on layout item maps
QList< QgsLayoutItemMap * > maps;
mLayout->layoutItems( maps );
for ( QgsLayoutItemMap *map : qgis::as_const( maps ) )
{
QgsGeoPdfRenderedFeatureHandler *handler = new QgsGeoPdfRenderedFeatureHandler( map, this );
QgsGeoPdfRenderedFeatureHandler *handler = new QgsGeoPdfRenderedFeatureHandler( map, this, exportableLayerIds );
mMapHandlers.insert( map, handler );
map->addRenderedFeatureHandler( handler );
}

View File

@ -42,6 +42,7 @@ class TestQgsLayoutGeoPdfExport : public QObject
void init();// will be called before each testfunction is executed.
void cleanup();// will be called after every testfunction.
void testCollectingFeatures();
void skipLayers();
private:
@ -352,5 +353,58 @@ void TestQgsLayoutGeoPdfExport::testCollectingFeatures()
QCOMPARE( layer3->featureCount(), 10L );
}
void TestQgsLayoutGeoPdfExport::skipLayers()
{
QgsVectorLayer *linesLayer = new QgsVectorLayer( TEST_DATA_DIR + QStringLiteral( "/lines.shp" ),
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( linesLayer->isValid() );
QgsVectorLayer *pointsLayer = new QgsVectorLayer( TEST_DATA_DIR + QStringLiteral( "/points.shp" ),
QStringLiteral( "points" ), QStringLiteral( "ogr" ) );
QVERIFY( pointsLayer->isValid() );
QgsVectorLayer *polygonLayer = new QgsVectorLayer( TEST_DATA_DIR + QStringLiteral( "/polys.shp" ),
QStringLiteral( "polys" ), QStringLiteral( "ogr" ) );
QVERIFY( polygonLayer->isValid() );
pointsLayer->setDisplayExpression( QStringLiteral( "Staff" ) );
QgsProject p;
p.addMapLayer( linesLayer );
p.addMapLayer( pointsLayer );
p.addMapLayer( polygonLayer );
linesLayer->setCustomProperty( QStringLiteral( "geopdf/includeFeatures" ), false );
pointsLayer->setCustomProperty( QStringLiteral( "geopdf/includeFeatures" ), true );
// nothing specifically set for polygonLayer => should be included
QgsLayout l( &p );
l.initializeDefaults();
QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
map->attemptSetSceneRect( QRectF( 20, 20, 200, 100 ) );
map->setFrameEnabled( true );
map->setLayers( QList<QgsMapLayer *>() << linesLayer << pointsLayer << polygonLayer );
map->setCrs( linesLayer->crs() );
map->zoomToExtent( linesLayer->extent() );
map->setBackgroundColor( QColor( 200, 220, 230 ) );
map->setBackgroundEnabled( true );
l.addLayoutItem( map );
QgsLayoutGeoPdfExporter geoPdfExporter( &l );
// trigger render
QgsLayoutExporter exporter( &l );
const QString outputFile = geoPdfExporter.generateTemporaryFilepath( QStringLiteral( "test_src.pdf" ) );
QgsLayoutExporter::PdfExportSettings settings;
settings.writeGeoPdf = true;
settings.exportMetadata = false;
exporter.exportToPdf( outputFile, settings );
// check that features were collected
QgsFeatureList lineFeatures = geoPdfExporter.mCollatedFeatures.value( QString() ).value( linesLayer->id() );
QCOMPARE( lineFeatures.count(), 0 ); // should be nothing, layer is set to skip
QgsFeatureList pointFeatures = geoPdfExporter.mCollatedFeatures.value( QString() ).value( pointsLayer->id() );
QCOMPARE( pointFeatures.count(), 15 ); // should be features, layer was set to export
QgsFeatureList polyFeatures = geoPdfExporter.mCollatedFeatures.value( QString() ).value( polygonLayer->id() );
QCOMPARE( polyFeatures.count(), 10 ); // should be features, layer did not have any setting set
}
QGSTEST_MAIN( TestQgsLayoutGeoPdfExport )
#include "testqgslayoutgeopdfexport.moc"