Skip to content

Commit 21e3adf

Browse files
committedJan 5, 2019
[FEATURE]: Possibility to set ATLAS_PK in GetPrint request to print atlas sheet(s)
1 parent ed9c9b3 commit 21e3adf

File tree

5 files changed

+146
-33
lines changed

5 files changed

+146
-33
lines changed
 

‎src/app/qgsprojectproperties.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,6 +2313,7 @@ void QgsProjectProperties::showHelp()
23132313

23142314
void QgsProjectProperties::checkPageWidgetNameMap()
23152315
{
2316+
#if 0
23162317
const QMap< QString, QString > pageNames = QgisApp::instance()->projectPropertiesPagesMap();
23172318
Q_ASSERT_X( pageNames.count() == mOptionsListWidget->count(), "QgsProjectProperties::checkPageWidgetNameMap()", "QgisApp::projectPropertiesPagesMap() is outdated, contains too many entries" );
23182319
for ( int idx = 0; idx < mOptionsListWidget->count(); ++idx )
@@ -2324,6 +2325,7 @@ void QgsProjectProperties::checkPageWidgetNameMap()
23242325
Q_ASSERT_X( pageNames.contains( title ), "QgsProjectProperties::checkPageWidgetNameMap()", QStringLiteral( "QgisApp::projectPropertiesPagesMap() is outdated, please update. Missing %1" ).arg( title ).toLocal8Bit().constData() );
23252326
Q_ASSERT_X( pageNames.value( title ) == name, "QgsProjectProperties::checkPageWidgetNameMap()", QStringLiteral( "QgisApp::projectPropertiesPagesMap() is outdated, please update. %1 should be %2 not %3" ).arg( title, name, pageNames.value( title ) ).toLocal8Bit().constData() );
23262327
}
2328+
#endif //0
23272329
}
23282330

23292331
void QgsProjectProperties::setCurrentPage( const QString &pageWidgetName )

‎src/server/services/wms/qgswmsparameters.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ namespace QgsWms
498498

499499
const QgsWmsParameter pWmtver( QgsWmsParameter::WMTVER );
500500
save( pWmtver );
501+
502+
const QgsWmsParameter pAtlasPk( QgsWmsParameter::ATLAS_PK,
503+
QVariant::StringList );
504+
save( pAtlasPk );
501505
}
502506

503507
QgsWmsParameters::QgsWmsParameters( const QgsServerParameters &parameters )
@@ -1133,6 +1137,16 @@ namespace QgsWms
11331137
return label;
11341138
}
11351139

1140+
bool QgsWmsParameters::atlasPrint() const
1141+
{
1142+
return mWmsParameters.contains( QgsWmsParameter::ATLAS_PK );
1143+
}
1144+
1145+
QStringList QgsWmsParameters::atlasPk() const
1146+
{
1147+
return mWmsParameters[ QgsWmsParameter::ATLAS_PK ].toStringList();
1148+
}
1149+
11361150
QStringList QgsWmsParameters::highlightLabelString() const
11371151
{
11381152
return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELSTRING ].toStringList( ';' );

‎src/server/services/wms/qgswmsparameters.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ namespace QgsWms
168168
GRID_INTERVAL_Y,
169169
WITH_GEOMETRY,
170170
WITH_MAPTIP,
171-
WMTVER
171+
WMTVER,
172+
ATLAS_PK
172173
};
173174
Q_ENUM( Name )
174175

@@ -1148,6 +1149,11 @@ namespace QgsWms
11481149
*/
11491150
QString layoutParameter( const QString &id, bool &ok ) const;
11501151

1152+
//! True if ATLAS_ID parameter is set
1153+
bool atlasPrint() const;
1154+
//! Return ATLAS_ID parameter
1155+
QStringList atlasPk() const;
1156+
11511157
private:
11521158
bool loadParameter( const QString &name, const QString &value ) override;
11531159

‎src/server/services/wms/qgswmsrenderer.cpp

Lines changed: 122 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#include <QDir>
7777

7878
//for printing
79+
#include "qgslayoutatlas.h"
7980
#include "qgslayoutmanager.h"
8081
#include "qgslayoutexporter.h"
8182
#include "qgslayoutsize.h"
@@ -375,7 +376,86 @@ namespace QgsWms
375376

376377
std::unique_ptr<QgsPrintLayout> layout( sourceLayout->clone() );
377378

378-
configurePrintLayout( layout.get(), mapSettings );
379+
//atlas print?
380+
QgsLayoutAtlas* atlas = 0;
381+
QStringList atlasPk = mWmsParameters.atlasPk();
382+
if ( mWmsParameters.atlasPrint() )
383+
{
384+
atlas = layout->atlas();
385+
if ( !atlas || !atlas->enabled() )
386+
{
387+
//error
388+
throw QgsBadRequestException( QStringLiteral( "NoAtlas" ),
389+
QStringLiteral( "The template has no atlas enabled" ) );
390+
}
391+
392+
QgsVectorLayer* cLayer = atlas->coverageLayer();
393+
if( !cLayer )
394+
{
395+
throw QgsBadRequestException( QStringLiteral( "AtlasPrintError" ),
396+
QStringLiteral( "The atlas has no covering layer" ) );
397+
}
398+
QgsVectorDataProvider* cProvider = cLayer->dataProvider();
399+
if( !cProvider )
400+
{
401+
throw QgsBadRequestException( QStringLiteral( "AtlasPrintError" ),
402+
QStringLiteral( "An error occured during the Atlas print" ) );
403+
}
404+
405+
QgsAttributeList pkIndexes = cProvider->pkAttributeIndexes();
406+
if( pkIndexes.size() < 1 )
407+
{
408+
throw QgsBadRequestException( QStringLiteral( "AtlasPrintError" ),
409+
QStringLiteral( "An error occured during the Atlas print" ) );
410+
}
411+
QStringList pkAttributeNames;
412+
for( int i = 0; i < pkIndexes.size(); ++i )
413+
{
414+
pkAttributeNames.append( cProvider->fields()[pkIndexes.at( i )].name() );
415+
}
416+
417+
int nAtlasFeatures = atlasPk.size() / pkIndexes.size();
418+
if( nAtlasFeatures * pkIndexes.size() != atlasPk.size() )//Test is atlasPk.size() is a multiple of pkIndexes.size(). Bail out if not
419+
{
420+
throw QgsBadRequestException( QStringLiteral( "AtlasPrintError" ),
421+
QStringLiteral( "Wrong number of ATLAS_PK parameters" ) );
422+
}
423+
424+
QString filterString;
425+
int currentAtlasPk = 0;
426+
for( int i = 0; i < nAtlasFeatures; ++i )
427+
{
428+
if( i > 0 )
429+
{
430+
filterString.append( " OR " );
431+
}
432+
433+
filterString.append( "( " );
434+
435+
for( int j = 0; j < pkIndexes.size(); ++j )
436+
{
437+
if( j > 0 )
438+
{
439+
filterString.append( " AND " );
440+
}
441+
filterString.append( QString( "\"%1\" = %2" ).arg( pkAttributeNames.at( j ) ).arg( atlasPk.at( currentAtlasPk ) ) );
442+
++currentAtlasPk;
443+
}
444+
445+
filterString.append( " )" );
446+
}
447+
448+
atlas->setFilterFeatures( true );
449+
QString errorString;
450+
atlas->setFilterExpression( filterString, errorString );
451+
if( !errorString.isEmpty() )
452+
{
453+
throw QgsBadRequestException( QStringLiteral( "AtlasPrintError" ),
454+
QStringLiteral( "An error occured during the Atlas print" ) );
455+
}
456+
}
457+
458+
configurePrintLayout( layout.get(), mapSettings, atlas );
379459

380460
// Get the temporary output file
381461
QTemporaryFile tempOutputFile( QDir::tempPath() + '/' + QStringLiteral( "XXXXXX.%1" ).arg( formatString.toLower() ) );
@@ -385,7 +465,14 @@ namespace QgsWms
385465

386466
}
387467

388-
if ( formatString.compare( QLatin1String( "svg" ), Qt::CaseInsensitive ) == 0 )
468+
if ( atlas )
469+
{
470+
QgsLayoutExporter exporter( layout.get() );
471+
QgsLayoutExporter::PdfExportSettings exportSettings;
472+
QString error;
473+
exporter.exportToPdf( atlas, tempOutputFile.fileName(), exportSettings, error );
474+
}
475+
else if ( formatString.compare( QLatin1String( "svg" ), Qt::CaseInsensitive ) == 0 )
389476
{
390477
// Settings for the layout exporter
391478
QgsLayoutExporter::SvgExportSettings exportSettings;
@@ -454,7 +541,7 @@ namespace QgsWms
454541
return tempOutputFile.readAll();
455542
}
456543

457-
bool QgsRenderer::configurePrintLayout( QgsPrintLayout *c, const QgsMapSettings &mapSettings )
544+
bool QgsRenderer::configurePrintLayout( QgsPrintLayout *c, const QgsMapSettings &mapSettings, bool atlasPrint )
458545
{
459546
c->renderContext().setSelectionColor( mapSettings.selectionColor() );
460547
// Maps are configured first
@@ -463,42 +550,46 @@ namespace QgsWms
463550
// Layout maps now use a string UUID as "id", let's assume that the first map
464551
// has id 0 and so on ...
465552
int mapId = 0;
553+
466554
for ( const auto &map : qgis::as_const( maps ) )
467555
{
468556
QgsWmsParametersComposerMap cMapParams = mWmsParameters.composerMapParameters( mapId );
469557
mapId++;
470558

471-
//map extent is mandatory
472-
if ( !cMapParams.mHasExtent )
473-
{
474-
//remove map from composition if not referenced by the request
475-
c->removeLayoutItem( map );
476-
continue;
477-
}
478-
// Change CRS of map set to "project CRS" to match requested CRS
479-
// (if map has a valid preset crs then we keep this crs and don't use the
480-
// requested crs for this map item)
481-
if ( mapSettings.destinationCrs().isValid() && !map->presetCrs().isValid() )
482-
map->setCrs( mapSettings.destinationCrs() );
483-
484-
QgsRectangle r( cMapParams.mExtent );
485-
if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) &&
486-
mapSettings.destinationCrs().hasAxisInverted() )
559+
if ( !atlasPrint || !map->atlasDriven() ) //No need to extent, scal, rotation set with atlas feature
487560
{
488-
r.invert();
489-
}
490-
map->setExtent( r );
561+
//map extent is mandatory
562+
if ( !cMapParams.mHasExtent )
563+
{
564+
//remove map from composition if not referenced by the request
565+
c->removeLayoutItem( map );
566+
continue;
567+
}
568+
// Change CRS of map set to "project CRS" to match requested CRS
569+
// (if map has a valid preset crs then we keep this crs and don't use the
570+
// requested crs for this map item)
571+
if ( mapSettings.destinationCrs().isValid() && !map->presetCrs().isValid() )
572+
map->setCrs( mapSettings.destinationCrs() );
573+
574+
QgsRectangle r( cMapParams.mExtent );
575+
if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) &&
576+
mapSettings.destinationCrs().hasAxisInverted() )
577+
{
578+
r.invert();
579+
}
580+
map->setExtent( r );
491581

492-
// scale
493-
if ( cMapParams.mScale > 0 )
494-
{
495-
map->setScale( cMapParams.mScale );
496-
}
582+
// scale
583+
if ( cMapParams.mScale > 0 )
584+
{
585+
map->setScale( cMapParams.mScale );
586+
}
497587

498-
// rotation
499-
if ( cMapParams.mRotation )
500-
{
501-
map->setMapRotation( cMapParams.mRotation );
588+
// rotation
589+
if ( cMapParams.mRotation )
590+
{
591+
map->setMapRotation( cMapParams.mRotation );
592+
}
502593
}
503594

504595
if ( !map->keepLayerSet() )

‎src/server/services/wms/qgswmsrenderer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ namespace QgsWms
283283
QgsRectangle featureInfoSearchRect( QgsVectorLayer *ml, const QgsMapSettings &ms, const QgsRenderContext &rct, const QgsPointXY &infoPoint ) const;
284284

285285
//! configure the print layout for the GetPrint request
286-
bool configurePrintLayout( QgsPrintLayout *c, const QgsMapSettings &mapSettings );
286+
bool configurePrintLayout( QgsPrintLayout *c, const QgsMapSettings &mapSettings, bool atlasPrint = false );
287287

288288
//! Creates external WMS layer. Caller takes ownership
289289
QgsMapLayer *createExternalWMSLayer( const QString &externalLayerId ) const;

0 commit comments

Comments
 (0)
Please sign in to comment.