Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'gdal raster overview add' and 'gdal raster overview delete' #11614

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ add_library(
gdalalg_raster_convert.cpp
gdalalg_raster_edit.cpp
gdalalg_raster_pipeline.cpp
gdalalg_raster_overview_add.cpp
gdalalg_raster_overview_delete.cpp
gdalalg_raster_read.cpp
gdalalg_raster_reproject.cpp
gdalalg_raster_write.cpp
Expand Down
2 changes: 2 additions & 0 deletions apps/gdalalg_raster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "gdalalg_raster_info.h"
#include "gdalalg_raster_convert.h"
#include "gdalalg_raster_edit.h"
#include "gdalalg_raster_overview.h"
#include "gdalalg_raster_pipeline.h"
#include "gdalalg_raster_reproject.h"

Expand All @@ -40,6 +41,7 @@ class GDALRasterAlgorithm final : public GDALAlgorithm
RegisterSubAlgorithm<GDALRasterInfoAlgorithm>();
RegisterSubAlgorithm<GDALRasterConvertAlgorithm>();
RegisterSubAlgorithm<GDALRasterEditAlgorithmStandalone>();
RegisterSubAlgorithm<GDALRasterOverviewAlgorithm>();
RegisterSubAlgorithm<GDALRasterPipelineAlgorithm>();
RegisterSubAlgorithm<GDALRasterReprojectAlgorithmStandalone>();
RegisterSubAlgorithm<GDALRasterBuildVRTAlgorithm>();
Expand Down
61 changes: 61 additions & 0 deletions apps/gdalalg_raster_overview.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/******************************************************************************
*
* Project: GDAL
* Purpose: gdal "raster overview" subcommand
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#ifndef GDALALG_RASTER_OVERVIEW_INCLUDED
#define GDALALG_RASTER_OVERVIEW_INCLUDED

#include "gdalalgorithm.h"

//! @cond Doxygen_Suppress

#include "gdalalgorithm.h"

#include "gdalalg_raster_overview_add.h"
#include "gdalalg_raster_overview_delete.h"

/************************************************************************/
/* GDALRasterOverviewAlgorithm */
/************************************************************************/

class GDALRasterOverviewAlgorithm final : public GDALAlgorithm
{
public:
static constexpr const char *NAME = "overview";
static constexpr const char *DESCRIPTION =
"Manage overviews of a raster dataset.";
static constexpr const char *HELP_URL =
"/programs/gdal_raster_overview.html";

static std::vector<std::string> GetAliases()
{
return {};
}

GDALRasterOverviewAlgorithm() : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
{
RegisterSubAlgorithm<GDALRasterOverviewAlgorithmAdd>();
RegisterSubAlgorithm<GDALRasterOverviewAlgorithmDelete>();
}

private:
bool RunImpl(GDALProgressFunc, void *) override
{
CPLError(CE_Failure, CPLE_AppDefined,
"The Run() method should not be called directly on the \"gdal "
"raster overview\" program.");
return false;
}
};

//! @endcond

#endif
157 changes: 157 additions & 0 deletions apps/gdalalg_raster_overview_add.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/******************************************************************************
*
* Project: GDAL
* Purpose: gdal "raster overview add" subcommand
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#include "gdalalg_raster_overview_add.h"

#include "cpl_string.h"
#include "gdal_priv.h"

//! @cond Doxygen_Suppress

#ifndef _
#define _(x) (x)
#endif

/************************************************************************/
/* GDALRasterOverviewAlgorithmAdd() */
/************************************************************************/

GDALRasterOverviewAlgorithmAdd::GDALRasterOverviewAlgorithmAdd()
: GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
{
AddProgressArg();
AddOpenOptionsArg(&m_openOptions);
AddArg("dataset", 0, _("Dataset (in-place updated, unless --read-only)"),
&m_dataset, GDAL_OF_RASTER | GDAL_OF_UPDATE)
.SetPositional()
.SetRequired();
AddArg(GDAL_ARG_NAME_READ_ONLY, 0, _("Open the dataset in read-only mode"),
&m_readOnly)
.AddHiddenAlias("ro");

AddArg("resampling", 'r', _("Resampling method"), &m_resampling)
.SetChoices("nearest", "average", "cubic", "cubicspline", "lanczos",
"bilinear", "gauss", "average_magphase", "rms", "mode")
.SetHiddenChoices("near");

auto &levelArg =
AddArg("levels", 0, _("Levels / decimation factors"), &m_levels);
levelArg.AddValidationAction(
[this, &levelArg]()
{
const auto &values = levelArg.Get<std::vector<int>>();
for (const auto &value : values)
{
if (value < 2)
{
ReportError(CE_Failure, CPLE_IllegalArg,
"Values of 'levels' argument should be "
"integers greater or equal to 2.");
return false;
}
}
return true;
});

auto &minSizeArg =
AddArg("min-size", 0,
_("Maximum width or height of the smallest overview level."),
&m_minSize);
minSizeArg.AddValidationAction(
[this, &minSizeArg]()
{
const int val = minSizeArg.Get<int>();
if (val <= 0)
{
ReportError(CE_Failure, CPLE_IllegalArg,
"Value of 'min-size' should be an integer greater "
"or equal to 1.");
return false;
}
return true;
});
}

/************************************************************************/
/* GDALRasterOverviewAlgorithmAdd::RunImpl() */
/************************************************************************/

bool GDALRasterOverviewAlgorithmAdd::RunImpl(GDALProgressFunc pfnProgress,
void *pProgressData)
{
auto poDS = m_dataset.GetDatasetRef();
CPLAssert(poDS);

std::string resampling = m_resampling;
if (resampling.empty() && poDS->GetRasterCount() > 0)
{
auto poBand = poDS->GetRasterBand(1);
if (poBand->GetOverviewCount() > 0)
{
const char *pszResampling =
poBand->GetOverview(0)->GetMetadataItem("RESAMPLING");
if (pszResampling)
{
resampling = pszResampling;
CPLDebug("GDAL",
"Reusing resampling method %s from existing "
"overview",
pszResampling);
}
}
}
if (resampling.empty())
resampling = "nearest";

std::vector<int> levels = m_levels;

// If no levels are specified, reuse the potentially existing ones.
if (levels.empty() && poDS->GetRasterCount() > 0)
{
auto poBand = poDS->GetRasterBand(1);
const int nExistingCount = poBand->GetOverviewCount();
if (nExistingCount > 0)
{
for (int iOvr = 0; iOvr < nExistingCount; ++iOvr)
{
auto poOverview = poBand->GetOverview(iOvr);
if (poOverview)
{
const int nOvFactor = GDALComputeOvFactor(
poOverview->GetXSize(), poBand->GetXSize(),
poOverview->GetYSize(), poBand->GetYSize());
levels.push_back(nOvFactor);
}
}
}
}

if (levels.empty())
{
const int nXSize = poDS->GetRasterXSize();
const int nYSize = poDS->GetRasterYSize();
int nOvrFactor = 1;
while (DIV_ROUND_UP(nXSize, nOvrFactor) > m_minSize ||
DIV_ROUND_UP(nYSize, nOvrFactor) > m_minSize)
{
nOvrFactor *= 2;
levels.push_back(nOvrFactor);
}
}

return levels.empty() ||
GDALBuildOverviews(GDALDataset::ToHandle(poDS), resampling.c_str(),
static_cast<int>(levels.size()), levels.data(), 0,
nullptr, pfnProgress, pProgressData) == CE_None;
}

//! @endcond
53 changes: 53 additions & 0 deletions apps/gdalalg_raster_overview_add.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/******************************************************************************
*
* Project: GDAL
* Purpose: gdal "raster overview add" subcommand
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#ifndef GDALALG_RASTER_OVERVIEW_ADD_INCLUDED
#define GDALALG_RASTER_OVERVIEW_ADD_INCLUDED

#include "gdalalgorithm.h"

//! @cond Doxygen_Suppress

/************************************************************************/
/* GDALRasterOverviewAlgorithmAdd */
/************************************************************************/

class GDALRasterOverviewAlgorithmAdd final : public GDALAlgorithm
{
public:
static constexpr const char *NAME = "add";
static constexpr const char *DESCRIPTION = "Adding overviews.";
static constexpr const char *HELP_URL =
"/programs/gdal_raster_overview_add.html";

static std::vector<std::string> GetAliases()
{
return {};
}

GDALRasterOverviewAlgorithmAdd();

private:
bool RunImpl(GDALProgressFunc, void *) override;

GDALArgDatasetValue m_dataset{};
std::vector<std::string> m_openOptions{};
std::vector<std::string> m_inputFormats{};
std::string m_resampling{};
std::vector<int> m_levels{};
int m_minSize = 256;
bool m_readOnly = false;
};

//! @endcond

#endif
56 changes: 56 additions & 0 deletions apps/gdalalg_raster_overview_delete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/******************************************************************************
*
* Project: GDAL
* Purpose: gdal "raster overview delete" subcommand
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#include "gdalalg_raster_overview_delete.h"

#include "gdal_priv.h"

//! @cond Doxygen_Suppress

#ifndef _
#define _(x) (x)
#endif

/************************************************************************/
/* GDALRasterOverviewAlgorithmDelete() */
/************************************************************************/

GDALRasterOverviewAlgorithmDelete::GDALRasterOverviewAlgorithmDelete()
: GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
{
AddProgressArg();
AddOpenOptionsArg(&m_openOptions);
AddArg("dataset", 0, _("Dataset (in-place updated, unless --read-only)"),
&m_dataset, GDAL_OF_RASTER | GDAL_OF_UPDATE)
.SetPositional()
.SetRequired();
AddArg(GDAL_ARG_NAME_READ_ONLY, 0, _("Open the dataset in read-only mode"),
&m_readOnly)
.AddHiddenAlias("ro");
}

/************************************************************************/
/* GDALRasterOverviewAlgorithmDelete::RunImpl() */
/************************************************************************/

bool GDALRasterOverviewAlgorithmDelete::RunImpl(GDALProgressFunc pfnProgress,
void *pProgressData)
{
auto poDS = m_dataset.GetDatasetRef();
CPLAssert(poDS);

return GDALBuildOverviews(GDALDataset::ToHandle(poDS), "NONE", 0, nullptr,
0, nullptr, pfnProgress,
pProgressData) == CE_None;
}

//! @endcond
Loading
Loading