Skip to content

Commit

Permalink
Unit tests for theme based layout rendering feature collection
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 20, 2019
1 parent cf19528 commit 763e2ef
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/core/layout/qgslayoutgeopdfexporter.cpp
Expand Up @@ -40,6 +40,7 @@ class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface

QgsGeoPdfRenderedFeatureHandler( QgsLayoutItemMap *map, QgsLayoutGeoPdfExporter *exporter )
: mExporter( exporter )
, mMap( map )
{
// get page size
const QgsLayoutSize pageSize = map->layout()->pageCollection()->page( map->page() )->pageSize();
Expand Down Expand Up @@ -71,6 +72,7 @@ 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();
const QString theme = ( mMap->mExportThemes.isEmpty() || mMap->mExportThemeIt == mMap->mExportThemes.end() ) ? QString() : *mMap->mExportThemeIt;

// transform from pixels to map item coordinates
QTransform pixelToMapItemTransform = QTransform::fromScale( 1.0 / context.renderContext.scaleFactor(), 1.0 / context.renderContext.scaleFactor() );
Expand All @@ -84,7 +86,7 @@ class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface
// always convert to multitype, to make things consistent
transformed.convertToMultiType();

mExporter->pushRenderedFeature( layerId, QgsLayoutGeoPdfExporter::RenderedFeature( feature, transformed ) );
mExporter->pushRenderedFeature( layerId, QgsLayoutGeoPdfExporter::RenderedFeature( feature, transformed ), theme );
}

QSet<QString> usedAttributes( QgsVectorLayer *, const QgsRenderContext & ) const override
Expand All @@ -96,6 +98,7 @@ class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface
QTransform mMapToLayoutTransform;
QTransform mLayoutToPdfTransform;
QgsLayoutGeoPdfExporter *mExporter = nullptr;
QgsLayoutItemMap *mMap = nullptr;
};
///@endcond

Expand Down
5 changes: 4 additions & 1 deletion src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -1171,7 +1171,10 @@ QgsLayoutItem::ExportLayerDetail QgsLayoutItemMap::exportLayerDetails() const
if ( !layers.isEmpty() )
{
const QgsMapLayer *layer = layers.constLast();
detail.name = QStringLiteral( "%1: %2" ).arg( displayName(), layer->name() );
if ( !detail.mapTheme.isEmpty() )
detail.name = QStringLiteral( "%1 (%2): %3" ).arg( displayName(), detail.mapTheme, layer->name() );
else
detail.name = QStringLiteral( "%1: %2" ).arg( displayName(), layer->name() );
detail.mapLayerId = layer->id();
}
}
Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutitemmap.h
Expand Up @@ -840,6 +840,7 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
friend class QgsLayoutItemLegend;
friend class TestQgsLayoutMap;
friend class QgsCompositionConverter;
friend class QgsGeoPdfRenderedFeatureHandler;

};

Expand Down
119 changes: 119 additions & 0 deletions tests/src/core/testqgslayoutgeopdfexport.cpp
Expand Up @@ -23,6 +23,7 @@
#include "qgsproject.h"
#include "qgslayoutexporter.h"
#include "qgslayoutgeopdfexporter.h"
#include "qgsmapthemecollection.h"
#include <gdal.h>

#include <QObject>
Expand Down Expand Up @@ -95,6 +96,22 @@ void TestQgsLayoutGeoPdfExport::testCollectingFeatures()
p.addMapLayer( pointsLayer );
p.addMapLayer( polygonLayer );

QgsMapThemeCollection::MapThemeRecord rec;
rec.setLayerRecords( QList<QgsMapThemeCollection::MapThemeLayerRecord>()
<< QgsMapThemeCollection::MapThemeLayerRecord( linesLayer )
);

p.mapThemeCollection()->insert( QStringLiteral( "test preset" ), rec );
rec.setLayerRecords( QList<QgsMapThemeCollection::MapThemeLayerRecord>()
<< QgsMapThemeCollection::MapThemeLayerRecord( linesLayer )
<< QgsMapThemeCollection::MapThemeLayerRecord( pointsLayer )
);
p.mapThemeCollection()->insert( QStringLiteral( "test preset2" ), rec );
rec.setLayerRecords( QList<QgsMapThemeCollection::MapThemeLayerRecord>()
<< QgsMapThemeCollection::MapThemeLayerRecord( polygonLayer )
);
p.mapThemeCollection()->insert( QStringLiteral( "test preset3" ), rec );

QgsLayout l( &p );
l.initializeDefaults();
QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
Expand Down Expand Up @@ -231,6 +248,108 @@ void TestQgsLayoutGeoPdfExport::testCollectingFeatures()
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( layer3->isValid() );
QCOMPARE( layer3->featureCount(), 10L );



// test for theme based export here!
l.renderContext().setExportThemes( QStringList() << QStringLiteral( "test preset2" ) << QStringLiteral( "test preset" ) << QStringLiteral( "test preset3" ) );
map2->setFollowVisibilityPreset( true );
map2->setFollowVisibilityPresetName( QStringLiteral( "test preset3" ) );

QgsLayoutGeoPdfExporter geoPdfExporter2( &l );
const QString outputFile2 = geoPdfExporter2.generateTemporaryFilepath( QStringLiteral( "test_src2.pdf" ) );
settings = QgsLayoutExporter::PdfExportSettings();
settings.writeGeoPdf = true;
settings.exportMetadata = false;
exporter.exportToPdf( outputFile, settings );

// check that features were collected
lineFeatures = geoPdfExporter2.mCollatedFeatures.value( QString() ).value( linesLayer->id() );
QCOMPARE( lineFeatures.count(), 0 );
lineFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset2" ) ).value( linesLayer->id() );
QCOMPARE( lineFeatures.count(), 6 );
lineFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset" ) ).value( linesLayer->id() );
QCOMPARE( lineFeatures.count(), 6 );
lineFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset3" ) ).value( linesLayer->id() );
QCOMPARE( lineFeatures.count(), 0 );

pointFeatures = geoPdfExporter2.mCollatedFeatures.value( QString() ).value( pointsLayer->id() );
QCOMPARE( pointFeatures.count(), 0 );
pointFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset2" ) ).value( pointsLayer->id() );
QCOMPARE( pointFeatures.count(), 15 );
pointFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset" ) ).value( pointsLayer->id() );
QCOMPARE( pointFeatures.count(), 0 );
pointFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset3" ) ).value( pointsLayer->id() );
QCOMPARE( pointFeatures.count(), 0 );

polyFeatures = geoPdfExporter2.mCollatedFeatures.value( QString() ).value( polygonLayer->id() );
QCOMPARE( polyFeatures.count(), 10 );
polyFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset2" ) ).value( polygonLayer->id() );
QCOMPARE( polyFeatures.count(), 0 );
polyFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset" ) ).value( polygonLayer->id() );
QCOMPARE( polyFeatures.count(), 0 );
polyFeatures = geoPdfExporter2.mCollatedFeatures.value( QStringLiteral( "test preset3" ) ).value( polygonLayer->id() );
QCOMPARE( polyFeatures.count(), 10 );

// finalize and test collation
details = QgsAbstractGeoPdfExporter::ExportDetails();
QCOMPARE( geoPdfExporter2.finalize( QList<QgsAbstractGeoPdfExporter::ComponentLayerDetail>(), outputFile, details ), expected );
QVERIFY( geoPdfExporter2.errorMessage().isEmpty() );

vectorDetail = QgsAbstractGeoPdfExporter::VectorComponentDetail();
for ( const auto &it : geoPdfExporter2.mVectorComponents )
{
if ( it.mapLayerId == linesLayer->id() && it.group == QStringLiteral( "test preset2" ) )
vectorDetail = it;
}

// read in as vector
layer1 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "%1|layername=%2" ).arg( vectorDetail.sourceVectorPath, vectorDetail.sourceVectorLayer ),
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( layer1->isValid() );
QCOMPARE( layer1->featureCount(), 6L );
vectorDetail = QgsAbstractGeoPdfExporter::VectorComponentDetail();
for ( const auto &it : geoPdfExporter2.mVectorComponents )
{
if ( it.mapLayerId == linesLayer->id() && it.group == QStringLiteral( "test preset" ) )
vectorDetail = it;
}

// read in as vector
layer1 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "%1|layername=%2" ).arg( vectorDetail.sourceVectorPath, vectorDetail.sourceVectorLayer ),
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( layer1->isValid() );
QCOMPARE( layer1->featureCount(), 6L );
vectorDetail = QgsAbstractGeoPdfExporter::VectorComponentDetail();
for ( const auto &it : geoPdfExporter2.mVectorComponents )
{
if ( it.mapLayerId == pointsLayer->id() && it.group == QStringLiteral( "test preset2" ) )
vectorDetail = it;
}
layer2 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "%1|layername=%2" ).arg( vectorDetail.sourceVectorPath, vectorDetail.sourceVectorLayer ),
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( layer2->isValid() );
QCOMPARE( layer2->featureCount(), 15L );
vectorDetail = QgsAbstractGeoPdfExporter::VectorComponentDetail();
for ( const auto &it : geoPdfExporter2.mVectorComponents )
{
if ( it.mapLayerId == polygonLayer->id() && it.group.isEmpty() )
vectorDetail = it;
}
layer3 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "%1|layername=%2" ).arg( vectorDetail.sourceVectorPath, vectorDetail.sourceVectorLayer ),
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( layer3->isValid() );
QCOMPARE( layer3->featureCount(), 10L );
vectorDetail = QgsAbstractGeoPdfExporter::VectorComponentDetail();
for ( const auto &it : geoPdfExporter2.mVectorComponents )
{
if ( it.mapLayerId == polygonLayer->id() && it.group == QStringLiteral( "test preset3" ) )
vectorDetail = it;
}
layer3 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "%1|layername=%2" ).arg( vectorDetail.sourceVectorPath, vectorDetail.sourceVectorLayer ),
QStringLiteral( "lines" ), QStringLiteral( "ogr" ) );
QVERIFY( layer3->isValid() );
QCOMPARE( layer3->featureCount(), 10L );
}

QGSTEST_MAIN( TestQgsLayoutGeoPdfExport )
Expand Down

0 comments on commit 763e2ef

Please sign in to comment.