• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 15885686134

25 Jun 2025 07:44PM UTC coverage: 71.084%. Remained the same
15885686134

push

github

rouault
gdal_priv.h: fix C++11 compatibility

573814 of 807237 relevant lines covered (71.08%)

250621.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/frmts/postgisraster/postgisrastertilerasterband.cpp
1
/***********************************************************************
2
 * File :    postgisrastertilerasterband.cpp
3
 * Project:  PostGIS Raster driver
4
 * Purpose:  GDAL Tile RasterBand implementation for PostGIS Raster
5
 * driver
6
 * Author:   Jorge Arevalo, jorge.arevalo@deimos-space.com
7
 *                          jorgearevalo@libregis.org
8
 *
9
 ***********************************************************************
10
 * Copyright (c) 2009 - 2013, Jorge Arevalo
11
 * Copyright (c) 2013-2018, Even Rouault
12
 *
13
 * SPDX-License-Identifier: MIT
14
 **********************************************************************/
15
#include "postgisraster.h"
16
#include <memory>
17

18
/************************
19
 * \brief Constructor
20
 ************************/
21
PostGISRasterTileRasterBand::PostGISRasterTileRasterBand(
×
22
    PostGISRasterTileDataset *poRTDSIn, int nBandIn, GDALDataType eDataTypeIn)
×
23
    : poSource(nullptr)
×
24
{
25
    // Basic properties.
26
    poDS = poRTDSIn;
×
27
    nBand = nBandIn;
×
28

29
#if 0
30
    CPLDebug("PostGIS_Raster",
31
        "PostGISRasterTileRasterBand::Constructor: Raster tile dataset "
32
        "of dimensions %dx%d", poRTDS->GetRasterXSize(),
33
        poRTDS->GetRasterYSize());
34
#endif
35

36
    eDataType = eDataTypeIn;
×
37

38
    nRasterXSize = poRTDSIn->GetRasterXSize();
×
39
    nRasterYSize = poRTDSIn->GetRasterYSize();
×
40

41
    nBlockXSize = nRasterXSize;
×
42
    nBlockYSize = nRasterYSize;
×
43
}
×
44

45
/************************
46
 * \brief Destructor
47
 ************************/
48
PostGISRasterTileRasterBand::~PostGISRasterTileRasterBand()
×
49
{
50
}
×
51

52
/***********************************************************************
53
 * \brief Returns true if the (only) block is stored in the cache
54
 **********************************************************************/
55
GBool PostGISRasterTileRasterBand::IsCached()
×
56
{
57
    GDALRasterBlock *poBlock = TryGetLockedBlockRef(0, 0);
×
58
    if (poBlock != nullptr)
×
59
    {
60
        poBlock->DropLock();
×
61
        return true;
×
62
    }
63

64
    return false;
×
65
}
66

67
/*****************************************************
68
 * \brief Read a natural block of raster band data
69
 *****************************************************/
70
CPLErr PostGISRasterTileRasterBand::IReadBlock(int /*nBlockXOff*/,
×
71
                                               int /*nBlockYOff*/, void *pImage)
72
{
73
    CPLString osCommand;
×
74
    PGresult *poResult = nullptr;
×
75
    int nWKBLength = 0;
×
76

77
    const int nPixelSize = GDALGetDataTypeSizeBytes(eDataType);
×
78

79
    PostGISRasterTileDataset *poRTDS =
80
        cpl::down_cast<PostGISRasterTileDataset *>(poDS);
×
81

82
    const double dfTileUpperLeftX = poRTDS->m_gt[GEOTRSFRM_TOPLEFT_X];
×
83
    const double dfTileUpperLeftY = poRTDS->m_gt[GEOTRSFRM_TOPLEFT_Y];
×
84
    const double dfTileResX = poRTDS->m_gt[1];
×
85
    const double dfTileResY = poRTDS->m_gt[5];
×
86
    const int nTileXSize = nBlockXSize;
×
87
    const int nTileYSize = nBlockYSize;
×
88

89
    CPLString osSchemaI(CPLQuotedSQLIdentifier(poRTDS->poRDS->pszSchema));
×
90
    CPLString osTableI(CPLQuotedSQLIdentifier(poRTDS->poRDS->pszTable));
×
91
    CPLString osColumnI(CPLQuotedSQLIdentifier(poRTDS->poRDS->pszColumn));
×
92

93
    CPLString osRasterToFetch;
×
94
    osRasterToFetch.Printf("ST_Band(%s, %d)", osColumnI.c_str(), nBand);
×
95
    // We don't honour CLIENT_SIDE_IF_POSSIBLE since it would be likely too
96
    // costly in that context.
97
    if (poRTDS->poRDS->eOutDBResolution != OutDBResolution::CLIENT_SIDE)
×
98
    {
99
        osRasterToFetch =
100
            "encode(ST_AsBinary(" + osRasterToFetch + ",TRUE),'hex')";
×
101
    }
102

103
    osCommand.Printf("SELECT %s FROM %s.%s WHERE ", osRasterToFetch.c_str(),
104
                     osSchemaI.c_str(), osTableI.c_str());
×
105

106
    // Get by PKID
107
    if (poRTDS->poRDS->pszPrimaryKeyName)
×
108
    {
109
        CPLString osPrimaryKeyNameI(
110
            CPLQuotedSQLIdentifier(poRTDS->poRDS->pszPrimaryKeyName));
×
111
        osCommand +=
112
            CPLSPrintf("%s = '%s'", osPrimaryKeyNameI.c_str(), poRTDS->pszPKID);
×
113
    }
114

115
    // Get by upperleft
116
    else
117
    {
118
        osCommand += CPLSPrintf("abs(ST_UpperLeftX(%s) - %.8f) < 1e-8 and "
119
                                "abs(ST_UpperLeftY(%s) - %.8f) < 1e-8",
120
                                osColumnI.c_str(), dfTileUpperLeftX,
121
                                osColumnI.c_str(), dfTileUpperLeftY);
×
122
    }
123

124
    poResult = PQexec(poRTDS->poRDS->poConn, osCommand.c_str());
×
125

126
#ifdef DEBUG_QUERY
127
    CPLDebug("PostGIS_Raster",
128
             "PostGISRasterTileRasterBand::IReadBlock(): "
129
             "Query = \"%s\" --> number of rows = %d",
130
             osCommand.c_str(), poResult ? PQntuples(poResult) : 0);
131
#endif
132

133
    if (poResult == nullptr || PQresultStatus(poResult) != PGRES_TUPLES_OK ||
×
134
        PQntuples(poResult) <= 0)
×
135
    {
136

137
        CPLString osError;
×
138
        if (PQresultStatus(poResult) == PGRES_FATAL_ERROR)
×
139
        {
140
            const char *pszError = PQerrorMessage(poRTDS->poRDS->poConn);
×
141
            if (pszError)
×
142
                osError = pszError;
×
143
        }
144
        if (poResult)
×
145
            PQclear(poResult);
×
146

147
        ReportError(CE_Failure, CPLE_AppDefined,
×
148
                    "Error getting block of data (upperpixel = %f, %f): %s",
149
                    dfTileUpperLeftX, dfTileUpperLeftY, osError.c_str());
150

151
        return CE_Failure;
×
152
    }
153

154
    /* Copy only data size, without payload */
155
    int nExpectedDataSize = nBlockXSize * nBlockYSize * nPixelSize;
×
156

157
    struct CPLFreer
158
    {
159
        void operator()(GByte *x) const
×
160
        {
161
            CPLFree(x);
×
162
        }
×
163
    };
164

165
    std::unique_ptr<GByte, CPLFreer> pbyDataAutoFreed(
166
        CPLHexToBinary(PQgetvalue(poResult, 0, 0), &nWKBLength));
×
167
    GByte *pbyData = pbyDataAutoFreed.get();
×
168
    PQclear(poResult);
×
169

170
    const int nMinimumWKBLength = RASTER_HEADER_SIZE + BAND_SIZE(1, nPixelSize);
×
171
    if (nWKBLength < nMinimumWKBLength)
×
172
    {
173
        CPLDebug("PostGIS_Raster",
×
174
                 "nWKBLength=%d. too short. Expected at least %d", nWKBLength,
175
                 nMinimumWKBLength);
176
        return CE_Failure;
×
177
    }
178

179
    // Is it indb-raster ?
180
    if ((pbyData[RASTER_HEADER_SIZE] & 0x80) == 0)
×
181
    {
182
        int nExpectedWKBLength =
×
183
            RASTER_HEADER_SIZE + BAND_SIZE(nPixelSize, nExpectedDataSize);
×
184
        if (nWKBLength != nExpectedWKBLength)
×
185
        {
186
            CPLDebug("PostGIS_Raster", "nWKBLength=%d, nExpectedWKBLength=%d",
×
187
                     nWKBLength, nExpectedWKBLength);
188
            return CE_Failure;
×
189
        }
190

191
        GByte *pbyDataToRead =
×
192
            GET_BAND_DATA(pbyData, 1, nPixelSize, nExpectedDataSize);
×
193

194
        // Do byte-swapping if necessary */
195
        const bool bIsLittleEndian = (pbyData[0] == 1);
×
196
#ifdef CPL_LSB
197
        const bool bSwap = !bIsLittleEndian;
×
198
#else
199
        const bool bSwap = bIsLittleEndian;
200
#endif
201

202
        if (bSwap && nPixelSize > 1)
×
203
        {
204
            GDALSwapWords(pbyDataToRead, nPixelSize, nBlockXSize * nBlockYSize,
×
205
                          nPixelSize);
206
        }
207

208
        memcpy(pImage, pbyDataToRead, nExpectedDataSize);
×
209
    }
210
    else
211
    {
212
        int nCurOffset = RASTER_HEADER_SIZE;
×
213
        if (!poRTDS->poRDS->LoadOutdbRaster(
×
214
                nCurOffset, eDataType, nBand, pbyData, nWKBLength, pImage,
215
                dfTileUpperLeftX, dfTileUpperLeftY, dfTileResX, dfTileResY,
216
                nTileXSize, nTileYSize))
217
        {
218
            return CE_Failure;
×
219
        }
220
    }
221

222
    return CE_None;
×
223
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc