LCOV - code coverage report
Current view: top level - frmts/postgisraster - postgisraster.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 4 0.0 %
Date: 2025-06-28 21:28:23 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /***********************************************************************
       2             :  * File :    postgisraster.h
       3             :  * Project:  PostGIS Raster driver
       4             :  * Purpose:  Main header file for PostGIS Raster Driver
       5             :  * Author:   Jorge Arevalo, jorge.arevalo@deimos-space.com
       6             :  *                          jorgearevalo@libregis.org
       7             :  *
       8             :  * Author:   David Zwarg, dzwarg@azavea.com
       9             :  *
      10             :  *
      11             :  ***********************************************************************
      12             :  * Copyright (c) 2009 - 2013, Jorge Arevalo, David Zwarg
      13             :  * Copyright (c) 2013, Even Rouault
      14             :  *
      15             :  * SPDX-License-Identifier: MIT
      16             :  **********************************************************************/
      17             : 
      18             : #ifndef POSTGISRASTER_H_INCLUDED
      19             : #define POSTGISRASTER_H_INCLUDED
      20             : 
      21             : #include "gdal_priv.h"
      22             : #include "libpq-fe.h"
      23             : #include "vrtdataset.h"
      24             : #include "cpl_mem_cache.h"
      25             : #include "cpl_quad_tree.h"
      26             : #include <float.h>
      27             : #include <map>
      28             : 
      29             : // #define DEBUG_VERBOSE
      30             : // #define DEBUG_QUERY
      31             : 
      32             : #if defined(DEBUG_VERBOSE) && !defined(DEBUG_QUERY)
      33             : #define DEBUG_QUERY
      34             : #endif
      35             : 
      36             : /**
      37             :  * The block size for the cache will be the minimum between the tile
      38             :  * size from sources and this value. So, please keep it at 2048 or
      39             :  * lower
      40             :  **/
      41             : #define MAX_BLOCK_SIZE 2048
      42             : 
      43             : #define NO_VALID_RES "-1234.56"
      44             : 
      45             : /**
      46             :  * To move over the data return by queries
      47             :  **/
      48             : #define POSTGIS_RASTER_VERSION static_cast<GUInt16>(0)
      49             : #define RASTER_HEADER_SIZE 61
      50             : #define RASTER_BAND_HEADER_FIXED_SIZE 1
      51             : 
      52             : #define BAND_SIZE(nodatasize, datasize)                                        \
      53             :     (RASTER_BAND_HEADER_FIXED_SIZE + (nodatasize) + (datasize))
      54             : 
      55             : #define GET_BAND_DATA(raster, nband, nodatasize, datasize)                     \
      56             :     ((raster) + RASTER_HEADER_SIZE + (nband)*BAND_SIZE(nodatasize, datasize) - \
      57             :      (datasize))
      58             : 
      59             : #define GEOTRSFRM_TOPLEFT_X 0
      60             : #define GEOTRSFRM_WE_RES 1
      61             : #define GEOTRSFRM_ROTATION_PARAM1 2
      62             : #define GEOTRSFRM_TOPLEFT_Y 3
      63             : #define GEOTRSFRM_ROTATION_PARAM2 4
      64             : #define GEOTRSFRM_NS_RES 5
      65             : 
      66             : // Number of results return by ST_Metadata PostGIS function
      67             : #define ELEMENTS_OF_METADATA_RECORD 10
      68             : 
      69             : // Positions of elements of ST_Metadata PostGIS function
      70             : #define POS_UPPERLEFTX 0
      71             : #define POS_UPPERLEFTY 1
      72             : #define POS_WIDTH 2
      73             : #define POS_HEIGHT 3
      74             : #define POS_SCALEX 4
      75             : #define POS_SCALEY 5
      76             : #define POS_SKEWX 6
      77             : #define POS_SKEWY 7
      78             : #define POS_SRID 8
      79             : #define POS_NBANDS 9
      80             : 
      81             : // Number of results return by ST_BandMetadata PostGIS function
      82             : #define ELEMENTS_OF_BAND_METADATA_RECORD 4
      83             : 
      84             : // Positions of elements of ST_BandMetadata PostGIS function
      85             : #define POS_PIXELTYPE 0
      86             : #define POS_NODATAVALUE 1
      87             : #define POS_ISOUTDB 2
      88             : #define POS_PATH 3
      89             : 
      90             : /**
      91             :  * The driver can work in these modes:
      92             :  * - NO_MODE: Error case
      93             :  * - ONE_RASTER_PER_ROW: Each row of the requested table is considered
      94             :  *              as a separated raster object. This is the default mode, if
      95             :  *              database and table name are provided, and no mode is specified.
      96             :  * - ONE_RASTER_PER_TABLE: All the rows of the requested table are
      97             :  *              considered as tiles of a bigger raster coverage (the whole
      98             :  *              table). If database and table name are specified and mode = 2
      99             :  *              is present in the connection string, this is the selected mode.
     100             :  * - BROWSE_SCHEMA: If no table name is specified, just database and
     101             :  *              schema names, the driver will yell of the schema's raster tables
     102             :  *              as possible datasets.
     103             :  * - BROWSE_DATABASE: If no table name is specified, just database name,
     104             :  *              the driver will yell of the database's raster tables as possible
     105             :  *              datasets.
     106             :  **/
     107             : typedef enum
     108             : {
     109             :     NO_MODE,
     110             :     ONE_RASTER_PER_ROW,
     111             :     ONE_RASTER_PER_TABLE,
     112             :     BROWSE_SCHEMA,
     113             :     BROWSE_DATABASE
     114             : } WorkingMode;
     115             : 
     116             : enum class OutDBResolution
     117             : {
     118             :     SERVER_SIDE,
     119             :     CLIENT_SIDE,
     120             :     CLIENT_SIDE_IF_POSSIBLE
     121             : };
     122             : 
     123             : /**
     124             :  * Important metadata of a PostGIS Raster band
     125             :  **/
     126             : typedef struct
     127             : {
     128             :     GDALDataType eDataType;
     129             :     int nBitsDepth;
     130             :     GBool bHasNoDataValue;
     131             :     GBool bIsOffline;
     132             :     char *path;
     133             :     double dfNoDataValue;
     134             : } BandMetadata;
     135             : 
     136             : typedef struct
     137             : {
     138             :     char *pszSchema;
     139             :     char *pszTable;
     140             :     char *pszColumn;
     141             :     int nFactor;
     142             : } PROverview;
     143             : 
     144             : // Some tools definitions
     145             : char *ReplaceQuotes(const char *, int);
     146             : GBool TranslateDataType(const char *, GDALDataType *, int *);
     147             : 
     148             : class PostGISRasterRasterBand;
     149             : class PostGISRasterTileDataset;
     150             : 
     151             : /***********************************************************************
     152             :  * PostGISRasterDriver: extends GDALDriver to support PostGIS Raster
     153             :  * connect.
     154             :  **********************************************************************/
     155             : class PostGISRasterDriver final : public GDALDriver
     156             : {
     157             : 
     158             :   private:
     159             :     CPLMutex *hMutex = nullptr;
     160             :     std::map<CPLString, PGconn *> oMapConnection{};
     161             : 
     162             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterDriver)
     163             :   public:
     164             :     PostGISRasterDriver();
     165             :     virtual ~PostGISRasterDriver();
     166             :     PGconn *GetConnection(const char *pszConnectionString,
     167             :                           const char *pszServiceIn, const char *pszDbnameIn,
     168             :                           const char *pszHostIn, const char *pszPortIn,
     169             :                           const char *pszUserIn);
     170             : 
     171             :     static PostGISRasterDriver *gpoPostGISRasterDriver;
     172             : };
     173             : 
     174             : /***********************************************************************
     175             :  * PostGISRasterDataset: extends VRTDataset to support PostGIS Raster
     176             :  * datasets
     177             :  **********************************************************************/
     178             : class PostGISRasterDataset final : public VRTDataset
     179             : {
     180             :     friend class PostGISRasterRasterBand;
     181             :     friend class PostGISRasterTileRasterBand;
     182             : 
     183             :   private:
     184             :     typedef enum
     185             :     {
     186             :         LOWEST_RESOLUTION,
     187             :         HIGHEST_RESOLUTION,
     188             :         AVERAGE_RESOLUTION,
     189             :         USER_RESOLUTION,
     190             :         AVERAGE_APPROX_RESOLUTION
     191             :     } ResolutionStrategy;
     192             : 
     193             :     char **papszSubdatasets;
     194             :     int nSrid;
     195             :     int nOverviewFactor;
     196             :     int nBandsToCreate;
     197             :     PGconn *poConn;
     198             :     GBool bRegularBlocking;
     199             :     GBool bAllTilesSnapToSameGrid;
     200             :     GBool bCheckAllTiles;
     201             :     char *pszSchema;
     202             :     char *pszTable;
     203             :     char *pszColumn;
     204             :     char *pszWhere;
     205             :     char *pszPrimaryKeyName;
     206             :     GBool bIsFastPK;
     207             :     int bHasTriedFetchingPrimaryKeyName;
     208             :     mutable OGRSpatialReference m_oSRS{};
     209             :     ResolutionStrategy resolutionStrategy;
     210             :     WorkingMode nMode;
     211             :     OutDBResolution eOutDBResolution{OutDBResolution::SERVER_SIDE};
     212             :     bool bHasStBandFileSize = false;
     213             :     int m_nTiles;
     214             :     double xmin;
     215             :     double ymin;
     216             :     double xmax;
     217             :     double ymax;
     218             :     PostGISRasterTileDataset **papoSourcesHolders;
     219             :     CPLQuadTree *hQuadTree;
     220             : 
     221             :     GBool bHasBuiltOverviews;
     222             :     int nOverviewCount;
     223             :     PostGISRasterDataset *poParentDS;
     224             :     PostGISRasterDataset **papoOverviewDS;
     225             : 
     226             :     std::map<CPLString, PostGISRasterTileDataset *> oMapPKIDToRTDS{};
     227             : 
     228             :     GBool bAssumeMultiBandReadPattern;
     229             :     int nNextExpectedBand;
     230             :     int nXOffPrev;
     231             :     int nYOffPrev;
     232             :     int nXSizePrev;
     233             :     int nYSizePrev;
     234             : 
     235             :     GBool bHasTriedHasSpatialIndex;
     236             :     GBool bHasSpatialIndex;
     237             : 
     238             :     GBool bBuildQuadTreeDynamically;
     239             : 
     240             :     GBool bTilesSameDimension;
     241             :     int nTileWidth;
     242             :     int nTileHeight;
     243             : 
     244             :     int m_nLastLoadSourcesXOff = 0;
     245             :     int m_nLastLoadSourcesYOff = 0;
     246             :     int m_nLastLoadSourcesXSize = 0;
     247             :     int m_nLastLoadSourcesYSize = 0;
     248             :     int m_nLastLoadSourcesBand = 0;
     249             : 
     250             :     lru11::Cache<std::string, std::shared_ptr<GDALDataset>> oOutDBDatasetCache{
     251             :         8, 0};
     252             :     lru11::Cache<std::string, bool> oOutDBFilenameUsable{100, 0};
     253             : 
     254             :     GBool ConstructOneDatasetFromTiles(PGresult *);
     255             :     GBool YieldSubdatasets(PGresult *, const char *);
     256             :     GBool SetRasterProperties(const char *);
     257             :     GBool BrowseDatabase(const char *, const char *);
     258             :     void AddComplexSource(PostGISRasterTileDataset *poRTDS);
     259             :     void GetDstWin(PostGISRasterTileDataset *, int *, int *, int *, int *);
     260             :     BandMetadata *GetBandsMetadata(int *);
     261             :     PROverview *GetOverviewTables(int *);
     262             : 
     263             :     PostGISRasterTileDataset *
     264             :     BuildRasterTileDataset(const char *pszMetadata, const char *pszPKID,
     265             :                            int nBandsFetched, BandMetadata *poBandMetaData);
     266             :     void UpdateGlobalResolutionWithTileResolution(double tilePixelSizeX,
     267             :                                                   double tilePixelSizeY);
     268             :     void BuildOverviews();
     269             :     void BuildBands(BandMetadata *poBandMetaData, int nBandsFetched);
     270             : 
     271           0 :     PostGISRasterTileDataset *GetMatchingSourceRef(const char *pszPKID)
     272             :     {
     273           0 :         return oMapPKIDToRTDS[pszPKID];
     274             :     }
     275             : 
     276             :     PostGISRasterTileDataset *GetMatchingSourceRef(double dfUpperLeftX,
     277             :                                                    double dfUpperLeftY);
     278             : 
     279             :     bool CanUseClientSideOutDB(bool bAllBandCaching, int nBand,
     280             :                                const CPLString &osWHERE);
     281             : 
     282             :     bool LoadOutdbRaster(int &nCurOffset, GDALDataType eDT, int nBand,
     283             :                          const GByte *pbyData, int nWKBLength, void *pImage,
     284             :                          double dfTileUpperLeftX, double dfTileUpperLeftY,
     285             :                          double dfTileResX, double dfTileResY, int nTileXSize,
     286             :                          int nTileYSize);
     287             : 
     288             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterDataset)
     289             : 
     290             :   protected:
     291             :     virtual int CloseDependentDatasets() override;
     292             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     293             : 
     294             :   public:
     295             :     PostGISRasterDataset();
     296             :     virtual ~PostGISRasterDataset();
     297             :     static GDALDataset *Open(GDALOpenInfo *);
     298             :     static GDALDataset *CreateCopy(const char *, GDALDataset *, int, char **,
     299             :                                    GDALProgressFunc, void *);
     300             :     static GBool InsertRaster(PGconn *, PostGISRasterDataset *, const char *,
     301             :                               const char *, const char *);
     302             :     static CPLErr Delete(const char *);
     303             :     virtual char **GetMetadataDomainList() override;
     304             :     char **GetMetadata(const char *) override;
     305             : 
     306             :     const OGRSpatialReference *GetSpatialRef() const override;
     307             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
     308             : 
     309             :     CPLErr SetGeoTransform(const GDALGeoTransform &gt) override;
     310             :     CPLErr GetGeoTransform(GDALGeoTransform &gt) const override;
     311             :     char **GetFileList() override;
     312             : 
     313             :     int GetOverviewCount();
     314             :     PostGISRasterDataset *GetOverviewDS(int iOvr);
     315             : 
     316             :     const char *GetPrimaryKeyRef();
     317             :     GBool HasSpatialIndex();
     318             :     GBool LoadSources(int nXOff, int nYOff, int nXSize, int nYSize, int nBand);
     319             :     GBool PolygonFromCoords(int nXOff, int nYOff, int nXEndOff, int nYEndOff,
     320             :                             double adfProjWin[8]);
     321             :     void CacheTile(const char *pszMetadata, const char *pszRaster,
     322             :                    const char *pszPKID, int nBand, bool bAllBandCaching);
     323             : };
     324             : 
     325             : /***********************************************************************
     326             :  * PostGISRasterRasterBand: extends VRTSourcedRasterBand to support
     327             :  * PostGIS Raster bands
     328             :  **********************************************************************/
     329             : class PostGISRasterTileRasterBand;
     330             : 
     331             : class PostGISRasterRasterBand final : public VRTSourcedRasterBand
     332             : {
     333             :     friend class PostGISRasterDataset;
     334             : 
     335             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterRasterBand)
     336             :   protected:
     337             :     const char *pszSchema;
     338             :     const char *pszTable;
     339             :     const char *pszColumn;
     340             : 
     341             :     void NullBuffer(void *pData, int nBufXSize, int nBufYSize,
     342             :                     GDALDataType eBufType, int nPixelSpace, int nLineSpace);
     343             : 
     344             :   public:
     345             :     PostGISRasterRasterBand(PostGISRasterDataset *poDSIn, int nBandIn,
     346             :                             GDALDataType eDataTypeIn, GBool bNoDataValueSetIn,
     347             :                             double dfNodata);
     348             : 
     349             :     virtual ~PostGISRasterRasterBand();
     350             : 
     351             :     virtual double GetNoDataValue(int *pbSuccess = nullptr) override;
     352             :     virtual CPLErr SetNoDataValue(double) override;
     353             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     354             :                              GDALDataType, GSpacing nPixelSpace,
     355             :                              GSpacing nLineSpace,
     356             :                              GDALRasterIOExtraArg *psExtraArg) override;
     357             : 
     358             :     virtual int GetOverviewCount() override;
     359             :     virtual GDALRasterBand *GetOverview(int) override;
     360             :     virtual GDALColorInterp GetColorInterpretation() override;
     361             : 
     362             :     virtual double GetMinimum(int *pbSuccess) override;
     363             :     virtual double GetMaximum(int *pbSuccess) override;
     364             :     virtual CPLErr ComputeRasterMinMax(int bApproxOK,
     365             :                                        double *adfMinMax) override;
     366             : };
     367             : 
     368             : /***********************************************************************
     369             :  * PostGISRasterTileDataset: it holds just a raster tile
     370             :  **********************************************************************/
     371             : class PostGISRasterTileRasterBand;
     372             : 
     373             : class PostGISRasterTileDataset final : public GDALDataset
     374             : {
     375             :     friend class PostGISRasterDataset;
     376             :     friend class PostGISRasterRasterBand;
     377             :     friend class PostGISRasterTileRasterBand;
     378             : 
     379             :   private:
     380             :     PostGISRasterDataset *poRDS;
     381             :     char *pszPKID;
     382             :     GDALGeoTransform m_gt{};
     383             : 
     384             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterTileDataset)
     385             : 
     386             :   public:
     387             :     PostGISRasterTileDataset(PostGISRasterDataset *poRDS, int nXSize,
     388             :                              int nYSize);
     389             :     ~PostGISRasterTileDataset();
     390             :     CPLErr GetGeoTransform(GDALGeoTransform &gt) const override;
     391             :     void GetNativeExtent(double *pdfMinX, double *pdfMinY, double *pdfMaxX,
     392             :                          double *pdfMaxY) const;
     393             : 
     394           0 :     const char *GetPKID() const
     395             :     {
     396           0 :         return pszPKID;
     397             :     }
     398             : };
     399             : 
     400             : /***********************************************************************
     401             :  * PostGISRasterTileRasterBand: it holds a raster tile band, that will
     402             :  * be used as a source for PostGISRasterRasterBand
     403             :  **********************************************************************/
     404             : class PostGISRasterTileRasterBand final : public GDALRasterBand
     405             : {
     406             :     friend class PostGISRasterRasterBand;
     407             :     friend class PostGISRasterDataset;
     408             : 
     409             :   private:
     410             :     GBool IsCached();
     411             : 
     412             :     VRTSource *poSource;
     413             : 
     414             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterTileRasterBand)
     415             : 
     416             :   public:
     417             :     PostGISRasterTileRasterBand(PostGISRasterTileDataset *poRTDS, int nBand,
     418             :                                 GDALDataType eDataType);
     419             :     virtual ~PostGISRasterTileRasterBand();
     420             :     virtual CPLErr IReadBlock(int, int, void *) override;
     421             : };
     422             : 
     423             : #endif  // POSTGISRASTER_H_INCLUDED

Generated by: LCOV version 1.14