Skip to content

Commit eeb55bb

Browse files
committed
Break out source descriptor parsing.
1 parent d0df507 commit eeb55bb

2 files changed

Lines changed: 43 additions & 24 deletions

File tree

apps/gdalalg_raster_calc.cpp

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,15 @@ SetBandIndicesFlattenedExpression(const std::string &origExpression,
189189
return expression;
190190
}
191191

192+
// Container for all properties of a dataset.
192193
struct SourceProperties
193194
{
194195
SourceProperties(const std::string &variable, const std::string &dsname)
195196
: variable(variable), dsname(dsname)
196197
{
197198
}
198199

200+
// Copy ctor needed for SRS.
199201
SourceProperties(const SourceProperties &other)
200202
{
201203
variable = other.variable;
@@ -224,6 +226,7 @@ struct SourceProperties
224226
GDALDataType eDT{GDT_Unknown};
225227
};
226228

229+
// Read a dataset, setting properties.
227230
bool SourceProperties::read()
228231
{
229232
std::unique_ptr<GDALDataset> ds(
@@ -243,9 +246,7 @@ bool SourceProperties::read()
243246
eDT = ds->GetRasterBand(1)->GetRasterDataType();
244247
for (int i = 2; i <= nBands; ++i)
245248
{
246-
GDALRasterBand *band = ds->GetRasterBand(i);
247-
248-
if (eDT != band->GetRasterDataType())
249+
if (eDT != ds->GetRasterBand(i)->GetRasterDataType())
249250
{
250251
eDT = GDT_Unknown;
251252
break;
@@ -254,10 +255,8 @@ bool SourceProperties::read()
254255

255256
for (int i = 1; i <= nBands; ++i)
256257
{
257-
GDALRasterBand *band = ds->GetRasterBand(i);
258-
259258
int success;
260-
double noDataVal = band->GetNoDataValue(&success);
259+
double noDataVal = ds->GetRasterBand(i)->GetNoDataValue(&success);
261260
if (success)
262261
noData[i - 1] = noDataVal;
263262
}
@@ -424,7 +423,7 @@ static bool CreateDerivedBandXML(
424423
"rasters with incompatible numbers of bands (source " +
425424
props.variable + " has " +
426425
std::to_string(props.nBands) +
427-
" bands but is expected to have 1 or " +
426+
" bands but expected to have 1 or " +
428427
std::to_string(nOutBands) + " bands)");
429428
}
430429

@@ -614,12 +613,37 @@ std::string parseInput(const std::string &input, std::string &variable,
614613
return "";
615614
}
616615

617-
bool ParseSourceDescriptors(const std::vector<std::string> &inputs,
618-
SourceList &datasets, bool requireSourceNames)
616+
bool ParseBuiltinSourceDescriptors(const std::vector<std::string> &inputs,
617+
SourceList &datasets)
619618
{
620-
int unnamedCount = 0;
621-
std::string unnamedDsn =
619+
const std::string unnamedDsn =
622620
"X"; // Not sure why we use X. Maybe it's already used?
621+
622+
for (size_t i = 0; i < inputs.size(); ++i)
623+
{
624+
const std::string &input = inputs[i];
625+
626+
std::string variable;
627+
std::string dsn;
628+
std::string err = parseInput(input, variable, dsn);
629+
if (err.size())
630+
return error(err);
631+
632+
// Ignore any parsed dataset name in builtin mode.
633+
variable = unnamedDsn + std::to_string(i);
634+
datasets.emplace_back(variable, dsn);
635+
}
636+
637+
return true;
638+
}
639+
640+
// Parse source input descriptors and create a list of SourceProperties
641+
bool ParseSourceDescriptors(const std::vector<std::string> &inputs,
642+
SourceList &datasets)
643+
{
644+
// Not sure why we use X. Maybe it's already used?
645+
const std::string unnamedDsn = "X";
646+
623647
for (const std::string &input : inputs)
624648
{
625649
std::string variable;
@@ -638,16 +662,12 @@ bool ParseSourceDescriptors(const std::vector<std::string> &inputs,
638662
// No varaible name was provided.
639663
if (variable == "_")
640664
{
641-
if (requireSourceNames && inputs.size() > 1)
665+
if (inputs.size() > 1)
642666
return error("Inputs must be named when more than one input is "
643667
"provided.");
644668

645669
variable = unnamedDsn;
646-
if (unnamedCount)
647-
variable += std::to_string(unnamedCount);
648-
unnamedCount++;
649670
}
650-
651671
datasets.emplace_back(variable, dsn);
652672
}
653673

@@ -716,13 +736,15 @@ static std::unique_ptr<GDALDataset> GDALCalcCreateVRTDerived(
716736
const std::string &fakeSourceFilename = std::string())
717737
{
718738
if (inputs.empty())
719-
{
720739
return nullptr;
721-
}
722740

723-
bool requireSourceNames = dialect != "builtin";
724741
SourceList sources;
725-
if (!ParseSourceDescriptors(inputs, sources, requireSourceNames))
742+
bool ok;
743+
if (dialect == "builtin")
744+
ok = ParseBuiltinSourceDescriptors(inputs, sources);
745+
else
746+
ok = ParseSourceDescriptors(inputs, sources);
747+
if (!ok)
726748
return nullptr;
727749

728750
maxSourceBands = 1;

autotest/utilities/test_gdalalg_raster_calc.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,10 +1002,7 @@ def test_gdalalg_raster_calc_sum_builtin_two_bands_three_bands_fail(calc, tmp_vs
10021002
calc["output-format"] = "MEM"
10031003
calc["calc"] = "sum"
10041004
calc["dialect"] = "builtin"
1005-
with pytest.raises(
1006-
Exception,
1007-
match=r"Expression cannot operate on all bands of rasters with incompatible numbers of bands \(source B has 3 bands but expected to have 1 or 2 bands\)",
1008-
):
1005+
with pytest.raises(Exception, match="Expression cannot operate on all bands.*"):
10091006
calc.Run()
10101007

10111008

0 commit comments

Comments
 (0)