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

Generated by: LCOV version 1.14