Skip to content

Commit b4eda38

Browse files
committed
Make sure datasets are closed.
Handle SD and non-SD invocations.
1 parent bbd3b02 commit b4eda38

File tree

1 file changed

+102
-45
lines changed

1 file changed

+102
-45
lines changed

apps/gdal_viewshed.cpp

Lines changed: 102 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -259,48 +259,62 @@ void validateArgs(Options &localOpts, const GDALArgumentParser &argParser)
259259
}
260260

261261
} // unnamed namespace
262-
} // namespace gdal
263-
264-
/************************************************************************/
265-
/* main() */
266-
/************************************************************************/
267262

268-
MAIN_START(argc, argv)
263+
struct ScopedDataset
269264
{
270-
using namespace gdal;
265+
ScopedDataset() : m_ds(nullptr)
266+
{
267+
}
271268

272-
EarlySetConfigOptions(argc, argv);
269+
ScopedDataset(GDALDatasetH ds) : m_ds(ds)
270+
{
271+
}
273272

274-
GDALAllRegister();
273+
~ScopedDataset()
274+
{
275+
if (m_ds)
276+
GDALClose(m_ds);
277+
}
275278

276-
argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
277-
CPLStringList aosArgv;
278-
aosArgv.Assign(argv, /* bTakeOwnership= */ true);
279-
if (argc < 1)
280-
std::exit(-argc);
279+
ScopedDataset &operator=(GDALDatasetH ds)
280+
{
281+
if (m_ds)
282+
GDALClose(m_ds);
283+
m_ds = ds;
284+
return *this;
285+
}
281286

282-
GDALArgumentParser argParser(aosArgv[0], /* bForBinary=*/true);
287+
operator GDALDatasetH() const
288+
{
289+
return m_ds;
290+
}
283291

284-
argParser.add_description(
285-
_("Calculates a viewshed raster from an input raster DEM."));
292+
operator bool() const
293+
{
294+
return m_ds != nullptr;
295+
}
286296

287-
argParser.add_epilog(_("For more details, consult "
288-
"https://gdal.org/programs/gdal_viewshed.html"));
297+
bool operator!() const
298+
{
299+
return m_ds == nullptr;
300+
}
289301

290-
Options localOpts = parseArgs(argParser, aosArgv);
291-
viewshed::Options &opts = localOpts.opts;
302+
GDALDatasetH m_ds;
303+
};
292304

293-
validateArgs(localOpts, argParser);
305+
bool run(gdal::Options &localOpts, bool adjustCurveCoeff)
306+
{
307+
viewshed::Options &opts = localOpts.opts;
294308

295309
/* -------------------------------------------------------------------- */
296310
/* Open source raster file. */
297311
/* -------------------------------------------------------------------- */
298-
GDALDatasetH hSrcDS =
312+
ScopedDataset srcDs =
299313
GDALOpen(localOpts.osSrcFilename.c_str(), GA_ReadOnly);
300-
if (hSrcDS == nullptr)
314+
if (!srcDs)
301315
exit(2);
302316

303-
GDALRasterBandH hBand = GDALGetRasterBand(hSrcDS, localOpts.nBandIn);
317+
GDALRasterBandH hBand = GDALGetRasterBand(srcDs, localOpts.nBandIn);
304318
if (hBand == nullptr)
305319
{
306320
CPLError(CE_Failure, CPLE_AppDefined,
@@ -311,28 +325,31 @@ MAIN_START(argc, argv)
311325
/* -------------------------------------------------------------------- */
312326
/* Open source SD raster file. */
313327
/* -------------------------------------------------------------------- */
314-
GDALDatasetH hSdDS = GDALOpen(localOpts.osSdFilename.c_str(), GA_ReadOnly);
315-
if (hSdDS == nullptr)
316-
exit(2);
328+
ScopedDataset sdDs;
329+
GDALRasterBandH hSdBand = nullptr;
317330

318-
GDALRasterBandH hSdBand = GDALGetRasterBand(hSdDS, 1);
319-
if (hSdBand == nullptr)
331+
if (localOpts.osSdFilename.size())
320332
{
321-
CPLError(CE_Failure, CPLE_AppDefined,
322-
"SD band (1) does not exist on SD dataset.");
323-
exit(2);
333+
sdDs = GDALOpen(localOpts.osSdFilename.c_str(), GA_ReadOnly);
334+
if (!sdDs)
335+
exit(2);
336+
337+
hSdBand = GDALGetRasterBand(sdDs, 1);
338+
if (hSdBand == nullptr)
339+
{
340+
CPLError(CE_Failure, CPLE_AppDefined,
341+
"SD band (1) does not exist on SD dataset.");
342+
exit(2);
343+
}
324344
}
325345

326-
if (!argParser.is_used("-cc"))
327-
opts.curveCoeff =
328-
gdal::viewshed::adjustCurveCoeff(opts.curveCoeff, hSrcDS);
346+
if (adjustCurveCoeff)
347+
opts.curveCoeff = viewshed::adjustCurveCoeff(opts.curveCoeff, srcDs);
329348

330349
/* -------------------------------------------------------------------- */
331350
/* Invoke. */
332351
/* -------------------------------------------------------------------- */
333352

334-
GDALDatasetH hDstDS;
335-
336353
bool bSuccess;
337354
if (opts.outputMode == viewshed::OutputMode::Cumulative)
338355
{
@@ -344,14 +361,54 @@ MAIN_START(argc, argv)
344361
else
345362
{
346363
viewshed::Viewshed oViewshed(opts);
347-
bSuccess = oViewshed.run(hBand, hSdBand,
348-
localOpts.bQuiet ? GDALDummyProgress
349-
: GDALTermProgress);
350-
hDstDS = GDALDataset::FromHandle(oViewshed.output().release());
351-
GDALClose(hSrcDS);
352-
if (GDALClose(hDstDS) != CE_None)
353-
bSuccess = false;
364+
365+
if (hSdBand)
366+
bSuccess = oViewshed.run(hBand, hSdBand,
367+
localOpts.bQuiet ? GDALDummyProgress
368+
: GDALTermProgress);
369+
else
370+
bSuccess = oViewshed.run(
371+
hBand, localOpts.bQuiet ? GDALDummyProgress : GDALTermProgress);
372+
ScopedDataset dstDs =
373+
GDALDataset::FromHandle(oViewshed.output().release());
374+
bSuccess = dstDs;
354375
}
376+
return bSuccess;
377+
}
378+
379+
} // namespace gdal
380+
381+
/************************************************************************/
382+
/* main() */
383+
/************************************************************************/
384+
385+
MAIN_START(argc, argv)
386+
{
387+
using namespace gdal;
388+
389+
EarlySetConfigOptions(argc, argv);
390+
391+
GDALAllRegister();
392+
393+
argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
394+
CPLStringList aosArgv;
395+
aosArgv.Assign(argv, /* bTakeOwnership= */ true);
396+
if (argc < 1)
397+
std::exit(-argc);
398+
399+
GDALArgumentParser argParser(aosArgv[0], /* bForBinary=*/true);
400+
401+
argParser.add_description(
402+
_("Calculates a viewshed raster from an input raster DEM."));
403+
404+
argParser.add_epilog(_("For more details, consult "
405+
"https://gdal.org/programs/gdal_viewshed.html"));
406+
407+
Options localOpts = parseArgs(argParser, aosArgv);
408+
409+
validateArgs(localOpts, argParser);
410+
411+
bool bSuccess = run(localOpts, !argParser.is_used("-cc"));
355412

356413
GDALDestroyDriverManager();
357414
OGRCleanupAll();

0 commit comments

Comments
 (0)