76
76
#include < QDir>
77
77
78
78
// for printing
79
+ #include " qgslayoutatlas.h"
79
80
#include " qgslayoutmanager.h"
80
81
#include " qgslayoutexporter.h"
81
82
#include " qgslayoutsize.h"
@@ -375,7 +376,86 @@ namespace QgsWms
375
376
376
377
std::unique_ptr<QgsPrintLayout> layout ( sourceLayout->clone () );
377
378
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 );
379
459
380
460
// Get the temporary output file
381
461
QTemporaryFile tempOutputFile ( QDir::tempPath () + ' /' + QStringLiteral ( " XXXXXX.%1" ).arg ( formatString.toLower () ) );
@@ -385,7 +465,14 @@ namespace QgsWms
385
465
386
466
}
387
467
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 )
389
476
{
390
477
// Settings for the layout exporter
391
478
QgsLayoutExporter::SvgExportSettings exportSettings;
@@ -454,7 +541,7 @@ namespace QgsWms
454
541
return tempOutputFile.readAll ();
455
542
}
456
543
457
- bool QgsRenderer::configurePrintLayout ( QgsPrintLayout *c, const QgsMapSettings &mapSettings )
544
+ bool QgsRenderer::configurePrintLayout ( QgsPrintLayout *c, const QgsMapSettings &mapSettings, bool atlasPrint )
458
545
{
459
546
c->renderContext ().setSelectionColor ( mapSettings.selectionColor () );
460
547
// Maps are configured first
@@ -463,42 +550,46 @@ namespace QgsWms
463
550
// Layout maps now use a string UUID as "id", let's assume that the first map
464
551
// has id 0 and so on ...
465
552
int mapId = 0 ;
553
+
466
554
for ( const auto &map : qgis::as_const ( maps ) )
467
555
{
468
556
QgsWmsParametersComposerMap cMapParams = mWmsParameters .composerMapParameters ( mapId );
469
557
mapId++;
470
558
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
487
560
{
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 );
491
581
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
+ }
497
587
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
+ }
502
593
}
503
594
504
595
if ( !map->keepLayerSet () )
0 commit comments