Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make gdalinfo/ogrinfo --formats -json work #10881

Merged
merged 1 commit into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions autotest/utilities/test_gdalinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ def test_gdalinfo_20(gdalinfo_path):
assert "GTiff -raster- (rw+vs): GeoTIFF" in ret


###############################################################################
# Test --formats -json


@pytest.mark.require_driver("VRT")
def test_gdalinfo_formats_json(gdalinfo_path):

ret = json.loads(
gdaltest.runexternal(gdalinfo_path + " --formats -json", check_memleak=False)
)
assert {
"short_name": "VRT",
"long_name": "Virtual Raster",
"scopes": ["raster", "multidimensional_raster"],
"capabilities": ["open", "create", "create_copy", "virtual_io"],
"file_extensions": ["vrt"],
} in ret


###############################################################################
# Test erroneous use of --format.

Expand Down
20 changes: 20 additions & 0 deletions autotest/utilities/test_ogrinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
# DEALINGS IN THE SOFTWARE.
###############################################################################

import json
import os
import pathlib
import stat
Expand Down Expand Up @@ -324,6 +325,25 @@ def test_ogrinfo_19(ogrinfo_path):
assert "ESRI Shapefile -vector- (rw+v): ESRI Shapefile" in ret


###############################################################################
# Test --formats -json


@pytest.mark.require_driver("ESRI Shapefile")
def test_ogrinfo_formats_json(ogrinfo_path):

ret = json.loads(
gdaltest.runexternal(ogrinfo_path + " --formats -json", check_memleak=False)
)
assert {
"short_name": "ESRI Shapefile",
"long_name": "ESRI Shapefile",
"scopes": ["vector"],
"capabilities": ["open", "create", "virtual_io"],
"file_extensions": ["shp", "dbf", "shz", "shp.zip"],
} in ret


###############################################################################
# Test --help-general

Expand Down
4 changes: 4 additions & 0 deletions doc/source/programs/raster_common_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ All GDAL command line programs support the following common options.

List detailed information about a single format driver. The format should be the short name reported in the --formats list, such as GTiff.

.. option:: --formats

List all drivers. Can be combined with ``-json`` switch of :program:`gdalinfo` of since GDAL 3.10

.. _raster_common_options_optfile:
.. option:: --optfile <filename>

Expand Down
4 changes: 4 additions & 0 deletions doc/source/programs/vector_common_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ All GDAL OGR command line programs support the following common options.
The format should be the short name reported in the :option:`--formats`
list, such as GML.

.. option:: --formats

List all drivers. Can be combined with ``-json`` switch of :program:`ogrinfo` of since GDAL 3.10

.. option:: --optfile <filename>

Read the named file and substitute the contents into the command line
Expand Down
87 changes: 85 additions & 2 deletions gcore/gdal_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

#include "cpl_conv.h"
#include "cpl_error.h"
#include "cpl_json.h"
#include "cpl_minixml.h"
#include "cpl_multiproc.h"
#include "cpl_string.h"
Expand Down Expand Up @@ -3425,7 +3426,7 @@ static void StripIrrelevantOptions(CPLXMLNode *psCOL, int nOptions)
* --version: report version of GDAL in use.
* --build: report build info about GDAL in use.
* --license: report GDAL license info.
* --formats: report all format drivers configured.
* --formats: report all format drivers configured. Can be used with -json since 3.10
* --format [format]: report details of one format driver.
* --optfile filename: expand an option file into the argument list.
* --config key value: set system configuration option.
Expand Down Expand Up @@ -3716,6 +3717,88 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
if (nOptions == 0)
nOptions = GDAL_OF_RASTER;

bool bJSON = false;
for (int i = 1; i < nArgc; i++)
{
if (strcmp(papszArgv[i], "-json") == 0)
{
bJSON = true;
break;
}
}

if (bJSON)
{
auto poDM = GetGDALDriverManager();
CPLJSONArray oArray;
const int nDriverCount = poDM->GetDriverCount();
for (int iDr = 0; iDr < nDriverCount; ++iDr)
{
auto poDriver = poDM->GetDriver(iDr);
CSLConstList papszMD = poDriver->GetMetadata();

if (nOptions == GDAL_OF_RASTER &&
!CPLFetchBool(papszMD, GDAL_DCAP_RASTER, false))
continue;
if (nOptions == GDAL_OF_VECTOR &&
!CPLFetchBool(papszMD, GDAL_DCAP_VECTOR, false))
continue;
if (nOptions == GDAL_OF_GNM &&
!CPLFetchBool(papszMD, GDAL_DCAP_GNM, false))
continue;
if (nOptions == GDAL_OF_MULTIDIM_RASTER &&
!CPLFetchBool(papszMD, GDAL_DCAP_MULTIDIM_RASTER,
false))
continue;

CPLJSONObject oJDriver;
oJDriver.Set("short_name", poDriver->GetDescription());
if (const char *pszLongName =
CSLFetchNameValue(papszMD, GDAL_DMD_LONGNAME))
oJDriver.Set("long_name", pszLongName);
CPLJSONArray oJScopes;
if (CPLFetchBool(papszMD, GDAL_DCAP_RASTER, false))
oJScopes.Add("raster");
if (CPLFetchBool(papszMD, GDAL_DCAP_MULTIDIM_RASTER, false))
oJScopes.Add("multidimensional_raster");
if (CPLFetchBool(papszMD, GDAL_DCAP_VECTOR, false))
oJScopes.Add("vector");
oJDriver.Add("scopes", oJScopes);
CPLJSONArray oJCaps;
if (CPLFetchBool(papszMD, GDAL_DCAP_OPEN, false))
oJCaps.Add("open");
if (CPLFetchBool(papszMD, GDAL_DCAP_CREATE, false))
oJCaps.Add("create");
if (CPLFetchBool(papszMD, GDAL_DCAP_CREATECOPY, false))
oJCaps.Add("create_copy");
if (CPLFetchBool(papszMD, GDAL_DCAP_VIRTUALIO, false))
oJCaps.Add("virtual_io");
oJDriver.Add("capabilities", oJCaps);

if (const char *pszExtensions = CSLFetchNameValueDef(
papszMD, GDAL_DMD_EXTENSIONS,
CSLFetchNameValue(papszMD, GDAL_DMD_EXTENSION)))
{
const CPLStringList aosExt(
CSLTokenizeString2(pszExtensions, " ", 0));
CPLJSONArray oJExts;
for (int i = 0; i < aosExt.size(); ++i)
{
oJExts.Add(aosExt[i]);
}
oJDriver.Add("file_extensions", oJExts);
}

oArray.Add(oJDriver);
}
printf(/*ok*/
"%s\n",
oArray.Format(CPLJSONObject::PrettyFormat::Pretty)
.c_str());

return 0;
}

printf(/*ok*/
"Supported Formats: (ro:read-only, rw:read-write, +:update, "
"v:virtual-I/O s:subdatasets)\n");
Expand All @@ -3725,7 +3808,7 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,

const char *pszRFlag = "", *pszWFlag, *pszVirtualIO,
*pszSubdatasets;
char **papszMD = GDALGetMetadata(hDriver, nullptr);
CSLConstList papszMD = GDALGetMetadata(hDriver, nullptr);

if (nOptions == GDAL_OF_RASTER &&
!CPLFetchBool(papszMD, GDAL_DCAP_RASTER, false))
Expand Down
Loading