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 144 : GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm(bool standaloneStep) 30 : : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL, 31 0 : ConstructorOptions() 32 144 : .SetStandaloneStep(standaloneStep) 33 144 : .SetInputDatasetMaxCount(1) 34 288 : .SetAddDefaultArguments(false)) 35 : { 36 144 : AddOutputFormatArg(&m_format).SetChoices("json", "text"); 37 144 : AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep); 38 144 : AddInputFormatsArg(&m_inputFormats) 39 432 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}) 40 144 : .SetHiddenForCLI(!standaloneStep); 41 : 42 : auto &datasetArg = 43 144 : AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR).AddAlias("dataset"); 44 144 : if (!standaloneStep) 45 69 : datasetArg.SetHidden(); 46 144 : auto &layerArg = AddLayerNameArg(&m_layerNames) 47 288 : .SetMutualExclusionGroup("layer-sql") 48 144 : .AddAlias("layer"); 49 144 : SetAutoCompleteFunctionForLayerName(layerArg, datasetArg); 50 : auto &argFeature = 51 : AddArg( 52 : "features", 0, 53 : _("List all features (beware of RAM consumption on large layers)"), 54 288 : &m_listFeatures) 55 144 : .SetMutualExclusionGroup("summary-features"); 56 : AddArg("summary", 0, _("List the layer names and the geometry type"), 57 288 : &m_summaryOnly) 58 144 : .SetMutualExclusionGroup("summary-features"); 59 : AddArg("limit", 0, 60 : _("Limit the number of features per layer (implies --features)"), 61 288 : &m_limit) 62 144 : .SetMinValueIncluded(0) 63 288 : .SetMetaVar("FEATURE-COUNT") 64 146 : .AddAction([&argFeature]() { argFeature.Set(true); }); 65 : AddArg("sql", 0, 66 : _("Execute the indicated SQL statement and return the result"), 67 288 : &m_sql) 68 144 : .SetReadFromFileAtSyntaxAllowed() 69 288 : .SetMetaVar("<statement>|@<filename>") 70 144 : .SetRemoveSQLCommentsEnabled() 71 144 : .SetMutualExclusionGroup("layer-sql"); 72 : AddArg("where", 0, 73 : _("Attribute query in a restricted form of the queries used in the " 74 : "SQL WHERE statement"), 75 288 : &m_where) 76 144 : .SetReadFromFileAtSyntaxAllowed() 77 288 : .SetMetaVar("<WHERE>|@<filename>") 78 144 : .SetRemoveSQLCommentsEnabled(); 79 288 : AddArg("fid", 0, _("Feature identifier"), &m_fid) 80 288 : .SetMetaVar("FID") 81 144 : .SetMutualExclusionGroup("layer-sql"); 82 144 : AddArg("dialect", 0, _("SQL dialect"), &m_dialect); 83 144 : AddOutputStringArg(&m_output); 84 144 : AddStdoutArg(&m_stdout); 85 : 86 144 : AddValidationAction( 87 78 : [this]() 88 : { 89 72 : if (!m_sql.empty() && !m_where.empty()) 90 : { 91 1 : ReportError(CE_Failure, CPLE_NotSupported, 92 : "Option 'sql' and 'where' are mutually exclusive"); 93 1 : return false; 94 : } 95 71 : return true; 96 : }); 97 144 : } 98 : 99 : /************************************************************************/ 100 : /* GDALVectorInfoAlgorithm::RunStep() */ 101 : /************************************************************************/ 102 : 103 32 : bool GDALVectorInfoAlgorithm::RunStep(GDALPipelineStepRunContext &) 104 : { 105 32 : CPLAssert(m_inputDataset.size() == 1); 106 32 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 107 32 : CPLAssert(poSrcDS); 108 : 109 32 : if (m_format.empty()) 110 19 : m_format = IsCalledFromCommandLine() ? "text" : "json"; 111 : 112 64 : CPLStringList aosOptions; 113 : 114 32 : aosOptions.AddString("--cli"); 115 : 116 32 : if (m_format == "json") 117 : { 118 18 : aosOptions.AddString("-json"); 119 : } 120 : 121 32 : if (m_summaryOnly) 122 : { 123 4 : aosOptions.AddString("-summary"); 124 : } 125 28 : else if (m_listFeatures) 126 : { 127 5 : aosOptions.AddString("-features"); 128 : } 129 : 130 32 : if (!m_sql.empty()) 131 : { 132 2 : aosOptions.AddString("-sql"); 133 2 : aosOptions.AddString(m_sql.c_str()); 134 : } 135 32 : if (!m_where.empty()) 136 : { 137 2 : aosOptions.AddString("-where"); 138 2 : aosOptions.AddString(m_where.c_str()); 139 : } 140 32 : if (m_fid >= 0) 141 : { 142 1 : aosOptions.AddString("-fid"); 143 1 : aosOptions.AddString(CPLSPrintf("%d", m_fid)); 144 : } 145 32 : if (!m_dialect.empty()) 146 : { 147 2 : aosOptions.AddString("-dialect"); 148 2 : aosOptions.AddString(m_dialect.c_str()); 149 : } 150 32 : if (m_stdout) 151 : { 152 6 : aosOptions.AddString("-stdout"); 153 : } 154 32 : if (m_limit > 0) 155 : { 156 1 : aosOptions.AddString("-limit"); 157 1 : aosOptions.AddString(std::to_string(m_limit)); 158 : } 159 : 160 : // Must be last, as positional 161 32 : aosOptions.AddString("dummy"); 162 33 : for (const std::string &name : m_layerNames) 163 1 : aosOptions.AddString(name.c_str()); 164 : 165 32 : if (m_layerNames.empty()) 166 : { 167 31 : aosOptions.AddString("-al"); 168 : } 169 : 170 : GDALVectorInfoOptions *psInfo = 171 32 : GDALVectorInfoOptionsNew(aosOptions.List(), nullptr); 172 : 173 32 : char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo); 174 32 : GDALVectorInfoOptionsFree(psInfo); 175 32 : if (!ret) 176 0 : return false; 177 : 178 32 : m_output = ret; 179 32 : CPLFree(ret); 180 : 181 32 : return true; 182 : } 183 : 184 : GDALVectorInfoAlgorithmStandalone::~GDALVectorInfoAlgorithmStandalone() = 185 : default; 186 : 187 : //! @endcond