LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_info.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 97 101 96.0 %
Date: 2026-07-09 08:35:43 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "vector info" subcommand
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_vector_info.h"
      14             : 
      15             : #include "cpl_conv.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdal_utils.h"
      18             : 
      19             : //! @cond Doxygen_Suppress
      20             : 
      21             : #ifndef _
      22             : #define _(x) (x)
      23             : #endif
      24             : 
      25             : /************************************************************************/
      26             : /*          GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm()          */
      27             : /************************************************************************/
      28             : 
      29         234 : GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm(bool standaloneStep)
      30             :     : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      31           0 :                                       ConstructorOptions()
      32         234 :                                           .SetStandaloneStep(standaloneStep)
      33         234 :                                           .SetInputDatasetMaxCount(1)
      34         468 :                                           .SetAddDefaultArguments(false))
      35             : {
      36         234 :     if (standaloneStep)
      37         152 :         AddProgressArg(/* hidden = */ true);
      38             : 
      39         234 :     AddOutputFormatArg(&m_format).SetChoices("json", "text");
      40         234 :     AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep);
      41         234 :     AddInputFormatsArg(&m_inputFormats)
      42         702 :         .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR})
      43         234 :         .SetHiddenForCLI(!standaloneStep);
      44             : 
      45             :     auto &datasetArg =
      46         234 :         AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR).AddAlias("dataset");
      47         234 :     if (!standaloneStep)
      48          82 :         datasetArg.SetHidden();
      49         234 :     auto &layerArg = AddLayerNameArg(&m_layerNames)
      50         468 :                          .SetMutualExclusionGroup("layer-sql")
      51         234 :                          .AddAlias("layer");
      52         234 :     SetAutoCompleteFunctionForLayerName(layerArg, datasetArg);
      53             :     auto &argFeature =
      54             :         AddArg(
      55             :             "features", 0,
      56             :             _("List all features (beware of RAM consumption on large layers)"),
      57         468 :             &m_listFeatures)
      58         234 :             .SetMutualExclusionGroup("summary-features");
      59             :     AddArg("summary", 0, _("List the layer names and the geometry type"),
      60         468 :            &m_summaryOnly)
      61         234 :         .SetMutualExclusionGroup("summary-features");
      62             :     AddArg("limit", 0,
      63             :            _("Limit the number of features per layer (implies --features)"),
      64         468 :            &m_limit)
      65         234 :         .SetMinValueIncluded(0)
      66         468 :         .SetMetaVar("FEATURE-COUNT")
      67         237 :         .AddAction([&argFeature]() { argFeature.Set(true); });
      68             :     AddArg("sql", 0,
      69             :            _("Execute the indicated SQL statement and return the result"),
      70         468 :            &m_sql)
      71         234 :         .SetReadFromFileAtSyntaxAllowed()
      72         468 :         .SetMetaVar("<statement>|@<filename>")
      73         234 :         .SetRemoveSQLCommentsEnabled()
      74         234 :         .SetMutualExclusionGroup("layer-sql");
      75             :     AddArg("where", 0,
      76             :            _("Attribute query in a restricted form of the queries used in the "
      77             :              "SQL WHERE statement"),
      78         468 :            &m_where)
      79         234 :         .SetReadFromFileAtSyntaxAllowed()
      80         468 :         .SetMetaVar("<WHERE>|@<filename>")
      81         234 :         .SetRemoveSQLCommentsEnabled();
      82         468 :     AddArg("fid", 0, _("Feature identifier"), &m_fid)
      83         468 :         .SetMetaVar("FID")
      84         234 :         .SetMutualExclusionGroup("layer-sql");
      85         234 :     AddArg("dialect", 0, _("SQL dialect"), &m_dialect);
      86         234 :     AddOutputStringArg(&m_output);
      87         234 :     AddStdoutArg(&m_stdout);
      88             :     AddArg("crs-format", 0, _("Which format to use to report CRS"),
      89         468 :            &m_crsFormat)
      90         234 :         .SetChoices("AUTO", "WKT2", "PROJJSON")
      91         234 :         .SetDefault(m_crsFormat)
      92         234 :         .SetCategory(GAAC_ESOTERIC);
      93             : 
      94         234 :     AddValidationAction(
      95         149 :         [this]()
      96             :         {
      97          72 :             if (!m_sql.empty() && !m_where.empty())
      98             :             {
      99           1 :                 ReportError(CE_Failure, CPLE_NotSupported,
     100             :                             "Option 'sql' and 'where' are mutually exclusive");
     101           1 :                 return false;
     102             :             }
     103             : 
     104          71 :             if (m_crsFormat != "AUTO" && m_format == "json")
     105             :             {
     106           0 :                 ReportError(CE_Failure, CPLE_AppDefined,
     107             :                             "'crs-format' cannot be set when 'format' is set "
     108             :                             "to 'json'");
     109           0 :                 return false;
     110             :             }
     111             : 
     112          71 :             return true;
     113             :         });
     114         234 : }
     115             : 
     116             : /************************************************************************/
     117             : /*                  GDALVectorInfoAlgorithm::RunStep()                  */
     118             : /************************************************************************/
     119             : 
     120          32 : bool GDALVectorInfoAlgorithm::RunStep(GDALPipelineStepRunContext &)
     121             : {
     122          32 :     CPLAssert(m_inputDataset.size() == 1);
     123          32 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
     124          32 :     CPLAssert(poSrcDS);
     125             : 
     126          32 :     if (m_format.empty())
     127          19 :         m_format = IsCalledFromCommandLine() ? "text" : "json";
     128             : 
     129          64 :     CPLStringList aosOptions;
     130             : 
     131          32 :     aosOptions.AddString("--cli");
     132          32 :     aosOptions.AddString("--crs-format=" + m_crsFormat);
     133             : 
     134          32 :     if (m_format == "json")
     135             :     {
     136          18 :         aosOptions.AddString("-json");
     137             :     }
     138             : 
     139          32 :     if (m_summaryOnly)
     140             :     {
     141           4 :         aosOptions.AddString("-summary");
     142             :     }
     143          28 :     else if (m_listFeatures)
     144             :     {
     145           5 :         aosOptions.AddString("-features");
     146             :     }
     147             : 
     148          32 :     if (!m_sql.empty())
     149             :     {
     150           2 :         aosOptions.AddString("-sql");
     151           2 :         aosOptions.AddString(m_sql.c_str());
     152             :     }
     153          32 :     if (!m_where.empty())
     154             :     {
     155           2 :         aosOptions.AddString("-where");
     156           2 :         aosOptions.AddString(m_where.c_str());
     157             :     }
     158          32 :     if (m_fid >= 0)
     159             :     {
     160           1 :         aosOptions.AddString("-fid");
     161           1 :         aosOptions.AddString(CPLSPrintf("%d", m_fid));
     162             :     }
     163          32 :     if (!m_dialect.empty())
     164             :     {
     165           2 :         aosOptions.AddString("-dialect");
     166           2 :         aosOptions.AddString(m_dialect.c_str());
     167             :     }
     168          32 :     if (m_stdout)
     169             :     {
     170           6 :         aosOptions.AddString("-stdout");
     171             :     }
     172          32 :     if (m_limit > 0)
     173             :     {
     174           1 :         aosOptions.AddString("-limit");
     175           1 :         aosOptions.AddString(std::to_string(m_limit));
     176             :     }
     177             : 
     178             :     // Must be last, as positional
     179          32 :     aosOptions.AddString("dummy");
     180          33 :     for (const std::string &name : m_layerNames)
     181           1 :         aosOptions.AddString(name.c_str());
     182             : 
     183          32 :     if (m_layerNames.empty())
     184             :     {
     185          31 :         aosOptions.AddString("-al");
     186             :     }
     187             : 
     188             :     GDALVectorInfoOptions *psInfo =
     189          32 :         GDALVectorInfoOptionsNew(aosOptions.List(), nullptr);
     190             : 
     191          32 :     char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo);
     192          32 :     GDALVectorInfoOptionsFree(psInfo);
     193          32 :     if (!ret)
     194           0 :         return false;
     195             : 
     196          32 :     m_output = ret;
     197          32 :     CPLFree(ret);
     198             : 
     199          32 :     return true;
     200             : }
     201             : 
     202             : GDALVectorInfoAlgorithmStandalone::~GDALVectorInfoAlgorithmStandalone() =
     203             :     default;
     204             : 
     205             : //! @endcond

Generated by: LCOV version 1.14