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

Generated by: LCOV version 1.14