LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_index.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 97 99 98.0 %
Date: 2025-08-19 18:03:11 Functions: 5 5 100.0 %

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

Generated by: LCOV version 1.14