LCOV - code coverage report
Current view: top level - core - qgsabstractgeopdfexporter.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 22 0.0 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                               qgsabstractgeopdfexporter.h
       3                 :            :                              --------------------------
       4                 :            :     begin                : August 2019
       5                 :            :     copyright            : (C) 2019 by Nyall Dawson
       6                 :            :     email                : nyall dot dawson at gmail dot com
       7                 :            :  ***************************************************************************/
       8                 :            : /***************************************************************************
       9                 :            :  *                                                                         *
      10                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      11                 :            :  *   it under the terms of the GNU General Public License as published by  *
      12                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      13                 :            :  *   (at your option) any later version.                                   *
      14                 :            :  *                                                                         *
      15                 :            :  ***************************************************************************/
      16                 :            : #ifndef QGSABSTRACTGEOPDFEXPORTER_H
      17                 :            : #define QGSABSTRACTGEOPDFEXPORTER_H
      18                 :            : 
      19                 :            : #include "qgis_core.h"
      20                 :            : #include <QList>
      21                 :            : #include <QTemporaryDir>
      22                 :            : #include <QMutex>
      23                 :            : #include <QDateTime>
      24                 :            : #include <QPainter>
      25                 :            : 
      26                 :            : #include "qgsfeature.h"
      27                 :            : #include "qgsabstractmetadatabase.h"
      28                 :            : #include "qgspolygon.h"
      29                 :            : 
      30                 :            : #define SIP_NO_FILE
      31                 :            : 
      32                 :            : 
      33                 :            : class QgsGeoPdfRenderedFeatureHandler;
      34                 :            : 
      35                 :            : /**
      36                 :            :  * \class QgsAbstractGeoPdfExporter
      37                 :            :  * \ingroup core
      38                 :            :  *
      39                 :            :  * \brief Abstract base class for GeoPDF exporters.
      40                 :            :  *
      41                 :            :  * The base class handles generic GeoPDF export setup, cleanup and processing steps.
      42                 :            :  *
      43                 :            :  * This class is a low level implementation detail only. Generally, you should use the high level interface exposed by
      44                 :            :  * classes like QgsLayoutExporter instead.
      45                 :            :  *
      46                 :            :  * \warning QgsAbstractGeoPdfExporter is designed to be a short lived object. It should be created for a
      47                 :            :  * single export operation only, and then immediately destroyed. Failure to correctly
      48                 :            :  * destroy the object after exporting a PDF will leave the application in an inconsistent, unstable state.
      49                 :            :  *
      50                 :            :  * \note Not available in Python bindings
      51                 :            :  *
      52                 :            :  * \since QGIS 3.10
      53                 :            :  */
      54                 :            : class CORE_EXPORT QgsAbstractGeoPdfExporter
      55                 :            : {
      56                 :            :   public:
      57                 :            : 
      58                 :            :     /**
      59                 :            :      * Returns TRUE if the current QGIS build is capable of GeoPDF support.
      60                 :            :      *
      61                 :            :      * If FALSE is returned, a user-friendly explanation why can be retrieved via
      62                 :            :      * geoPDFAvailabilityExplanation().
      63                 :            :      */
      64                 :            :     static bool geoPDFCreationAvailable();
      65                 :            : 
      66                 :            :     /**
      67                 :            :      * Returns a user-friendly, translated string explaining why GeoPDF export
      68                 :            :      * support is not available on the current QGIS build (or an empty string if
      69                 :            :      * GeoPDF support IS available).
      70                 :            :      * \see geoPDFCreationAvailable()
      71                 :            :      */
      72                 :            :     static QString geoPDFAvailabilityExplanation();
      73                 :            : 
      74                 :            :     /**
      75                 :            :      * Constructor for QgsAbstractGeoPdfExporter.
      76                 :            :      */
      77                 :          0 :     QgsAbstractGeoPdfExporter() = default;
      78                 :            : 
      79                 :          0 :     virtual ~QgsAbstractGeoPdfExporter() = default;
      80                 :            : 
      81                 :            :     /**
      82                 :            :      * Contains information about a feature rendered inside the PDF.
      83                 :            :      */
      84                 :          0 :     struct RenderedFeature
      85                 :            :     {
      86                 :            : 
      87                 :            :       /**
      88                 :            :        * Constructor for RenderedFeature.
      89                 :            :        */
      90                 :            :       RenderedFeature() = default;
      91                 :            : 
      92                 :            :       /**
      93                 :            :        * Constructor for RenderedFeature.
      94                 :            :        */
      95                 :          0 :       RenderedFeature( const QgsFeature &feature, const QgsGeometry &renderedBounds )
      96                 :          0 :         : feature( feature )
      97                 :          0 :         , renderedBounds( renderedBounds )
      98                 :          0 :       {}
      99                 :            : 
     100                 :            :       /**
     101                 :            :        * Rendered feature.
     102                 :            :        */
     103                 :            :       QgsFeature feature;
     104                 :            : 
     105                 :            :       /**
     106                 :            :        * Bounds, in PDF units, of rendered feature. (Multi)LineString or Polygon types only.
     107                 :            :        */
     108                 :            :       QgsGeometry renderedBounds;
     109                 :            :     };
     110                 :            : 
     111                 :            :     /**
     112                 :            :      * \brief Contains details of a particular input component to be used during PDF composition.
     113                 :            :      * \ingroup core
     114                 :            :      * \since QGIS 3.10
     115                 :            :      */
     116                 :          0 :     struct CORE_EXPORT ComponentLayerDetail
     117                 :            :     {
     118                 :            : 
     119                 :            :       //! User-friendly name for the generated PDF layer
     120                 :            :       QString name;
     121                 :            : 
     122                 :            :       //! Associated map layer ID, or an empty string if this component layer is not associated with a map layer
     123                 :            :       QString mapLayerId;
     124                 :            : 
     125                 :            :       //! Optional group name, for arranging layers in top-level groups
     126                 :            :       QString group;
     127                 :            : 
     128                 :            :       //! File path to the (already created) PDF to use as the source for this component layer
     129                 :            :       QString sourcePdfPath;
     130                 :            : 
     131                 :            :       //! Component composition mode
     132                 :          0 :       QPainter::CompositionMode compositionMode = QPainter::CompositionMode_SourceOver;
     133                 :            : 
     134                 :            :       //! Component opacity
     135                 :          0 :       double opacity = 1.0;
     136                 :            : 
     137                 :            :     };
     138                 :            : 
     139                 :            :     /**
     140                 :            :      * \brief Contains details of a control point used during georeferencing GeoPDF outputs.
     141                 :            :      * \ingroup core
     142                 :            :      * \since QGIS 3.10
     143                 :            :      */
     144                 :          0 :     struct ControlPoint
     145                 :            :     {
     146                 :            : 
     147                 :            :       /**
     148                 :            :        * Constructor for ControlPoint, at the specified \a pagePoint (in millimeters)
     149                 :            :        * and \a geoPoint (in CRS units).
     150                 :            :        */
     151                 :          0 :       ControlPoint( const QgsPointXY &pagePoint, const QgsPointXY &geoPoint )
     152                 :          0 :         : pagePoint( pagePoint )
     153                 :          0 :         , geoPoint( geoPoint )
     154                 :          0 :       {}
     155                 :            : 
     156                 :            :       //! Coordinate on the page of the control point, in millimeters
     157                 :            :       QgsPointXY pagePoint;
     158                 :            : 
     159                 :            :       //! Georeferenced coordinate of the control point, in CRS units
     160                 :            :       QgsPointXY geoPoint;
     161                 :            :     };
     162                 :            : 
     163                 :          0 :     struct GeoReferencedSection
     164                 :            :     {
     165                 :            : 
     166                 :            :       /**
     167                 :            :        * Bounds of the georeferenced section on the page, in millimeters.
     168                 :            :        *
     169                 :            :        * \note if pageBoundsPolygon is specified then this setting is ignored.
     170                 :            :        */
     171                 :            :       QgsRectangle pageBoundsMm;
     172                 :            : 
     173                 :            :       /**
     174                 :            :        * Bounds of the georeferenced section on the page, in millimeters, as a free-form polygon.
     175                 :            :        *
     176                 :            :        * If specified, this will be used instead of pageBoundsMm.
     177                 :            :        */
     178                 :            :       QgsPolygon pageBoundsPolygon;
     179                 :            : 
     180                 :            :       //! Coordinate reference system for georeferenced section
     181                 :            :       QgsCoordinateReferenceSystem crs;
     182                 :            : 
     183                 :            :       //! List of control points corresponding to this georeferenced section
     184                 :            :       QList< QgsAbstractGeoPdfExporter::ControlPoint > controlPoints;
     185                 :            : 
     186                 :            :     };
     187                 :            : 
     188                 :            :     /**
     189                 :            :      * Called multiple times during the rendering operation, whenever a \a feature associated with the specified
     190                 :            :      * \a layerId is rendered.
     191                 :            :      *
     192                 :            :      * The optional \a group argument can be used to differentiate features from the same layer exported
     193                 :            :      * multiple times as part of different layer groups.
     194                 :            :      */
     195                 :            :     void pushRenderedFeature( const QString &layerId, const QgsAbstractGeoPdfExporter::RenderedFeature &feature, const QString &group = QString() );
     196                 :            : 
     197                 :          0 :     struct ExportDetails
     198                 :            :     {
     199                 :            :       //! Page size, in millimeters
     200                 :            :       QSizeF pageSizeMm;
     201                 :            : 
     202                 :            :       //! Output DPI
     203                 :          0 :       double dpi = 300;
     204                 :            : 
     205                 :            :       //! List of georeferenced sections
     206                 :            :       QList< QgsAbstractGeoPdfExporter::GeoReferencedSection > georeferencedSections;
     207                 :            : 
     208                 :            :       //! Metadata author tag
     209                 :            :       QString author;
     210                 :            : 
     211                 :            :       //! Metadata producer tag
     212                 :            :       QString producer;
     213                 :            : 
     214                 :            :       //! Metadata creator tag
     215                 :            :       QString creator;
     216                 :            : 
     217                 :            :       //! Metadata creation datetime
     218                 :            :       QDateTime creationDateTime;
     219                 :            : 
     220                 :            :       //! Metadata subject tag
     221                 :            :       QString subject;
     222                 :            : 
     223                 :            :       //! Metadata title tag
     224                 :            :       QString title;
     225                 :            : 
     226                 :            :       //! Metadata keyword map
     227                 :            :       QgsAbstractMetadataBase::KeywordMap keywords;
     228                 :            : 
     229                 :            :       /**
     230                 :            :        * TRUE if ISO3200 extension format georeferencing should be used.
     231                 :            :        *
     232                 :            :        * This is a recommended setting which results in Geospatial PDF files compatible
     233                 :            :        * with the built-in Acrobat geospatial tools.
     234                 :            :        */
     235                 :          0 :       bool useIso32000ExtensionFormatGeoreferencing = true;
     236                 :            : 
     237                 :            :       /**
     238                 :            :        * TRUE if OGC "best practice" format georeferencing should be used.
     239                 :            :        *
     240                 :            :        * \warning This results in GeoPDF files compatible with the TerraGo suite of tools, but
     241                 :            :        * can break compatibility with the built-in Acrobat geospatial tools (yes, GeoPDF
     242                 :            :        * format is a mess!).
     243                 :            :       */
     244                 :          0 :       bool useOgcBestPracticeFormatGeoreferencing = false;
     245                 :            : 
     246                 :            :       /**
     247                 :            :        * TRUE if feature vector information (such as attributes) should be exported.
     248                 :            :        */
     249                 :          0 :       bool includeFeatures = true;
     250                 :            : 
     251                 :            :       /**
     252                 :            :        * Optional map of map layer ID to custom logical layer tree group in created PDF file.
     253                 :            :        *
     254                 :            :        * E.g. if the map contains "layer1": "Environment", "layer2": "Environment", "layer3": "Transport"
     255                 :            :        * then the created PDF file will have entries in its layer tree for "Environment" and "Transport",
     256                 :            :        * and toggling "Environment" will toggle BOTH layer1 and layer2.
     257                 :            :        *
     258                 :            :        * Layers which are not included in this group will always have their own individual layer tree entry
     259                 :            :        * created for them automatically.
     260                 :            :        */
     261                 :            :       QMap< QString, QString > customLayerTreeGroups;
     262                 :            : 
     263                 :            :       /**
     264                 :            :        * Optional map of map layer ID to custom layer tree name to show in the created PDF file.
     265                 :            :        *
     266                 :            :        * \since QGIS 3.14
     267                 :            :        */
     268                 :            :       QMap< QString, QString > layerIdToPdfLayerTreeNameMap;
     269                 :            : 
     270                 :            :       /**
     271                 :            :        * Optional map of map layer ID to initial visibility state. If a layer ID is not present in this,
     272                 :            :        * it will default to being initially visible when opening the PDF.
     273                 :            :        *
     274                 :            :        * \since QGIS 3.14
     275                 :            :        */
     276                 :            :       QMap< QString, bool > initialLayerVisibility;
     277                 :            : 
     278                 :            :       /**
     279                 :            :        * Optional list of layer IDs, in the order desired to appear in the generated GeoPDF file.
     280                 :            :        *
     281                 :            :        * Layers appearing earlier in the list will show earlier in the GeoPDF layer tree list.
     282                 :            :        *
     283                 :            :        * \since QGIS 3.14
     284                 :            :        */
     285                 :            :       QStringList layerOrder;
     286                 :            : 
     287                 :            :     };
     288                 :            : 
     289                 :            :     /**
     290                 :            :      * To be called after the rendering operation is complete.
     291                 :            :      *
     292                 :            :      * Will export the list of PDF layer \a components to a new PDF file at \a destinationFile. The \a components
     293                 :            :      * argument gives a list of additional layers to include in the generated PDF file. These must have already
     294                 :            :      * been created, e.g. as a result of rendering layers to separate PDF source files.
     295                 :            :      *
     296                 :            :      * Any features previously collected by calls to pushRenderedFeature() will be included automatically in the GeoPDF
     297                 :            :      * export.
     298                 :            :      *
     299                 :            :      * Returns TRUE if the operation was successful, or FALSE if an error occurred. If an error occurred, it
     300                 :            :      * can be retrieved by calling errorMessage().
     301                 :            :      */
     302                 :            :     bool finalize( const QList< QgsAbstractGeoPdfExporter::ComponentLayerDetail > &components, const QString &destinationFile, const ExportDetails &details );
     303                 :            : 
     304                 :            :     /**
     305                 :            :      * Returns the last error message encountered during the export.
     306                 :            :      */
     307                 :            :     QString errorMessage() { return mErrorMessage; }
     308                 :            : 
     309                 :            :     /**
     310                 :            :      * Returns a file path to use for temporary files required for GeoPDF creation.
     311                 :            :      */
     312                 :            :     QString generateTemporaryFilepath( const QString &filename ) const;
     313                 :            : 
     314                 :            :     /**
     315                 :            :      * Returns TRUE if the specified composition \a mode is supported for layers
     316                 :            :      * during GeoPDF exports.
     317                 :            :      *
     318                 :            :      * \since QGIS 3.14
     319                 :            :      */
     320                 :            :     static bool compositionModeSupported( QPainter::CompositionMode mode );
     321                 :            : 
     322                 :            :   protected:
     323                 :            : 
     324                 :            :     /**
     325                 :            :      * Contains information relating to a single PDF layer in the GeoPDF export.
     326                 :            :      */
     327                 :          0 :     struct VectorComponentDetail
     328                 :            :     {
     329                 :            :       //! User-friendly name for the generated PDF layer
     330                 :            :       QString name;
     331                 :            : 
     332                 :            :       //! Associated map layer ID
     333                 :            :       QString mapLayerId;
     334                 :            : 
     335                 :            :       //! Optional layer group name
     336                 :            :       QString group;
     337                 :            : 
     338                 :            :       //! Field name for display
     339                 :            :       QString displayAttribute;
     340                 :            : 
     341                 :            :       //! File path to the (already created) vector dataset to use as the source for this component layer
     342                 :            :       QString sourceVectorPath;
     343                 :            : 
     344                 :            :       //! Layer name in vector dataset to use as the source
     345                 :            :       QString sourceVectorLayer;
     346                 :            : 
     347                 :            :     };
     348                 :            : 
     349                 :            :   private:
     350                 :            : 
     351                 :            :     QMutex mMutex;
     352                 :            :     QMap< QString, QMap< QString, QgsFeatureList > > mCollatedFeatures;
     353                 :            : 
     354                 :            :     /**
     355                 :            :      * Returns the PDF output component details for the layer with given \a layerId.
     356                 :            :      */
     357                 :            :     virtual VectorComponentDetail componentDetailForLayerId( const QString &layerId ) = 0;
     358                 :            : 
     359                 :            :     QList< VectorComponentDetail > mVectorComponents;
     360                 :            : 
     361                 :            :     QString mErrorMessage;
     362                 :            :     QTemporaryDir mTemporaryDir;
     363                 :            : 
     364                 :            : 
     365                 :            :     bool saveTemporaryLayers();
     366                 :            : 
     367                 :            :     QString createCompositionXml( const QList< QgsAbstractGeoPdfExporter::ComponentLayerDetail > &components, const ExportDetails &details );
     368                 :            : 
     369                 :            :     /**
     370                 :            :      * Returns the GDAL string representation of the specified QPainter composition \a mode.
     371                 :            :      */
     372                 :            :     static QString compositionModeToString( QPainter::CompositionMode mode );
     373                 :            : 
     374                 :            :     friend class TestQgsLayoutGeoPdfExport;
     375                 :            :     friend class TestQgsGeoPdfExport;
     376                 :            : };
     377                 :            : 
     378                 :            : #endif //QGSABSTRACTGEOPDFEXPORTER_H
     379                 :            : 
     380                 :            : 
     381                 :            : 

Generated by: LCOV version 1.14