• 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

99.17
/apps/gdalalg_raster_update.cpp
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  gdal "raster update" subcommand
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12

13
#include "gdalalg_raster_update.h"
14

15
#include "cpl_conv.h"
16

17
#include "gdal_priv.h"
18
#include "gdal_utils.h"
19
#include "gdalalg_raster_reproject.h"  // for GDALRasterReprojectUtils
20
#include "gdalalg_raster_overview_refresh.h"
21
#include "ogr_spatialref.h"
22

23
#include <algorithm>
24
#include <array>
25
#include <cmath>
26
#include <tuple>
27

28
//! @cond Doxygen_Suppress
29

30
#ifndef _
31
#define _(x) (x)
32
#endif
33

34
/************************************************************************/
35
/*        GDALRasterUpdateAlgorithm::GDALRasterUpdateAlgorithm()        */
36
/************************************************************************/
37

38
GDALRasterUpdateAlgorithm::GDALRasterUpdateAlgorithm()
12✔
39
    : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
12✔
40
{
41
    AddProgressArg();
12✔
42

43
    AddOpenOptionsArg(&m_openOptions);
12✔
44
    AddInputFormatsArg(&m_inputFormats)
12✔
45
        .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_RASTER});
24✔
46
    AddInputDatasetArg(&m_inputDataset, GDAL_OF_RASTER);
12✔
47

48
    AddOutputDatasetArg(&m_outputDataset, GDAL_OF_RASTER)
12✔
49
        .SetDatasetInputFlags(GADV_NAME | GADV_OBJECT);
12✔
50

51
    AddUpdateArg(&m_update).SetDefault(true).SetHidden();
12✔
52

53
    AddArg("geometry", 0, _("Clipping geometry (WKT or GeoJSON)"), &m_geometry)
24✔
54
        .SetMutualExclusionGroup("bbox-geometry-like");
12✔
55
    AddArg("geometry-crs", 0, _("CRS of clipping geometry"), &m_geometryCrs)
24✔
56
        .SetIsCRSArg()
24✔
57
        .AddHiddenAlias("geometry_srs");
12✔
58

59
    GDALRasterReprojectUtils::AddResamplingArg(this, m_resampling);
12✔
60

61
    GDALRasterReprojectUtils::AddWarpOptTransformOptErrorThresholdArg(
12✔
62
        this, m_warpOptions, m_transformOptions, m_errorThreshold);
12✔
63

64
    AddArg("no-update-overviews", 0, _("Do not update existing overviews"),
65
           &m_noUpdateOverviews);
12✔
66
}
12✔
67

68
/************************************************************************/
69
/*                GDALRasterUpdateAlgorithm::RunImpl()                  */
70
/************************************************************************/
71

72
bool GDALRasterUpdateAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
8✔
73
                                        void *pProgressData)
74
{
75
    auto poSrcDS = m_inputDataset.GetDatasetRef();
8✔
76
    CPLAssert(poSrcDS);
8✔
77

78
    auto poDstDS = m_outputDataset.GetDatasetRef();
8✔
79
    CPLAssert(poDstDS);
8✔
80
    CPLAssert(poDstDS->GetAccess() == GA_Update);
8✔
81

82
    std::unique_ptr<OGRGeometry> poClipGeom;
8✔
83
    std::string errMsg;
16✔
84
    if (!m_geometry.empty())
8✔
85
    {
86
        std::tie(poClipGeom, errMsg) = GetClipGeometry();
2✔
87
        if (!poClipGeom)
2✔
88
        {
89
            ReportError(CE_Failure, CPLE_AppDefined, "%s", errMsg.c_str());
1✔
90
            return false;
1✔
91
        }
92
    }
93

94
    auto poSrcDriver = poSrcDS->GetDriver();
7✔
95
    auto poDstDriver = poDstDS->GetDriver();
7✔
96
    if (poSrcDS == poDstDS ||
13✔
97
        (poSrcDriver && poDstDriver &&
6✔
98
         !EQUAL(poSrcDriver->GetDescription(), "MEM") &&
6✔
99
         !EQUAL(poDstDriver->GetDescription(), "MEM") &&
2✔
100
         strcmp(poSrcDS->GetDescription(), poDstDS->GetDescription()) == 0))
2✔
101
    {
102
        ReportError(CE_Failure, CPLE_NotSupported,
2✔
103
                    "Source and destination datasets must be different");
104
        return false;
2✔
105
    }
106

107
    CPLStringList aosOptions;
10✔
108
    if (!m_resampling.empty())
5✔
109
    {
110
        aosOptions.AddString("-r");
5✔
111
        aosOptions.AddString(m_resampling.c_str());
5✔
112
    }
113
    for (const std::string &opt : m_warpOptions)
6✔
114
    {
115
        aosOptions.AddString("-wo");
1✔
116
        aosOptions.AddString(opt.c_str());
1✔
117
    }
118
    for (const std::string &opt : m_transformOptions)
6✔
119
    {
120
        aosOptions.AddString("-to");
1✔
121
        aosOptions.AddString(opt.c_str());
1✔
122
    }
123
    if (std::isfinite(m_errorThreshold))
5✔
124
    {
125
        aosOptions.AddString("-et");
1✔
126
        aosOptions.AddString(CPLSPrintf("%.17g", m_errorThreshold));
1✔
127
    }
128

129
    if (poClipGeom)
5✔
130
    {
131
        aosOptions.AddString("-cutline");
1✔
132
        aosOptions.AddString(poClipGeom->exportToWkt());
1✔
133
    }
134

135
    bool bOvrCanBeUpdated = false;
5✔
136
    std::vector<double> overviewRefreshBBox;
5✔
137
    if (poDstDS->GetRasterBand(1)->GetOverviewCount() > 0 &&
7✔
138
        !m_noUpdateOverviews)
2✔
139
    {
140
        GDALGeoTransform gt;
2✔
141
        const auto poSrcCRS = poSrcDS->GetSpatialRef();
2✔
142
        const auto poDstCRS = poDstDS->GetSpatialRef();
2✔
143
        const bool bBothCRS = poSrcCRS && poDstCRS;
2✔
144
        const bool bBothNoCRS = !poSrcCRS && !poDstCRS;
2✔
145
        if ((bBothCRS || bBothNoCRS) && poSrcDS->GetGeoTransform(gt) == CE_None)
2✔
146
        {
147
            auto poCT = std::unique_ptr<OGRCoordinateTransformation>(
148
                bBothCRS ? OGRCreateCoordinateTransformation(poSrcCRS, poDstCRS)
1✔
149
                         : nullptr);
5✔
150
            if (bBothNoCRS || poCT)
2✔
151
            {
152
                const double dfTLX = gt[0];
2✔
153
                const double dfTLY = gt[3];
2✔
154

155
                double dfTRX = 0;
2✔
156
                double dfTRY = 0;
2✔
157
                gt.Apply(poSrcDS->GetRasterXSize(), 0, &dfTRX, &dfTRY);
2✔
158

159
                double dfBLX = 0;
2✔
160
                double dfBLY = 0;
2✔
161
                gt.Apply(0, poSrcDS->GetRasterYSize(), &dfBLX, &dfBLY);
2✔
162

163
                double dfBRX = 0;
2✔
164
                double dfBRY = 0;
2✔
165
                gt.Apply(poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize(),
2✔
166
                         &dfBRX, &dfBRY);
167

168
                const double dfXMin =
169
                    std::min(std::min(dfTLX, dfTRX), std::min(dfBLX, dfBRX));
2✔
170
                const double dfYMin =
171
                    std::min(std::min(dfTLY, dfTRY), std::min(dfBLY, dfBRY));
2✔
172
                const double dfXMax =
173
                    std::max(std::max(dfTLX, dfTRX), std::max(dfBLX, dfBRX));
2✔
174
                const double dfYMax =
175
                    std::max(std::max(dfTLY, dfTRY), std::max(dfBLY, dfBRY));
2✔
176
                double dfOutXMin = dfXMin;
2✔
177
                double dfOutYMin = dfYMin;
2✔
178
                double dfOutXMax = dfXMax;
2✔
179
                double dfOutYMax = dfYMax;
2✔
180
                if (!poCT || poCT->TransformBounds(
3✔
181
                                 dfXMin, dfYMin, dfXMax, dfYMax, &dfOutXMin,
182
                                 &dfOutYMin, &dfOutXMax, &dfOutYMax, 21))
1✔
183
                {
184
                    bOvrCanBeUpdated = true;
2✔
185
                    CPLDebug("update",
2✔
186
                             "Refresh overviews from (%f,%f) to (%f,%f)",
187
                             dfOutXMin, dfOutYMin, dfOutXMax, dfOutYMax);
188
                    overviewRefreshBBox = std::vector<double>{
4✔
189
                        dfOutXMin, dfOutYMin, dfOutXMax, dfOutYMax};
2✔
190
                }
191
            }
192
        }
193
        if (!bOvrCanBeUpdated)
2✔
194
        {
195
            ReportError(CE_Warning, CPLE_AppDefined,
×
196
                        "Overviews can not be updated");
197
        }
198
    }
199

200
    bool bOK = false;
5✔
201
    GDALWarpAppOptions *psOptions =
202
        GDALWarpAppOptionsNew(aosOptions.List(), nullptr);
5✔
203
    if (psOptions)
5✔
204
    {
205
        std::unique_ptr<void, decltype(&GDALDestroyScaledProgress)> pScaledData(
206
            nullptr, GDALDestroyScaledProgress);
10✔
207
        if (pfnProgress)
5✔
208
        {
209
            pScaledData.reset(
3✔
210
                GDALCreateScaledProgress(0.0, bOvrCanBeUpdated ? 0.75 : 1.0,
211
                                         pfnProgress, pProgressData));
212
            GDALWarpAppOptionsSetProgress(psOptions, GDALScaledProgress,
3✔
213
                                          pScaledData.get());
214
        }
215

216
        GDALDatasetH hSrcDS = GDALDataset::ToHandle(poSrcDS);
5✔
217
        GDALDatasetH hDstDS = GDALDataset::ToHandle(poDstDS);
5✔
218
        auto poRetDS = GDALDataset::FromHandle(
5✔
219
            GDALWarp(nullptr, hDstDS, 1, &hSrcDS, psOptions, nullptr));
220
        GDALWarpAppOptionsFree(psOptions);
5✔
221

222
        bOK = poRetDS != nullptr;
5✔
223
        if (bOK && bOvrCanBeUpdated)
5✔
224
        {
225
            GDALRasterOverviewAlgorithmRefresh refresh;
2✔
226
            refresh.GetArg("dataset")->Set(poRetDS);
2✔
227
            if (!m_resampling.empty())
2✔
228
                refresh.GetArg("resampling")->Set(m_resampling);
2✔
229
            refresh.GetArg("bbox")->Set(overviewRefreshBBox);
2✔
230
            pScaledData.reset(GDALCreateScaledProgress(0.75, 1.0, pfnProgress,
2✔
231
                                                       pProgressData));
232
            bOK = refresh.Run(pScaledData ? GDALScaledProgress : nullptr,
2✔
233
                              pScaledData.get());
234
        }
235
        if (bOK && pfnProgress)
5✔
236
            pfnProgress(1.0, "", pProgressData);
3✔
237
    }
238

239
    return bOK;
5✔
240
}
241

242
//! @endcond
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