LCOV - code coverage report
Current view: top level - apps - gdal_footprint_bin.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 66 97 68.0 %
Date: 2024-05-03 15:49:35 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Utilities
       4             :  * Purpose:  Computes the footprint of a GDAL raster
       5             :  * Authors:  Even Rouault, <even dot rouault at spatialys dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Even Rouault <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "cpl_string.h"
      30             : #include "gdal_version.h"
      31             : #include "commonutils.h"
      32             : #include "gdal_utils_priv.h"
      33             : #include "gdal_priv.h"
      34             : #include "ogrsf_frmts.h"
      35             : 
      36             : /************************************************************************/
      37             : /*                               Usage()                                */
      38             : /************************************************************************/
      39             : 
      40           0 : static void Usage(bool bIsError, const char *pszErrorMsg = nullptr)
      41             : 
      42             : {
      43           0 :     fprintf(bIsError ? stderr : stdout,
      44             :             "Usage: gdal_footprint [--help] [--help-general]\n"
      45             :             "       [-b <band>]... [-combine_bands union|intersection]\n"
      46             :             "       [-oo <NAME>=<VALUE>]... [-ovr <index>]\n"
      47             :             "       [-srcnodata \"<value>[ <value>]...\"]\n"
      48             :             "       [-t_cs pixel|georef] [-t_srs <srs_def>] [-split_polys]\n"
      49             :             "       [-convex_hull] [-densify <value>] [-simplify <value>]\n"
      50             :             "       [-min_ring_area <value>] [-max_points <value>|unlimited]\n"
      51             :             "       [-of <ogr_format>] [-lyr_name <dst_layername>]\n"
      52             :             "       [-location_field_name <field_name>] [-no_location]\n"
      53             :             "       [-write_absolute_path]\n"
      54             :             "       [-dsco <name>=<value>]... [-lco <name>=<value>]... "
      55             :             "[-overwrite] [-q]\n"
      56             :             "       <src_filename> <dst_filename>\n");
      57             : 
      58           0 :     if (pszErrorMsg != nullptr)
      59           0 :         fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
      60           0 :     exit(bIsError ? 1 : 0);
      61             : }
      62             : 
      63             : /************************************************************************/
      64             : /*                                main()                                */
      65             : /************************************************************************/
      66             : 
      67           8 : MAIN_START(argc, argv)
      68             : {
      69             :     /* Check strict compilation and runtime library version as we use C++ API */
      70           8 :     if (!GDAL_CHECK_VERSION(argv[0]))
      71           0 :         exit(1);
      72             : 
      73           8 :     EarlySetConfigOptions(argc, argv);
      74             : 
      75             :     /* -------------------------------------------------------------------- */
      76             :     /*      Generic arg processing.                                         */
      77             :     /* -------------------------------------------------------------------- */
      78           8 :     GDALAllRegister();
      79           8 :     argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
      80           8 :     if (argc < 1)
      81           0 :         exit(-argc);
      82             : 
      83          34 :     for (int i = 0; i < argc; i++)
      84             :     {
      85          27 :         if (EQUAL(argv[i], "--utility_version"))
      86             :         {
      87           1 :             printf("%s was compiled against GDAL %s and "
      88             :                    "is running against GDAL %s\n",
      89             :                    argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
      90           1 :             CSLDestroy(argv);
      91           1 :             return 0;
      92             :         }
      93          26 :         else if (EQUAL(argv[i], "--help"))
      94             :         {
      95           0 :             Usage(false);
      96             :         }
      97             :     }
      98             : 
      99           7 :     GDALFootprintOptionsForBinary sOptionsForBinary;
     100             :     // coverity[tainted_data]
     101             :     GDALFootprintOptions *psOptions =
     102           7 :         GDALFootprintOptionsNew(argv + 1, &sOptionsForBinary);
     103           7 :     CSLDestroy(argv);
     104             : 
     105           7 :     if (psOptions == nullptr)
     106             :     {
     107           0 :         Usage(true);
     108             :     }
     109             : 
     110           7 :     if (!(sOptionsForBinary.bQuiet))
     111             :     {
     112           6 :         GDALFootprintOptionsSetProgress(psOptions, GDALTermProgress, nullptr);
     113             :     }
     114             : 
     115           7 :     if (sOptionsForBinary.osSource.empty())
     116           0 :         Usage(true, "No input file specified.");
     117             : 
     118           7 :     if (!sOptionsForBinary.bDestSpecified)
     119           0 :         Usage(true, "No output file specified.");
     120             : 
     121             :     /* -------------------------------------------------------------------- */
     122             :     /*      Open input file.                                                */
     123             :     /* -------------------------------------------------------------------- */
     124           7 :     GDALDatasetH hInDS = GDALOpenEx(sOptionsForBinary.osSource.c_str(),
     125             :                                     GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
     126             :                                     /*papszAllowedDrivers=*/nullptr,
     127           7 :                                     sOptionsForBinary.aosOpenOptions.List(),
     128             :                                     /*papszSiblingFiles=*/nullptr);
     129             : 
     130           7 :     if (hInDS == nullptr)
     131           1 :         exit(1);
     132             : 
     133             :     /* -------------------------------------------------------------------- */
     134             :     /*      Open output file if it exists.                                  */
     135             :     /* -------------------------------------------------------------------- */
     136           6 :     GDALDatasetH hDstDS = nullptr;
     137           6 :     if (!(sOptionsForBinary.bCreateOutput))
     138             :     {
     139           5 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     140             :         hDstDS =
     141           5 :             GDALOpenEx(sOptionsForBinary.osDest.c_str(),
     142             :                        GDAL_OF_VECTOR | GDAL_OF_VERBOSE_ERROR | GDAL_OF_UPDATE,
     143             :                        nullptr, nullptr, nullptr);
     144           5 :         CPLPopErrorHandler();
     145             :     }
     146             : 
     147           7 :     if (!sOptionsForBinary.osFormat.empty() &&
     148           1 :         (sOptionsForBinary.bCreateOutput || hDstDS == nullptr))
     149             :     {
     150           1 :         GDALDriverManager *poDM = GetGDALDriverManager();
     151             :         GDALDriver *poDriver =
     152           1 :             poDM->GetDriverByName(sOptionsForBinary.osFormat.c_str());
     153           1 :         char **papszDriverMD = (poDriver) ? poDriver->GetMetadata() : nullptr;
     154           2 :         if (poDriver == nullptr ||
     155           1 :             !CPLTestBool(CSLFetchNameValueDef(papszDriverMD, GDAL_DCAP_VECTOR,
     156           2 :                                               "FALSE")) ||
     157           1 :             !CPLTestBool(
     158             :                 CSLFetchNameValueDef(papszDriverMD, GDAL_DCAP_CREATE, "FALSE")))
     159             :         {
     160           0 :             fprintf(stderr,
     161             :                     "Output driver `%s' not recognised or does not support "
     162             :                     "direct output file creation.\n",
     163             :                     sOptionsForBinary.osFormat.c_str());
     164           0 :             fprintf(stderr, "The following format drivers are configured and "
     165             :                             "support direct output:\n");
     166             : 
     167           0 :             for (int iDriver = 0; iDriver < poDM->GetDriverCount(); iDriver++)
     168             :             {
     169           0 :                 GDALDriver *poIter = poDM->GetDriver(iDriver);
     170           0 :                 papszDriverMD = poIter->GetMetadata();
     171           0 :                 if (CPLTestBool(CSLFetchNameValueDef(
     172           0 :                         papszDriverMD, GDAL_DCAP_VECTOR, "FALSE")) &&
     173           0 :                     CPLTestBool(CSLFetchNameValueDef(
     174             :                         papszDriverMD, GDAL_DCAP_CREATE, "FALSE")))
     175             :                 {
     176           0 :                     fprintf(stderr, "  -> `%s'\n", poIter->GetDescription());
     177             :                 }
     178             :             }
     179           0 :             exit(1);
     180             :         }
     181             :     }
     182             : 
     183           6 :     if (hDstDS && sOptionsForBinary.bOverwrite)
     184             :     {
     185           1 :         auto poDstDS = GDALDataset::FromHandle(hDstDS);
     186           1 :         int nLayerCount = poDstDS->GetLayerCount();
     187           1 :         int iLayerToDelete = -1;
     188           2 :         for (int i = 0; i < nLayerCount; ++i)
     189             :         {
     190           1 :             auto poLayer = poDstDS->GetLayer(i);
     191           2 :             if (poLayer &&
     192           1 :                 poLayer->GetName() == sOptionsForBinary.osDestLayerName)
     193             :             {
     194           0 :                 iLayerToDelete = i;
     195           0 :                 break;
     196             :             }
     197             :         }
     198           1 :         bool bDeleteOK = false;
     199           1 :         if (iLayerToDelete >= 0 && poDstDS->TestCapability(ODsCDeleteLayer))
     200             :         {
     201           0 :             bDeleteOK = poDstDS->DeleteLayer(iLayerToDelete) == OGRERR_NONE;
     202             :         }
     203           1 :         if (!bDeleteOK && nLayerCount == 1)
     204             :         {
     205           1 :             GDALClose(hDstDS);
     206           1 :             hDstDS = nullptr;
     207           1 :             CPLPushErrorHandler(CPLQuietErrorHandler);
     208           1 :             GDALDeleteDataset(nullptr, sOptionsForBinary.osDest.c_str());
     209           1 :             CPLPopErrorHandler();
     210           1 :             VSIUnlink(sOptionsForBinary.osDest.c_str());
     211           1 :         }
     212             :     }
     213           5 :     else if (sOptionsForBinary.bOverwrite)
     214             :     {
     215           0 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     216           0 :         GDALDeleteDataset(nullptr, sOptionsForBinary.osDest.c_str());
     217           0 :         CPLPopErrorHandler();
     218           0 :         VSIUnlink(sOptionsForBinary.osDest.c_str());
     219             :     }
     220             : 
     221           6 :     int bUsageError = FALSE;
     222           6 :     GDALDatasetH hRetDS = GDALFootprint(sOptionsForBinary.osDest.c_str(),
     223             :                                         hDstDS, hInDS, psOptions, &bUsageError);
     224           6 :     if (bUsageError == TRUE)
     225           0 :         Usage(true);
     226           6 :     int nRetCode = hRetDS ? 0 : 1;
     227             : 
     228           6 :     GDALClose(hInDS);
     229           6 :     if (GDALClose(hRetDS) != CE_None)
     230           0 :         nRetCode = 1;
     231           6 :     GDALFootprintOptionsFree(psOptions);
     232             : 
     233           6 :     GDALDestroyDriverManager();
     234             : 
     235           6 :     return nRetCode;
     236             : }
     237             : 
     238           0 : MAIN_END

Generated by: LCOV version 1.14