diff --git a/apps/ogrinfo_lib.cpp b/apps/ogrinfo_lib.cpp index a407116421a3..9aa19640505a 100644 --- a/apps/ogrinfo_lib.cpp +++ b/apps/ogrinfo_lib.cpp @@ -52,7 +52,6 @@ typedef enum struct GDALVectorInfoOptions { GDALVectorInfoFormat eFormat = FORMAT_TEXT; - std::string osFilename{}; std::string osWHERE{}; CPLStringList aosLayers{}; std::unique_ptr poSpatialFilter; @@ -1843,9 +1842,7 @@ char *GDALVectorInfo(GDALDatasetH hDataset, CPLString osRet; CPLJSONObject oRoot; - const std::string osFilename(!psOptions->osFilename.empty() - ? psOptions->osFilename - : std::string(poDS->GetDescription())); + const std::string osFilename(poDS->GetDescription()); const bool bJson = psOptions->eFormat == FORMAT_JSON; CPLJSONArray oLayerArray; @@ -2430,8 +2427,13 @@ static std::unique_ptr GDALVectorInfoOptionsGetParser( .help(_("Format/driver name(s) to try when opening the input file.")); argParser->add_argument("filename") - .nargs(psOptionsForBinary ? 1 : 0) - .store_into(psOptions->osFilename) + .nargs(argparse::nargs_pattern::optional) + .action( + [psOptionsForBinary](const std::string &s) + { + if (psOptionsForBinary) + psOptionsForBinary->osFilename = s; + }) .help(_("The data source to open.")); argParser->add_argument("layer") @@ -2471,12 +2473,21 @@ std::string GDALVectorInfoGetParserUsage() /** * Allocates a GDALVectorInfoOptions struct. * + * Note that when this function is used a library function, and not from the + * ogrinfo utility, a dataset name must be specified if any layer names(s) are + * specified (if no layer name is specific, passing a dataset name is not + * needed). That dataset name may be a dummy one, as the dataset taken into + * account is the hDS parameter passed to GDALVectorInfo(). + * Similarly the -oo switch in a non-ogrinfo context will be ignored, and it + * is the responsibility of the user to apply them when opening the hDS parameter + * passed to GDALVectorInfo(). + * * @param papszArgv NULL terminated list of options (potentially including * filename and open options too), or NULL. The accepted options are the ones of * the ogrinfo utility. * @param psOptionsForBinary (output) may be NULL (and should generally be * NULL), otherwise (ogrinfo_bin.cpp use case) must be allocated with - * GDALVectorInfoOptionsForBinaryNew() prior to this + * GDALVectorInfoOptionsForBinaryNew() prior to this * function. Will be filled with potentially present filename, open options, * subdataset number... * @return pointer to the allocated GDALVectorInfoOptions struct. Must be freed @@ -2594,7 +2605,6 @@ GDALVectorInfoOptionsNew(char **papszArgv, if (psOptionsForBinary) { psOptions->bStdoutOutput = true; - psOptionsForBinary->osFilename = psOptions->osFilename; psOptionsForBinary->osSQLStatement = psOptions->osSQLStatement; } diff --git a/autotest/utilities/test_ogrinfo_lib.py b/autotest/utilities/test_ogrinfo_lib.py index e46db5212df0..055e69ed2c40 100755 --- a/autotest/utilities/test_ogrinfo_lib.py +++ b/autotest/utilities/test_ogrinfo_lib.py @@ -609,3 +609,31 @@ def test_ogrinfo_lib_json_features_resolution(): s = gdal.VectorInfo(content, dumpFeatures=True) assert "POINT Z (1.2 1.2 1.23)" in s + + +############################################################################### +# Test layers option + + +def test_ogrinfo_lib_layers(): + + ds = gdal.GetDriverByName("Memory").Create("dummy", 0, 0, 0, gdal.GDT_Unknown) + ds.CreateLayer("foo") + ds.CreateLayer("bar") + + j = gdal.VectorInfo(ds, format="json", layers=[]) + assert len(j["layers"]) == 2 + assert j["layers"][0]["name"] == "foo" + assert j["layers"][1]["name"] == "bar" + + j = gdal.VectorInfo(ds, format="json", layers=["foo"]) + assert len(j["layers"]) == 1 + assert j["layers"][0]["name"] == "foo" + + j = gdal.VectorInfo(ds, format="json", layers=["foo", "bar"]) + assert len(j["layers"]) == 2 + assert j["layers"][0]["name"] == "foo" + assert j["layers"][1]["name"] == "bar" + + with pytest.raises(Exception, match="Couldn't fetch requested layer"): + gdal.VectorInfo(ds, format="json", layers=["invalid"])