@@ -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