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

Generated by: LCOV version 1.14