Skip to content

Commit dbecc33

Browse files
authored
Merge pull request #12140 from rouault/gdal_raster_index
Add "gdal raster index" and "gdal driver gti create" (port of gdaltindex)
2 parents ab5908a + c41b70f commit dbecc33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1932
-79
lines changed

.github/workflows/doc_checks.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ jobs:
4949
-DBUILD_TESTING=ON \
5050
-DDOXYGEN_FAIL_ON_WARNINGS=ON \
5151
-DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \
52-
-DOGR_BUILD_OPTIONAL_DRIVERS=OFF
52+
-DOGR_BUILD_OPTIONAL_DRIVERS=OFF \
53+
-DGDAL_ENABLE_DRIVER_GTI=ON
5354
cmake --build . -j$(nproc)
5455
5556
- name: Print versions

apps/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ add_library(
2424
gdalalg_raster_edit.cpp
2525
gdalalg_raster_contour.cpp
2626
gdalalg_raster_hillshade.cpp
27+
gdalalg_raster_index.cpp
2728
gdalalg_raster_mosaic.cpp
2829
gdalalg_raster_pipeline.cpp
2930
gdalalg_raster_overview_add.cpp
@@ -64,6 +65,7 @@ add_library(
6465
gdalalg_vector_grid_invdistnn.cpp
6566
gdalalg_vector_grid_linear.cpp
6667
gdalalg_vector_grid_nearest.cpp
68+
gdalalg_vector_output_abstract.cpp
6769
gdalalg_vector_reproject.cpp
6870
gdalalg_vector_select.cpp
6971
gdalalg_vector_sql.cpp

apps/gdal_utils.h

+4
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ GDALTileIndexOptions CPL_DLL *
334334
GDALTileIndexOptionsNew(char **papszArgv,
335335
GDALTileIndexOptionsForBinary *psOptionsForBinary);
336336

337+
void CPL_DLL GDALTileIndexOptionsSetProgress(GDALTileIndexOptions *psOptions,
338+
GDALProgressFunc pfnProgress,
339+
void *pProgressData);
340+
337341
void CPL_DLL GDALTileIndexOptionsFree(GDALTileIndexOptions *psOptions);
338342

339343
GDALDatasetH CPL_DLL GDALTileIndex(const char *pszDest, int nSrcCount,

apps/gdal_utils_priv.h

+7
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,13 @@ std::string CPL_DLL GDALRasterizeAppGetParserUsage();
255255
std::string CPL_DLL
256256
GDALDEMAppGetParserUsage(const std::string &osProcessingMode);
257257

258+
GDALDatasetH GDALTileIndexInternal(const char *pszDest,
259+
GDALDatasetH hTileIndexDS, OGRLayerH hLayer,
260+
int nSrcCount,
261+
const char *const *papszSrcDSNames,
262+
const GDALTileIndexOptions *psOptionsIn,
263+
int *pbUsageError);
264+
258265
#endif /* #ifndef DOXYGEN_SKIP */
259266

260267
#endif /* GDAL_UTILS_PRIV_H_INCLUDED */

apps/gdalalg_raster.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "gdalalg_raster_edit.h"
2323
#include "gdalalg_raster_contour.h"
2424
#include "gdalalg_raster_hillshade.h"
25+
#include "gdalalg_raster_index.h"
2526
#include "gdalalg_raster_mosaic.h"
2627
#include "gdalalg_raster_overview.h"
2728
#include "gdalalg_raster_pipeline.h"
@@ -58,6 +59,7 @@ class GDALRasterAlgorithm final : public GDALAlgorithm
5859
RegisterSubAlgorithm<GDALRasterClipAlgorithmStandalone>();
5960
RegisterSubAlgorithm<GDALRasterEditAlgorithmStandalone>();
6061
RegisterSubAlgorithm<GDALRasterHillshadeAlgorithmStandalone>();
62+
RegisterSubAlgorithm<GDALRasterIndexAlgorithm>();
6163
RegisterSubAlgorithm<GDALRasterOverviewAlgorithm>();
6264
RegisterSubAlgorithm<GDALRasterPipelineAlgorithm>();
6365
RegisterSubAlgorithm<GDALRasterReprojectAlgorithmStandalone>();

apps/gdalalg_raster_index.cpp

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/******************************************************************************
2+
*
3+
* Project: GDAL
4+
* Purpose: gdal "raster index" 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_index.h"
14+
15+
#include "cpl_conv.h"
16+
#include "gdal_priv.h"
17+
#include "gdal_utils_priv.h"
18+
#include "ogrsf_frmts.h"
19+
20+
//! @cond Doxygen_Suppress
21+
22+
#ifndef _
23+
#define _(x) (x)
24+
#endif
25+
26+
/************************************************************************/
27+
/* GDALRasterIndexAlgorithm::GDALRasterIndexAlgorithm() */
28+
/************************************************************************/
29+
30+
GDALRasterIndexAlgorithm::GDALRasterIndexAlgorithm()
31+
: GDALVectorOutputAbstractAlgorithm(NAME, DESCRIPTION, HELP_URL)
32+
{
33+
AddProgressArg();
34+
AddInputDatasetArg(&m_inputDatasets, GDAL_OF_RASTER)
35+
.SetAutoOpenDataset(false);
36+
GDALVectorOutputAbstractAlgorithm::AddAllOutputArgs();
37+
38+
AddCommonOptions();
39+
40+
AddArg("source-crs-field-name", 0,
41+
_("Name of the field to store the CRS of each dataset"),
42+
&m_sourceCrsName)
43+
.SetMinCharCount(1);
44+
AddArg("source-crs-format", 0,
45+
_("Format in which the CRS of each dataset must be written"),
46+
&m_sourceCrsFormat)
47+
.SetMinCharCount(1)
48+
.SetDefault(m_sourceCrsFormat)
49+
.SetChoices("auto", "WKT", "EPSG", "PROJ");
50+
}
51+
52+
/************************************************************************/
53+
/* GDALRasterIndexAlgorithm::GDALRasterIndexAlgorithm() */
54+
/************************************************************************/
55+
56+
GDALRasterIndexAlgorithm::GDALRasterIndexAlgorithm(
57+
const std::string &name, const std::string &description,
58+
const std::string &helpURL)
59+
: GDALVectorOutputAbstractAlgorithm(name, description, helpURL)
60+
{
61+
}
62+
63+
/************************************************************************/
64+
/* GDALRasterIndexAlgorithm::AddCommonOptions() */
65+
/************************************************************************/
66+
67+
void GDALRasterIndexAlgorithm::AddCommonOptions()
68+
{
69+
AddArg("recursive", 0,
70+
_("Whether input directories should be explored recursively."),
71+
&m_recursive);
72+
AddArg("filename-filter", 0,
73+
_("Pattern that the filenames in input directories should follow "
74+
"('*' and '?' wildcard)"),
75+
&m_filenameFilter);
76+
AddArg("min-pixel-size", 0,
77+
_("Minimum pixel size in term of geospatial extent per pixel "
78+
"(resolution) that a raster should have to be selected."),
79+
&m_minPixelSize)
80+
.SetMinValueExcluded(0);
81+
AddArg("max-pixel-size", 0,
82+
_("Maximum pixel size in term of geospatial extent per pixel "
83+
"(resolution) that a raster should have to be selected."),
84+
&m_maxPixelSize)
85+
.SetMinValueExcluded(0);
86+
AddArg("location-name", 0, _("Name of the field with the raster path"),
87+
&m_locationName)
88+
.SetDefault(m_locationName)
89+
.SetMinCharCount(1);
90+
AddArg("absolute-path", 0,
91+
_("Whether the path to the input datasets should be stored as an "
92+
"absolute path"),
93+
&m_writeAbsolutePaths);
94+
AddArg("dst-crs", 0, _("Destination CRS"), &m_crs)
95+
.SetIsCRSArg()
96+
.AddHiddenAlias("t_srs");
97+
98+
{
99+
auto &arg =
100+
AddArg("metadata", 0, _("Add dataset metadata item"), &m_metadata)
101+
.SetMetaVar("<KEY>=<VALUE>");
102+
arg.AddValidationAction([this, &arg]()
103+
{ return ValidateKeyValue(arg); });
104+
arg.AddHiddenAlias("mo");
105+
}
106+
}
107+
108+
/************************************************************************/
109+
/* GDALRasterIndexAlgorithm::RunImpl() */
110+
/************************************************************************/
111+
112+
bool GDALRasterIndexAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
113+
void *pProgressData)
114+
{
115+
CPLStringList aosSources;
116+
for (auto &srcDS : m_inputDatasets)
117+
{
118+
if (srcDS.GetDatasetRef())
119+
{
120+
ReportError(
121+
CE_Failure, CPLE_IllegalArg,
122+
"Input datasets must be provided by name, not as object");
123+
return false;
124+
}
125+
aosSources.push_back(srcDS.GetName());
126+
}
127+
128+
auto setupRet = SetupOutputDataset();
129+
if (!setupRet.outDS)
130+
return false;
131+
132+
if (!SetDefaultOutputLayerNameIfNeeded(setupRet.outDS))
133+
return false;
134+
135+
CPLStringList aosOptions;
136+
if (m_recursive)
137+
{
138+
aosOptions.push_back("-recursive");
139+
}
140+
for (const std::string &s : m_filenameFilter)
141+
{
142+
aosOptions.push_back("-filename_filter");
143+
aosOptions.push_back(s);
144+
}
145+
if (m_minPixelSize > 0)
146+
{
147+
aosOptions.push_back("-min_pixel_size");
148+
aosOptions.push_back(CPLSPrintf("%.17g", m_minPixelSize));
149+
}
150+
if (m_maxPixelSize > 0)
151+
{
152+
aosOptions.push_back("-max_pixel_size");
153+
aosOptions.push_back(CPLSPrintf("%.17g", m_maxPixelSize));
154+
}
155+
156+
if (!m_outputLayerName.empty())
157+
{
158+
aosOptions.push_back("-lyr_name");
159+
aosOptions.push_back(m_outputLayerName);
160+
}
161+
162+
aosOptions.push_back("-tileindex");
163+
aosOptions.push_back(m_locationName);
164+
165+
if (m_writeAbsolutePaths)
166+
{
167+
aosOptions.push_back("-write_absolute_path");
168+
}
169+
if (m_crs.empty())
170+
{
171+
if (m_sourceCrsName.empty())
172+
aosOptions.push_back("-skip_different_projection");
173+
}
174+
else
175+
{
176+
aosOptions.push_back("-t_srs");
177+
aosOptions.push_back(m_crs);
178+
}
179+
if (!m_sourceCrsName.empty())
180+
{
181+
aosOptions.push_back("-src_srs_name");
182+
aosOptions.push_back(m_sourceCrsName);
183+
184+
aosOptions.push_back("-src_srs_format");
185+
aosOptions.push_back(CPLString(m_sourceCrsFormat).toupper());
186+
}
187+
188+
for (const std::string &s : m_metadata)
189+
{
190+
aosOptions.push_back("-mo");
191+
aosOptions.push_back(s);
192+
}
193+
194+
if (!AddExtraOptions(aosOptions))
195+
return false;
196+
197+
std::unique_ptr<GDALTileIndexOptions, decltype(&GDALTileIndexOptionsFree)>
198+
options(GDALTileIndexOptionsNew(aosOptions.List(), nullptr),
199+
GDALTileIndexOptionsFree);
200+
201+
if (options)
202+
{
203+
GDALTileIndexOptionsSetProgress(options.get(), pfnProgress,
204+
pProgressData);
205+
}
206+
207+
const bool ret =
208+
options && GDALTileIndexInternal(m_outputDataset.GetName().c_str(),
209+
GDALDataset::ToHandle(setupRet.outDS),
210+
OGRLayer::ToHandle(setupRet.layer),
211+
aosSources.size(), aosSources.List(),
212+
options.get(), nullptr) != nullptr;
213+
214+
if (ret && setupRet.newDS)
215+
{
216+
m_outputDataset.Set(std::move(setupRet.newDS));
217+
}
218+
219+
return ret;
220+
}
221+
222+
//! @endcond

apps/gdalalg_raster_index.h

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/******************************************************************************
2+
*
3+
* Project: GDAL
4+
* Purpose: gdal "raster index" 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+
#ifndef GDALALG_RASTER_INDEX_INCLUDED
14+
#define GDALALG_RASTER_INDEX_INCLUDED
15+
16+
#include "gdalalg_vector_output_abstract.h"
17+
18+
//! @cond Doxygen_Suppress
19+
20+
/************************************************************************/
21+
/* GDALRasterIndexAlgorithm */
22+
/************************************************************************/
23+
24+
class CPL_DLL GDALRasterIndexAlgorithm /* non final */
25+
: public GDALVectorOutputAbstractAlgorithm
26+
{
27+
public:
28+
static constexpr const char *NAME = "index";
29+
static constexpr const char *DESCRIPTION =
30+
"Create a vector index of raster datasets.";
31+
static constexpr const char *HELP_URL = "/programs/gdal_raster_index.html";
32+
33+
GDALRasterIndexAlgorithm();
34+
35+
GDALRasterIndexAlgorithm(const std::string &name,
36+
const std::string &description,
37+
const std::string &helpURL);
38+
39+
protected:
40+
void AddCommonOptions();
41+
42+
// Virtual method that may be overridden by derived classes to add options
43+
// to GDALTileIndex()
44+
virtual bool AddExtraOptions([[maybe_unused]] CPLStringList &aosOptions)
45+
{
46+
return true;
47+
}
48+
49+
std::vector<GDALArgDatasetValue> m_inputDatasets{};
50+
51+
private:
52+
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
53+
54+
bool m_recursive = false;
55+
std::vector<std::string> m_filenameFilter{};
56+
double m_minPixelSize = 0;
57+
double m_maxPixelSize = 0;
58+
std::string m_locationName = "location";
59+
bool m_writeAbsolutePaths = false;
60+
std::string m_crs{};
61+
std::string m_sourceCrsName{};
62+
std::string m_sourceCrsFormat = "auto";
63+
std::vector<std::string> m_metadata{};
64+
};
65+
66+
//! @endcond
67+
68+
#endif

0 commit comments

Comments
 (0)