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-01-18 12:42:00 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             :     double adfGeoTransform[6];
     195             :     int nSrid;
     196             :     int nOverviewFactor;
     197             :     int nBandsToCreate;
     198             :     PGconn *poConn;
     199             :     GBool bRegularBlocking;
     200             :     GBool bAllTilesSnapToSameGrid;
     201             :     GBool bCheckAllTiles;
     202             :     char *pszSchema;
     203             :     char *pszTable;
     204             :     char *pszColumn;
     205             :     char *pszWhere;
     206             :     char *pszPrimaryKeyName;
     207             :     GBool bIsFastPK;
     208             :     int bHasTriedFetchingPrimaryKeyName;
     209             :     mutable OGRSpatialReference m_oSRS{};
     210             :     ResolutionStrategy resolutionStrategy;
     211             :     WorkingMode nMode;
     212             :     OutDBResolution eOutDBResolution{OutDBResolution::SERVER_SIDE};
     213             :     bool bHasStBandFileSize = false;
     214             :     int m_nTiles;
     215             :     double xmin;
     216             :     double ymin;
     217             :     double xmax;
     218             :     double ymax;
     219             :     PostGISRasterTileDataset **papoSourcesHolders;
     220             :     CPLQuadTree *hQuadTree;
     221             : 
     222             :     GBool bHasBuiltOverviews;
     223             :     int nOverviewCount;
     224             :     PostGISRasterDataset *poParentDS;
     225             :     PostGISRasterDataset **papoOverviewDS;
     226             : 
     227             :     std::map<CPLString, PostGISRasterTileDataset *> oMapPKIDToRTDS{};
     228             : 
     229             :     GBool bAssumeMultiBandReadPattern;
     230             :     int nNextExpectedBand;
     231             :     int nXOffPrev;
     232             :     int nYOffPrev;
     233             :     int nXSizePrev;
     234             :     int nYSizePrev;
     235             : 
     236             :     GBool bHasTriedHasSpatialIndex;
     237             :     GBool bHasSpatialIndex;
     238             : 
     239             :     GBool bBuildQuadTreeDynamically;
     240             : 
     241             :     GBool bTilesSameDimension;
     242             :     int nTileWidth;
     243             :     int nTileHeight;
     244             : 
     245             :     int m_nLastLoadSourcesXOff = 0;
     246             :     int m_nLastLoadSourcesYOff = 0;
     247             :     int m_nLastLoadSourcesXSize = 0;
     248             :     int m_nLastLoadSourcesYSize = 0;
     249             :     int m_nLastLoadSourcesBand = 0;
     250             : 
     251             :     lru11::Cache<std::string, std::shared_ptr<GDALDataset>> oOutDBDatasetCache{
     252             :         8, 0};
     253             :     lru11::Cache<std::string, bool> oOutDBFilenameUsable{100, 0};
     254             : 
     255             :     GBool ConstructOneDatasetFromTiles(PGresult *);
     256             :     GBool YieldSubdatasets(PGresult *, const char *);
     257             :     GBool SetRasterProperties(const char *);
     258             :     GBool BrowseDatabase(const char *, const char *);
     259             :     void AddComplexSource(PostGISRasterTileDataset *poRTDS);
     260             :     void GetDstWin(PostGISRasterTileDataset *, int *, int *, int *, int *);
     261             :     BandMetadata *GetBandsMetadata(int *);
     262             :     PROverview *GetOverviewTables(int *);
     263             : 
     264             :     PostGISRasterTileDataset *
     265             :     BuildRasterTileDataset(const char *pszMetadata, const char *pszPKID,
     266             :                            int nBandsFetched, BandMetadata *poBandMetaData);
     267             :     void UpdateGlobalResolutionWithTileResolution(double tilePixelSizeX,
     268             :                                                   double tilePixelSizeY);
     269             :     void BuildOverviews();
     270             :     void BuildBands(BandMetadata *poBandMetaData, int nBandsFetched);
     271             : 
     272           0 :     PostGISRasterTileDataset *GetMatchingSourceRef(const char *pszPKID)
     273             :     {
     274           0 :         return oMapPKIDToRTDS[pszPKID];
     275             :     }
     276             : 
     277             :     PostGISRasterTileDataset *GetMatchingSourceRef(double dfUpperLeftX,
     278             :                                                    double dfUpperLeftY);
     279             : 
     280             :     bool CanUseClientSideOutDB(bool bAllBandCaching, int nBand,
     281             :                                const CPLString &osWHERE);
     282             : 
     283             :     bool LoadOutdbRaster(int &nCurOffset, GDALDataType eDT, int nBand,
     284             :                          const GByte *pbyData, int nWKBLength, void *pImage,
     285             :                          double dfTileUpperLeftX, double dfTileUpperLeftY,
     286             :                          double dfTileResX, double dfTileResY, int nTileXSize,
     287             :                          int nTileYSize);
     288             : 
     289             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterDataset)
     290             : 
     291             :   protected:
     292             :     virtual int CloseDependentDatasets() override;
     293             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     294             : 
     295             :   public:
     296             :     PostGISRasterDataset();
     297             :     virtual ~PostGISRasterDataset();
     298             :     static GDALDataset *Open(GDALOpenInfo *);
     299             :     static GDALDataset *CreateCopy(const char *, GDALDataset *, int, char **,
     300             :                                    GDALProgressFunc, void *);
     301             :     static GBool InsertRaster(PGconn *, PostGISRasterDataset *, const char *,
     302             :                               const char *, const char *);
     303             :     static CPLErr Delete(const char *);
     304             :     virtual char **GetMetadataDomainList() override;
     305             :     char **GetMetadata(const char *) override;
     306             : 
     307             :     const OGRSpatialReference *GetSpatialRef() const override;
     308             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
     309             : 
     310             :     CPLErr SetGeoTransform(double *) override;
     311             :     CPLErr GetGeoTransform(double *) override;
     312             :     char **GetFileList() override;
     313             : 
     314             :     int GetOverviewCount();
     315             :     PostGISRasterDataset *GetOverviewDS(int iOvr);
     316             : 
     317             :     const char *GetPrimaryKeyRef();
     318             :     GBool HasSpatialIndex();
     319             :     GBool LoadSources(int nXOff, int nYOff, int nXSize, int nYSize, int nBand);
     320             :     GBool PolygonFromCoords(int nXOff, int nYOff, int nXEndOff, int nYEndOff,
     321             :                             double adfProjWin[8]);
     322             :     void CacheTile(const char *pszMetadata, const char *pszRaster,
     323             :                    const char *pszPKID, int nBand, bool bAllBandCaching);
     324             : };
     325             : 
     326             : /***********************************************************************
     327             :  * PostGISRasterRasterBand: extends VRTSourcedRasterBand to support
     328             :  * PostGIS Raster bands
     329             :  **********************************************************************/
     330             : class PostGISRasterTileRasterBand;
     331             : 
     332             : class PostGISRasterRasterBand final : public VRTSourcedRasterBand
     333             : {
     334             :     friend class PostGISRasterDataset;
     335             : 
     336             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterRasterBand)
     337             :   protected:
     338             :     const char *pszSchema;
     339             :     const char *pszTable;
     340             :     const char *pszColumn;
     341             : 
     342             :     void NullBuffer(void *pData, int nBufXSize, int nBufYSize,
     343             :                     GDALDataType eBufType, int nPixelSpace, int nLineSpace);
     344             : 
     345             :   public:
     346             :     PostGISRasterRasterBand(PostGISRasterDataset *poDSIn, int nBandIn,
     347             :                             GDALDataType eDataTypeIn, GBool bNoDataValueSetIn,
     348             :                             double dfNodata);
     349             : 
     350             :     virtual ~PostGISRasterRasterBand();
     351             : 
     352             :     virtual double GetNoDataValue(int *pbSuccess = nullptr) override;
     353             :     virtual CPLErr SetNoDataValue(double) override;
     354             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     355             :                              GDALDataType, GSpacing nPixelSpace,
     356             :                              GSpacing nLineSpace,
     357             :                              GDALRasterIOExtraArg *psExtraArg) override;
     358             : 
     359             :     virtual int GetOverviewCount() override;
     360             :     virtual GDALRasterBand *GetOverview(int) override;
     361             :     virtual GDALColorInterp GetColorInterpretation() override;
     362             : 
     363             :     virtual double GetMinimum(int *pbSuccess) override;
     364             :     virtual double GetMaximum(int *pbSuccess) override;
     365             :     virtual CPLErr ComputeRasterMinMax(int bApproxOK,
     366             :                                        double *adfMinMax) override;
     367             : };
     368             : 
     369             : /***********************************************************************
     370             :  * PostGISRasterTileDataset: it holds just a raster tile
     371             :  **********************************************************************/
     372             : class PostGISRasterTileRasterBand;
     373             : 
     374             : class PostGISRasterTileDataset final : public GDALDataset
     375             : {
     376             :     friend class PostGISRasterDataset;
     377             :     friend class PostGISRasterRasterBand;
     378             :     friend class PostGISRasterTileRasterBand;
     379             : 
     380             :   private:
     381             :     PostGISRasterDataset *poRDS;
     382             :     char *pszPKID;
     383             :     double adfGeoTransform[6];
     384             : 
     385             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterTileDataset)
     386             : 
     387             :   public:
     388             :     PostGISRasterTileDataset(PostGISRasterDataset *poRDS, int nXSize,
     389             :                              int nYSize);
     390             :     ~PostGISRasterTileDataset();
     391             :     CPLErr GetGeoTransform(double *) override;
     392             :     void GetExtent(double *pdfMinX, double *pdfMinY, double *pdfMaxX,
     393             :                    double *pdfMaxY) const;
     394             : 
     395           0 :     const char *GetPKID() const
     396             :     {
     397           0 :         return pszPKID;
     398             :     }
     399             : };
     400             : 
     401             : /***********************************************************************
     402             :  * PostGISRasterTileRasterBand: it holds a raster tile band, that will
     403             :  * be used as a source for PostGISRasterRasterBand
     404             :  **********************************************************************/
     405             : class PostGISRasterTileRasterBand final : public GDALRasterBand
     406             : {
     407             :     friend class PostGISRasterRasterBand;
     408             :     friend class PostGISRasterDataset;
     409             : 
     410             :   private:
     411             :     GBool IsCached();
     412             : 
     413             :     VRTSource *poSource;
     414             : 
     415             :     CPL_DISALLOW_COPY_ASSIGN(PostGISRasterTileRasterBand)
     416             : 
     417             :   public:
     418             :     PostGISRasterTileRasterBand(PostGISRasterTileDataset *poRTDS, int nBand,
     419             :                                 GDALDataType eDataType);
     420             :     virtual ~PostGISRasterTileRasterBand();
     421             :     virtual CPLErr IReadBlock(int, int, void *) override;
     422             : };
     423             : 
     424             : #endif  // POSTGISRASTER_H_INCLUDED

Generated by: LCOV version 1.14