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 49 : GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm() 30 49 : : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL) 31 : { 32 49 : AddOutputFormatArg(&m_format).SetDefault("json").SetChoices("json", "text"); 33 49 : AddOpenOptionsArg(&m_openOptions); 34 49 : AddInputFormatsArg(&m_inputFormats) 35 98 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}); 36 : auto &datasetArg = 37 49 : AddInputDatasetArg(&m_dataset, GDAL_OF_VECTOR).AddAlias("dataset"); 38 : auto &layerArg = 39 49 : AddLayerNameArg(&m_layerNames).SetMutualExclusionGroup("layer-sql"); 40 49 : SetAutoCompleteFunctionForLayerName(layerArg, datasetArg); 41 : AddArg("features", 0, 42 : _("List all features (beware of RAM consumption on large layers)"), 43 98 : &m_listFeatures) 44 49 : .SetMutualExclusionGroup("summary-features"); 45 : AddArg("summary", 0, _("List the layer names and the geometry type"), 46 98 : &m_summaryOnly) 47 49 : .SetMutualExclusionGroup("summary-features"); 48 : AddArg("sql", 0, 49 : _("Execute the indicated SQL statement and return the result"), 50 98 : &m_sql) 51 49 : .SetReadFromFileAtSyntaxAllowed() 52 98 : .SetMetaVar("<statement>|@<filename>") 53 49 : .SetRemoveSQLCommentsEnabled() 54 49 : .SetMutualExclusionGroup("layer-sql"); 55 : AddArg("where", 0, 56 : _("Attribute query in a restricted form of the queries used in the " 57 : "SQL WHERE statement"), 58 98 : &m_where) 59 49 : .SetReadFromFileAtSyntaxAllowed() 60 98 : .SetMetaVar("<WHERE>|@<filename>") 61 49 : .SetRemoveSQLCommentsEnabled(); 62 49 : AddArg("dialect", 0, _("SQL dialect"), &m_dialect); 63 : AddArg(GDAL_ARG_NAME_UPDATE, 0, _("Open the dataset in update mode"), 64 98 : &m_update) 65 : .AddAction( 66 2 : [this]() 67 : { 68 1 : if (m_update) 69 : { 70 1 : ReportError(CE_Warning, CPLE_AppDefined, 71 : "Option 'update' is deprecated since GDAL 3.12 " 72 : "and will be removed in GDAL 3.13. Use 'gdal " 73 : "vector sql --update' instead."); 74 : } 75 49 : }); 76 49 : AddOutputStringArg(&m_output); 77 : AddArg("stdout", 0, 78 : _("Directly output on stdout (format=text mode only). If enabled, " 79 : "output-string will be empty"), 80 98 : &m_stdout) 81 49 : .SetHiddenForCLI(); 82 49 : } 83 : 84 : /************************************************************************/ 85 : /* GDALVectorInfoAlgorithm::RunImpl() */ 86 : /************************************************************************/ 87 : 88 22 : bool GDALVectorInfoAlgorithm::RunImpl(GDALProgressFunc, void *) 89 : { 90 22 : CPLAssert(m_dataset.GetDatasetRef()); 91 : 92 44 : CPLStringList aosOptions; 93 : 94 22 : aosOptions.AddString("--cli"); 95 : 96 22 : if (m_format == "json") 97 : { 98 13 : aosOptions.AddString("-json"); 99 : } 100 : 101 22 : if (m_summaryOnly) 102 : { 103 4 : aosOptions.AddString("-summary"); 104 : } 105 18 : else if (m_listFeatures) 106 : { 107 2 : aosOptions.AddString("-features"); 108 : } 109 : 110 22 : if (!m_sql.empty()) 111 : { 112 3 : aosOptions.AddString("-sql"); 113 3 : aosOptions.AddString(m_sql.c_str()); 114 : } 115 22 : if (!m_where.empty()) 116 : { 117 2 : aosOptions.AddString("-where"); 118 2 : aosOptions.AddString(m_where.c_str()); 119 : } 120 22 : if (!m_dialect.empty()) 121 : { 122 2 : aosOptions.AddString("-dialect"); 123 2 : aosOptions.AddString(m_dialect.c_str()); 124 : } 125 22 : if (m_stdout) 126 : { 127 1 : aosOptions.AddString("-stdout"); 128 : } 129 : 130 : // Must be last, as positional 131 22 : aosOptions.AddString("dummy"); 132 24 : for (const std::string &name : m_layerNames) 133 2 : aosOptions.AddString(name.c_str()); 134 : 135 22 : if (m_layerNames.empty()) 136 : { 137 20 : aosOptions.AddString("-al"); 138 : } 139 : 140 : GDALVectorInfoOptions *psInfo = 141 22 : GDALVectorInfoOptionsNew(aosOptions.List(), nullptr); 142 : 143 22 : char *ret = GDALVectorInfo(GDALDataset::ToHandle(m_dataset.GetDatasetRef()), 144 : psInfo); 145 22 : GDALVectorInfoOptionsFree(psInfo); 146 22 : if (!ret) 147 1 : return false; 148 : 149 21 : m_output = ret; 150 21 : CPLFree(ret); 151 : 152 21 : return true; 153 : } 154 : 155 : //! @endcond