From 2c52dc2f9b32095033c2d1635edaaa3f754fd72f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 11 Mar 2025 12:32:35 -0400 Subject: [PATCH 01/17] Doc: Remove derelict files from .gitignore --- doc/.gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/.gitignore b/doc/.gitignore index dd6bda754be8..b4caee1cb4bf 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,2 @@ build data -source/drivers/raster/driver_summary.rst -source/drivers/vector/driver_summary.rst From 1b5795a68819e51e455978af24f751568688e1e1 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 11 Mar 2025 14:08:16 -0400 Subject: [PATCH 02/17] Doc: Add words to spelling_wordlist.txt --- doc/source/spelling_wordlist.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/source/spelling_wordlist.txt b/doc/source/spelling_wordlist.txt index 0928cf12bb4d..8b660d989f0f 100644 --- a/doc/source/spelling_wordlist.txt +++ b/doc/source/spelling_wordlist.txt @@ -364,6 +364,7 @@ checksums Cheeseman Christoph Chroma +chrominance chs chSep cid @@ -522,6 +523,7 @@ cvs Cxx Cygwin dall +dan DanB DanielM danlittle @@ -798,6 +800,7 @@ Erdas eRequestedInputDT erer eResampleAlg +Errno erroring errorMsg ers @@ -947,6 +950,7 @@ fs fSecond fseek fsiz +fsspec ftell FTimesBold FTimesRoman @@ -1496,6 +1500,7 @@ Julien Jupyter Jürgen Kadaster +Ka kak kakadu Kakadu @@ -2144,6 +2149,7 @@ objdir objectclasses OBJECTID objektkoordinaten +observability oci OCI odbc @@ -2219,6 +2225,7 @@ orthocorrection orthorectification Orthorectified orthorectifying +os osAfter osBefore osgeo @@ -2490,6 +2497,7 @@ poOtherGeom poppler Poppler poRootGroup +pos positionName posix Posix @@ -3137,7 +3145,7 @@ subsetted subsetting Subsetting subsettings -substituable +substitutable substring subsubgroup subtelty @@ -3252,6 +3260,7 @@ tim timePosition timesheet TinZ +timezones tippecanoe tm tmerc @@ -3419,6 +3428,7 @@ utf UTF utils utm +utmsmall va Vaisala valgrind From 70cbd9867db54162f05a2d474b4b45b7259619c4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 12 Mar 2025 10:18:31 -0400 Subject: [PATCH 03/17] Doc: Escape -- to avoid unwanted in Doxygen output --- alg/viewshed/viewshed_executor.cpp | 2 +- apps/gdalargumentparser.h | 2 +- gcore/gdal_misc.cpp | 34 +++++++++++++++--------------- gcore/gdalalgorithm.h | 22 +++++++++---------- ogr/ogr_spatialref.h | 2 +- ogr/ogr_srs_api.h | 2 +- ogr/ogrutils.cpp | 22 +++++++++---------- port/cpl_conv.cpp | 6 +++--- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/alg/viewshed/viewshed_executor.cpp b/alg/viewshed/viewshed_executor.cpp index 3f54937553ca..b608cf75a2c3 100644 --- a/alg/viewshed/viewshed_executor.cpp +++ b/alg/viewshed/viewshed_executor.cpp @@ -93,7 +93,7 @@ double doMax(int nXOffset, int nYOffset, double dfThisPrev, double dfLast, } // unnamed namespace -/// Constructor -- the viewshed algorithm executor +/// Constructor - the viewshed algorithm executor /// @param srcBand Source raster band /// @param dstBand Destination raster band /// @param nX X position of observer diff --git a/apps/gdalargumentparser.h b/apps/gdalargumentparser.h index e6f64add7e10..be4c4439cf6b 100644 --- a/apps/gdalargumentparser.h +++ b/apps/gdalargumentparser.h @@ -73,7 +73,7 @@ class GDALArgumentParser : public ArgumentParser //! Format an exception as an error message and display the program usage void display_error_and_usage(const std::exception &err); - //! Add -q/--quiet argument, and store its value in *pVar (if pVar not null) + //! Add -q/\--quiet argument, and store its value in *pVar (if pVar not null) Argument &add_quiet_argument(bool *pVar); //! Add "-if format_name" argument for input format, and store its value into *pvar. diff --git a/gcore/gdal_misc.cpp b/gcore/gdal_misc.cpp index d6c310bf751c..a93baf935ef7 100644 --- a/gcore/gdal_misc.cpp +++ b/gcore/gdal_misc.cpp @@ -2838,8 +2838,8 @@ int CPL_STDCALL GDALWriteWorldFile(const char *pszBaseFilename, *
  • "RELEASE_NAME": Returns the GDAL_RELEASE_NAME. ie. "3.6.3"
  • *
  • "RELEASE_NICKNAME": (>= 3.11) Returns the GDAL_RELEASE_NICKNAME. * (may be empty)
  • - *
  • "--version": Returns one line version message suitable for - * use in response to --version requests. i.e. "GDAL 3.6.3, released + *
  • "\--version": Returns one line version message suitable for + * use in response to \--version requests. i.e. "GDAL 3.6.3, released * 2023/03/12"
  • *
  • "LICENSE": Returns the content of the LICENSE.TXT file from * the GDAL_DATA directory. @@ -3552,24 +3552,24 @@ static void StripIrrelevantOptions(CPLXMLNode *psCOL, int nOptions) * options for all GDAL commandline utilities. It takes care of the following * commandline options: * - * --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. 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. - * --config key=value: set system configuration option (since GDAL 3.9) - * --debug [on/off/value]: set debug level. - * --mempreload dir: preload directory contents into /vsimem - * --pause: Pause for user input (allows time to attach debugger) - * --locale [locale]: Install a locale using setlocale() (debugging) - * --help-general: report detailed help on general options. + * \--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. 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. + * \--config key=value: set system configuration option (since GDAL 3.9) + * \--debug [on/off/value]: set debug level. + * \--mempreload dir: preload directory contents into /vsimem + * \--pause: Pause for user input (allows time to attach debugger) + * \--locale [locale]: Install a locale using setlocale() (debugging) + * \--help-general: report detailed help on general options. * * The argument array is replaced "in place" and should be freed with * CSLDestroy() when no longer needed. The typical usage looks something * like the following. Note that the formats should be registered so that - * the --formats and --format options will work properly. + * the \--formats and \--format options will work properly. * * int main( int argc, char ** argv ) * { @@ -3583,7 +3583,7 @@ static void StripIrrelevantOptions(CPLXMLNode *psCOL, int nOptions) * @param ppapszArgv pointer to the argument list array (will be updated in * place). * @param nOptions a or-able combination of GDAL_OF_RASTER and GDAL_OF_VECTOR - * to determine which drivers should be displayed by --formats. + * to determine which drivers should be displayed by \--formats. * If set to 0, GDAL_OF_RASTER is assumed. * * @return updated nArgc argument count. Return of 0 requests terminate diff --git a/gcore/gdalalgorithm.h b/gcore/gdalalgorithm.h index 3e00fbb8adf8..ed27f2d36ea1 100644 --- a/gcore/gdalalgorithm.h +++ b/gcore/gdalalgorithm.h @@ -620,7 +620,7 @@ class CPL_DLL GDALAlgorithmArgDecl final */ GDALAlgorithmArgDecl &SetMaxCount(int count); - /** Declare whether in --help message one should display hints about the + /** Declare whether in \--help message one should display hints about the * minimum/maximum number of values. Defaults to true. */ GDALAlgorithmArgDecl &SetDisplayHintAboutRepetition(bool displayHint) @@ -862,7 +862,7 @@ class CPL_DLL GDALAlgorithmArgDecl final return m_maxCount; } - /** Returns whether in --help message one should display hints about the + /** Returns whether in \--help message one should display hints about the * minimum/maximum number of values. Defaults to true. */ inline bool GetDisplayHintAboutRepetition() const @@ -1949,7 +1949,7 @@ class CPL_DLL GDALAlgorithmRegistry }; /** Return the usage as a string appropriate for command-line interface - * --help output. + * \--help output. */ virtual std::string GetUsageForCLI(bool shortUsage, @@ -1973,19 +1973,19 @@ class CPL_DLL GDALAlgorithmRegistry return *this; } - /** Whether the --help flag has been specified. */ + /** Whether the \--help flag has been specified. */ bool IsHelpRequested() const { return m_helpRequested; } - /** Whether the --json-usage flag has been specified. */ + /** Whether the \--json-usage flag has been specified. */ bool IsJSONUsageRequested() const { return m_JSONUsageRequested; } - /** Whether the --progress flag has been specified. */ + /** Whether the \--progress flag has been specified. */ bool IsProgressBarRequested() const { if (m_selectedSubAlg) @@ -2001,7 +2001,7 @@ class CPL_DLL GDALAlgorithmRegistry /** Used by the "gdal info" special algorithm when it first tries to * run "gdal raster info", to inherit from the potential special flags, - * such as --help or --json-usage, that this later algorithm has received. + * such as \--help or \--json-usage, that this later algorithm has received. */ bool PropagateSpecialActionTo(GDALAlgorithm *target) { @@ -2035,7 +2035,7 @@ class CPL_DLL GDALAlgorithmRegistry /** Long description of the algorithm */ std::string m_longDescription{}; - /** Whether a progress bar is requested (value of --progress argument) */ + /** Whether a progress bar is requested (value of \--progress argument) */ bool m_progressBarRequested = false; friend class GDALVectorPipelineAlgorithm; @@ -2156,10 +2156,10 @@ class CPL_DLL GDALAlgorithmRegistry GDAL_OF_MULTIDIM_RASTER, bool positionalAndRequired = true); - /** Add --overwrite argument. */ + /** Add \--overwrite argument. */ GDALInConstructionAlgorithmArg &AddOverwriteArg(bool *pValue); - /** Add --update argument. */ + /** Add \--update argument. */ GDALInConstructionAlgorithmArg &AddUpdateArg(bool *pValue); /** Add (non-CLI) output-string argument. */ @@ -2188,7 +2188,7 @@ class CPL_DLL GDALAlgorithmRegistry GDALInConstructionAlgorithmArg & AddBBOXArg(std::vector *pValue, const char *helpMessage = nullptr); - /** Add --progress argument. */ + /** Add \--progress argument. */ GDALInConstructionAlgorithmArg &AddProgressArg(); /** Validation function to use for key=value type of arguments. */ diff --git a/ogr/ogr_spatialref.h b/ogr/ogr_spatialref.h index 9d3c8a61855e..6d3426f4654f 100644 --- a/ogr/ogr_spatialref.h +++ b/ogr/ogr_spatialref.h @@ -673,7 +673,7 @@ class CPL_DLL OGRSpatialReference OGRErr SetUTM(int nZone, int bNorth = TRUE); int GetUTMZone(int *pbNorth = nullptr) const; - /** Wagner I -- VII */ + /** Wagner I \-- VII */ OGRErr SetWagner(int nVariation, double dfCenterLat, double dfFalseEasting, double dfFalseNorthing); diff --git a/ogr/ogr_srs_api.h b/ogr/ogr_srs_api.h index 7e477c88b049..2a4da159ac13 100644 --- a/ogr/ogr_srs_api.h +++ b/ogr/ogr_srs_api.h @@ -895,7 +895,7 @@ OGRErr CPL_DLL OSRSetTPED(OGRSpatialReferenceH hSRS, double dfLat1, OGRErr CPL_DLL OSRSetVDG(OGRSpatialReferenceH hSRS, double dfCenterLong, double dfFalseEasting, double dfFalseNorthing); -/** Wagner I -- VII */ +/** Wagner I \-- VII */ OGRErr CPL_DLL OSRSetWagner(OGRSpatialReferenceH hSRS, int nVariation, double dfCenterLat, double dfFalseEasting, double dfFalseNorthing); diff --git a/ogr/ogrutils.cpp b/ogr/ogrutils.cpp index 0a1956bc8c42..3d49fb4df53a 100644 --- a/ogr/ogrutils.cpp +++ b/ogr/ogrutils.cpp @@ -903,21 +903,21 @@ void OGRFree(void *pMemory) * options for all OGR commandline utilities. It takes care of the following * commandline options: * - * --version: report version of GDAL in use. - * --license: report GDAL license info. - * --format [format]: report details of one format driver. - * --formats: report all format drivers configured. - * --optfile filename: expand an option file into the argument list. - * --config key value: set system configuration option. - * --debug [on/off/value]: set debug level. - * --pause: Pause for user input (allows time to attach debugger) - * --locale [locale]: Install a locale using setlocale() (debugging) - * --help-general: report detailed help on general options. + * \--version: report version of GDAL in use. + * \--license: report GDAL license info. + * \--format [format]: report details of one format driver. + * \--formats: report all format drivers configured. + * \--optfile filename: expand an option file into the argument list. + * \--config key value: set system configuration option. + * \--debug [on/off/value]: set debug level. + * \--pause: Pause for user input (allows time to attach debugger) + * \--locale [locale]: Install a locale using setlocale() (debugging) + * \--help-general: report detailed help on general options. * * The argument array is replaced "in place" and should be freed with * CSLDestroy() when no longer needed. The typical usage looks something * like the following. Note that the formats should be registered so that - * the --formats option will work properly. + * the \--formats option will work properly. * * int main( int argc, char ** argv ) * { diff --git a/port/cpl_conv.cpp b/port/cpl_conv.cpp index e2bb55ee0e31..229c3c80ab48 100644 --- a/port/cpl_conv.cpp +++ b/port/cpl_conv.cpp @@ -2038,8 +2038,8 @@ static void CPLSetConfigOptionDetectUnknownConfigOption(const char *pszKey, * value provided during the last call will be used. * * Options can also be passed on the command line of most GDAL utilities - * with '--config KEY VALUE' (or '--config KEY=VALUE' since GDAL 3.10). - * For example, ogrinfo --config CPL_DEBUG ON ~/data/test/point.shp + * with '\--config KEY VALUE' (or '\--config KEY=VALUE' since GDAL 3.10). + * For example, ogrinfo \--config CPL_DEBUG ON ~/data/test/point.shp * * This function can also be used to clear a setting by passing NULL as the * value (note: passing NULL will not unset an existing environment variable; @@ -2454,7 +2454,7 @@ void CPLLoadConfigOptionsFromFile(const char *pszFilename, int bOverrideEnvVars) * * Otherwise, for Unix builds, CPLLoadConfigOptionsFromFile() will be called * with ${sysconfdir}/gdal/gdalrc first where ${sysconfdir} evaluates - * to ${prefix}/etc, unless the --sysconfdir switch of configure has been + * to ${prefix}/etc, unless the \--sysconfdir switch of configure has been * invoked. * * Then CPLLoadConfigOptionsFromFile() will be called with $(HOME)/.gdal/gdalrc From 603245968aa32fe2ffed1b01468c95f3244a1f9a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Mar 2025 09:39:04 -0400 Subject: [PATCH 04/17] Doc build: Only check Python module loading for HTML build --- doc/source/conf.py | 72 ++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 63a8263ba25a..6b08257ad38e 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -17,42 +17,45 @@ sys.path.insert(0, os.path.abspath("_extensions")) -# -- Check we can load the GDAL Python bindings -import traceback +def check_python_bindings(): + # -- Check we can load the GDAL Python bindings -from sphinx.util import logging + import traceback -logger = logging.getLogger(__name__) -try: - from osgeo import gdal -except ImportError as e: - logger.warn( - "Failed to load GDAL Python bindings. The Python bindings must be accessible to build Python API documentation." - ) - if sys.version_info < (3, 10): - exc_info = sys.exc_info() - for line in traceback.format_exception(*exc_info): - logger.info(line[:-1]) - else: - for line in traceback.format_exception(e): - logger.info(line[:-1]) -else: - version_file = os.path.join( - os.path.dirname(__file__), os.pardir, os.pardir, "VERSION" - ) - doc_version = open(version_file).read().strip() - gdal_version = gdal.__version__ - gdal_version_stripped = gdal_version - for suffix in ["dev", "beta"]: - pos_suffix = gdal_version_stripped.find(suffix) - if pos_suffix > 0: - gdal_version_stripped = gdal_version_stripped[0:pos_suffix] - - if doc_version.strip() != gdal_version_stripped: + from sphinx.util import logging + + logger = logging.getLogger(__name__) + try: + from osgeo import gdal + except ImportError as e: logger.warn( - f"Building documentation for GDAL {doc_version} but osgeo.gdal module has version {gdal_version}. Python API documentation may be incorrect." + "Failed to load GDAL Python bindings. The Python bindings must be accessible to build Python API documentation." + ) + if sys.version_info < (3, 10): + exc_info = sys.exc_info() + for line in traceback.format_exception(*exc_info): + logger.info(line[:-1]) + else: + for line in traceback.format_exception(e): + logger.info(line[:-1]) + else: + version_file = os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, "VERSION" ) + doc_version = open(version_file).read().strip() + gdal_version = gdal.__version__ + gdal_version_stripped = gdal_version + for suffix in ["dev", "beta"]: + pos_suffix = gdal_version_stripped.find(suffix) + if pos_suffix > 0: + gdal_version_stripped = gdal_version_stripped[0:pos_suffix] + + if doc_version.strip() != gdal_version_stripped: + logger.warn( + f"Building documentation for GDAL {doc_version} but osgeo.gdal module has version {gdal_version}. Python API documentation may be incorrect." + ) + # -- Project information ----------------------------------------------------- @@ -786,3 +789,10 @@ os.path.join(os.path.dirname(__file__), "../../autotest/gcore/data/utmsmall.tif"), target_filename, ) + + +def setup(app): + app.connect( + "builder-inited", + lambda app: check_python_bindings() if app.builder.name == "html" else None, + ) From fbcdb64b22e278b8099cfca6b3b3b52b4bd340b8 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Mar 2025 09:39:49 -0400 Subject: [PATCH 05/17] Doc: Omit user survey from PDF build The SVG images cannot be written to this format --- doc/source/community/user_survey_2024.rst | 288 +++++++++++----------- 1 file changed, 147 insertions(+), 141 deletions(-) diff --git a/doc/source/community/user_survey_2024.rst b/doc/source/community/user_survey_2024.rst index 61e4adc6479b..41032d8bd01d 100644 --- a/doc/source/community/user_survey_2024.rst +++ b/doc/source/community/user_survey_2024.rst @@ -3,144 +3,150 @@ 2024 GDAL user survey ===================== -In October 2024, The GDAL maintenance program created an open survey to collect -feedback on user's experience with GDAL and the direction of the maintenance -program. The survey was publicized on gdal.org, the gdal-dev mailing list, the -project GitHub page, and social media. From October 28 to November 21, the -survey received 602 responses. - -Who responded to the survey? ----------------------------- - -Survey respondents were generally very experienced users, with 79% of users -having spent 5 or more years working with GDAL. Surprisingly, two respondents -claimed to be Frank Warmerdam, who originated the project in 1998. More than -half (52%) have built GDAL from source, 29% subscribe to the gdal-dev mailing -list, and 29% have contributed to the project by submitting bug reports or pull -requests. The high experience level of respondents reflects the challenge of -reaching users who may use GDAL less often, through other software, or are not -connected to the project community via mailing lists or social media. - -.. image:: ../../images/community/survey_2024/years_experience.svg - -Operating system -^^^^^^^^^^^^^^^^ - -Most survey respondents use GDAL on Linux, followed by Windows and OS X. -Responses to "Other" included WSL2 and iOS. - -.. image:: ../../images/community/survey_2024/operating_system.svg - -Local or cloud? -^^^^^^^^^^^^^^^ - -Most survey respondents use GDAL primarily with local file systems. - -.. image:: ../../images/community/survey_2024/local_or_cloud_read.svg - -.. image:: ../../images/community/survey_2024/local_or_cloud_write.svg - -Data formats -^^^^^^^^^^^^ - -Among raster data formats, GeoTIFF commands an overwhelming majority of GDAL -usage: - -.. image:: ../../images/community/survey_2024/raster_data_formats.svg - -The most popular vector format was GeoPackage, followed by classics such as -Shapefile, GeoJSON, and PostGIS. GeoParquet, Esri FileGeodatabase, FlatGeobuf, -and GML each earned enough votes to remain out of the "Other" category. - -.. image:: ../../images/community/survey_2024/vector_data_formats.svg - -Installing GDAL ---------------- - -Survey respondents obtain GDAL from a variety of channels, depending on the -platform. On Linux, standard system packages are the most popular solution. -OSX users rely primarily on Homebrew; most Windows users user OSGeo4W. The -popularity of Homebrew among Windows users may indicate that GDAL is being used -through the Windows Subsystem for Linux (WSL). The reported usage of OSGeo4W by -Linux users is more difficult to explain. - -.. image:: ../../images/community/survey_2024/where_gdal_obtained_linux.svg - -.. image:: ../../images/community/survey_2024/where_gdal_obtained_osx.svg - -.. image:: ../../images/community/survey_2024/where_gdal_obtained_windows.svg - -As may be expected for a group of experienced users, most respondents reported -that GDAL is easy to install with the options they need. Still, installation -remains a difficulty for many users. - -.. image:: ../../images/community/survey_2024/easy_to_install_gdal.svg - -Installation difficulties were not associated with a particular operating -system. - -.. image:: ../../images/community/survey_2024/easy_to_install_gdal_os.svg - -How is GDAL used? ------------------ - -The greatest number of respondents reported using GDAL from Python, with a -roughly 50/50 split between the GDAL Python bindings and higher-level packages -such as shapely, rasterio, and geopandas. After Python, the greatest number of -respondents reported using the command line interface, followed by smaller -number of users working in R, PostGIS, and QGIS. - -.. image:: ../../images/community/survey_2024/way_gdal_used.svg - -Getting help with GDAL ----------------------- - -Most users use gdal.org (directly or via a search engine) as their starting -point when trying to get help with GDAL. - -.. image:: ../../images/community/survey_2024/gdal_help_source.svg - -Difficulties using GDAL ------------------------ - -Users did not identify a single area as a source of their challenges with GDAL. -However, the top responses of "finding examples" and "understanding features" -point to a shortage of documentation. - -.. image:: ../../images/community/survey_2024/gdal_challenge.svg - -Consistent with the above, respondents reported "examples", "workflows", and -"API usage" as high priorities for documentation efforts. - -.. image:: ../../images/community/survey_2024/documentation_needs.svg - -And "examples" and "doc" rank highly among open-ended responses to -"what could make GDAL easier to use?" - -.. image:: ../../images/community/survey_2024/gdal_easier_to_use.svg - -Maintenance program activities ------------------------------- - -Among activities undertaken by the maintenance program so far, respondents found -the most value in enhancements to GDAL's dependencies (such as PROJ, GEOS, and -libtiff), its Python bindings, and documentation. - -.. image:: ../../images/community/survey_2024/maintenance_program_activities.svg - -Asked about a variety of tasks the maintenance program could take on beyond -those listed above, respondents showed some enthusiasm for almost everything! -Still, high priorities were given to performance, improving format -capabilities, and improving the command line interface while preserving -backward compatibility. - -.. image:: ../../images/community/survey_2024/maintenance_program_areas_of_focus.svg - -Next steps ----------- - -The maintenance program will use these results to inform work over the coming -year. Some work has already been performed to `develop an improved -command-line interface `__ and `add a -mechanism for usage examples to be cross-referenced in the -documentation `__. +.. only:: not html + + Results of the 2024 GDAL user survey are available at https://gdal.org. + +.. only:: html + + In October 2024, The GDAL maintenance program created an open survey to collect + feedback on user's experience with GDAL and the direction of the maintenance + program. The survey was publicized on gdal.org, the gdal-dev mailing list, the + project GitHub page, and social media. From October 28 to November 21, the + survey received 602 responses. + + Who responded to the survey? + ---------------------------- + + Survey respondents were generally very experienced users, with 79% of users + having spent 5 or more years working with GDAL. Surprisingly, two respondents + claimed to be Frank Warmerdam, who originated the project in 1998. More than + half (52%) have built GDAL from source, 29% subscribe to the gdal-dev mailing + list, and 29% have contributed to the project by submitting bug reports or pull + requests. The high experience level of respondents reflects the challenge of + reaching users who may use GDAL less often, through other software, or are not + connected to the project community via mailing lists or social media. + + .. image:: ../../images/community/survey_2024/years_experience.svg + + Operating system + ^^^^^^^^^^^^^^^^ + + Most survey respondents use GDAL on Linux, followed by Windows and OS X. + Responses to "Other" included WSL2 and iOS. + + .. image:: ../../images/community/survey_2024/operating_system.svg + + Local or cloud? + ^^^^^^^^^^^^^^^ + + Most survey respondents use GDAL primarily with local file systems. + + .. image:: ../../images/community/survey_2024/local_or_cloud_read.svg + + .. image:: ../../images/community/survey_2024/local_or_cloud_write.svg + + Data formats + ^^^^^^^^^^^^ + + Among raster data formats, GeoTIFF commands an overwhelming majority of GDAL + usage: + + .. image:: ../../images/community/survey_2024/raster_data_formats.svg + + The most popular vector format was GeoPackage, followed by classics such as + Shapefile, GeoJSON, and PostGIS. GeoParquet, Esri FileGeodatabase, FlatGeobuf, + and GML each earned enough votes to remain out of the "Other" category. + + .. image:: ../../images/community/survey_2024/vector_data_formats.svg + + Installing GDAL + --------------- + + Survey respondents obtain GDAL from a variety of channels, depending on the + platform. On Linux, standard system packages are the most popular solution. + OSX users rely primarily on Homebrew; most Windows users user OSGeo4W. The + popularity of Homebrew among Windows users may indicate that GDAL is being used + through the Windows Subsystem for Linux (WSL). The reported usage of OSGeo4W by + Linux users is more difficult to explain. + + .. image:: ../../images/community/survey_2024/where_gdal_obtained_linux.svg + + .. image:: ../../images/community/survey_2024/where_gdal_obtained_osx.svg + + .. image:: ../../images/community/survey_2024/where_gdal_obtained_windows.svg + + As may be expected for a group of experienced users, most respondents reported + that GDAL is easy to install with the options they need. Still, installation + remains a difficulty for many users. + + .. image:: ../../images/community/survey_2024/easy_to_install_gdal.svg + + Installation difficulties were not associated with a particular operating + system. + + .. image:: ../../images/community/survey_2024/easy_to_install_gdal_os.svg + + How is GDAL used? + ----------------- + + The greatest number of respondents reported using GDAL from Python, with a + roughly 50/50 split between the GDAL Python bindings and higher-level packages + such as shapely, rasterio, and geopandas. After Python, the greatest number of + respondents reported using the command line interface, followed by smaller + number of users working in R, PostGIS, and QGIS. + + .. image:: ../../images/community/survey_2024/way_gdal_used.svg + + Getting help with GDAL + ---------------------- + + Most users use gdal.org (directly or via a search engine) as their starting + point when trying to get help with GDAL. + + .. image:: ../../images/community/survey_2024/gdal_help_source.svg + + Difficulties using GDAL + ----------------------- + + Users did not identify a single area as a source of their challenges with GDAL. + However, the top responses of "finding examples" and "understanding features" + point to a shortage of documentation. + + .. image:: ../../images/community/survey_2024/gdal_challenge.svg + + Consistent with the above, respondents reported "examples", "workflows", and + "API usage" as high priorities for documentation efforts. + + .. image:: ../../images/community/survey_2024/documentation_needs.svg + + And "examples" and "doc" rank highly among open-ended responses to + "what could make GDAL easier to use?" + + .. image:: ../../images/community/survey_2024/gdal_easier_to_use.svg + + Maintenance program activities + ------------------------------ + + Among activities undertaken by the maintenance program so far, respondents found + the most value in enhancements to GDAL's dependencies (such as PROJ, GEOS, and + libtiff), its Python bindings, and documentation. + + .. image:: ../../images/community/survey_2024/maintenance_program_activities.svg + + Asked about a variety of tasks the maintenance program could take on beyond + those listed above, respondents showed some enthusiasm for almost everything! + Still, high priorities were given to performance, improving format + capabilities, and improving the command line interface while preserving + backward compatibility. + + .. image:: ../../images/community/survey_2024/maintenance_program_areas_of_focus.svg + + Next steps + ---------- + + The maintenance program will use these results to inform work over the coming + year. Some work has already been performed to `develop an improved + command-line interface `__ and `add a + mechanism for usage examples to be cross-referenced in the + documentation `__. From 441f060d67fd6231cec4759b477fc73d6f2cd1a2 Mon Sep 17 00:00:00 2001 From: Dan Baston Date: Mon, 10 Mar 2025 14:37:51 -0400 Subject: [PATCH 06/17] Docs: Build using CMake --- .github/workflows/code_checks.yml | 12 - .github/workflows/doc_checks.yml | 54 +- .readthedocs.yaml | 1 - doc/CMakeLists.txt | 198 +++-- doc/Makefile | 89 --- doc/requirements.txt | 1 + doc/rtd/pre_build.sh | 5 + doc/source/conf.py | 9 +- ogr/Doxyfile | 1241 ----------------------------- 9 files changed, 179 insertions(+), 1431 deletions(-) delete mode 100644 doc/Makefile delete mode 100644 ogr/Doxyfile diff --git a/.github/workflows/code_checks.yml b/.github/workflows/code_checks.yml index c7ca8295fe50..67ff8690038d 100644 --- a/.github/workflows/code_checks.yml +++ b/.github/workflows/code_checks.yml @@ -164,18 +164,6 @@ jobs: - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 - doxygen: - runs-on: ubuntu-latest - container: ghcr.io/osgeo/proj-docs - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Run doxygen - run: | - cd doc - make doxygen_check_warnings - other_checks: runs-on: ubuntu-24.04 steps: diff --git a/.github/workflows/doc_checks.yml b/.github/workflows/doc_checks.yml index eee389f10313..3109df4cc512 100644 --- a/.github/workflows/doc_checks.yml +++ b/.github/workflows/doc_checks.yml @@ -21,52 +21,44 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: true - container: ghcr.io/osgeo/proj-docs + container: ubuntu:24.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup environment shell: bash -l {0} + env: + DEBIAN_FRONTEND: noninteractive run: | apt update - apt install -y libproj-dev swig - PYTHON_CMD=python3 && $PYTHON_CMD -m pip install -r doc/requirements.txt - PYTHON_CMD=python3 && $PYTHON_CMD -m pip install numpy setuptools - pushd . + apt install -y g++ cmake doxygen enchant-2 python3 python3-dev python3-pip python3-venv libproj-dev swig + python3 -m venv create doc_env + . doc_env/bin/activate + python3 -m pip install -r doc/requirements.txt + echo PATH=$PATH >> $GITHUB_ENV + + - name: Build GDAL + shell: bash -l {0} + run: | mkdir build cd build - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH cmake .. \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_BUILD_TYPE=Debug \ -DBUILD_APPS=ON \ - -DBUILD_TESTING=OFF \ + -DBUILD_DOCS=ON \ + -DBUILD_TESTING=ON \ -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \ -DOGR_BUILD_OPTIONAL_DRIVERS=OFF cmake --build . -j$(nproc) - cmake --install . - # With the new ghcr.io/osgeo/proj-docs image based on Ubuntu 24.04 - # a venv is activated. The above does not install the - # Python bindings into it (and the ones in the system are not found - # without overriding PYTHONPATH), so do it through pip install - cd swig/python - python3 setup.py sdist - cp dist/* /tmp/gdal.tar.gz - PYTHON_CMD=python3 && $PYTHON_CMD -m pip install /tmp/gdal.tar.gz - ldconfig - popd - - - name: Update components - shell: bash -l {0} - run: | - PYTHON_CMD=python3 && $PYTHON_CMD -m pip install -U "sphinx-rtd-theme>=3.0.0" "sphinxcontrib-spelling>=8.0.0" - name: Print versions shell: bash -l {0} run: | + which python3 python3 --version sphinx-build --version - PYTHON_CMD=python3 && $PYTHON_CMD -m pip list --not-required --format=columns + python3 -m pip list --not-required --format=columns + - name: Lint .rst files shell: bash -l {0} run: | @@ -79,11 +71,11 @@ jobs: - name: Doxygen shell: bash -l {0} run: | - mkdir -p doc/build - doxygen Doxyfile + cmake --build . --target doxygen_xml + working-directory: build - name: Spelling shell: bash -l {0} run: | - sed -i '/html_extra_path/d' source/conf.py # avoid WARNING: html_extra_path entry '../build/html_extra' is placed inside outdir - make spelling - working-directory: ./doc + python3 -c 'from osgeo import gdal' + ctest -V -R spelling --output-on-failure + working-directory: build diff --git a/.readthedocs.yaml b/.readthedocs.yaml index cf89aec5477d..b6c01d0a096d 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -15,7 +15,6 @@ build: - (git --no-pager log --pretty="tformat:%s -- %b" -1 | paste -s -d " " | grep -viqP "skip ci|ci skip") || exit 183 pre_build: - ./doc/rtd/pre_build.sh - - cd doc && make doxygen apt_packages: - ant diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index a41405f330d3..3af0e82e5ae9 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -2,23 +2,19 @@ find_package(Doxygen) find_program(SPHINX_BUILD sphinx-build) -find_program(MAKE_EXECUTABLE make) -if (UNIX - AND (NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + +if ((NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") AND DOXYGEN_FOUND - AND SPHINX_BUILD - AND MAKE_EXECUTABLE) + AND SPHINX_BUILD) set(BUILD_DOCS_DEFAULT ON) else() set(BUILD_DOCS_DEFAULT OFF) endif() -option(BUILD_DOCS "Set to ON to define documentation targets: 'html', 'latexpdf', 'man', 'doxygen', 'doxygen_check_warnings', 'spelling', 'clean_doc'" ${BUILD_DOCS_DEFAULT}) + +option(BUILD_DOCS "Set to ON to define documentation targets: 'html', 'latexpdf', 'man', 'doxygen_xml', 'doxygen_html' " ${BUILD_DOCS_DEFAULT}) if (BUILD_DOCS) - if (NOT UNIX) - message(FATAL_ERROR "BUILD_DOCS=ON requires a UNIX environment") - endif() if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") message(FATAL_ERROR "BUILD_DOCS=ON not compatible of in-source builds (CMAKE_SOURCE_DIR=CMAKE_BINARY_DIR)") endif() @@ -28,49 +24,145 @@ if (BUILD_DOCS) if (NOT SPHINX_BUILD) message(FATAL_ERROR "BUILD_DOCS=ON requires sphinx-build") endif() - if (NOT MAKE_EXECUTABLE) - message(FATAL_ERROR "BUILD_DOCS=ON requires 'make' executable") - endif() - set(DOC_BUILDDIR "${CMAKE_CURRENT_BINARY_DIR}/build") - - add_custom_target( - doxygen - COMMAND ${MAKE_EXECUTABLE} doxygen BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - doxygen_check_warnings - COMMAND ${MAKE_EXECUTABLE} doxygen_check_warnings BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - html - COMMAND ${MAKE_EXECUTABLE} html BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - latexpdf - COMMAND ${MAKE_EXECUTABLE} latexpdf BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - man - COMMAND ${MAKE_EXECUTABLE} man BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - spelling - COMMAND ${MAKE_EXECUTABLE} spelling BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - clean_doc - COMMAND ${MAKE_EXECUTABLE} clean BUILDDIR=${DOC_BUILDDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - set_property( - TARGET clean_doc - APPEND - PROPERTY ADDITIONAL_CLEAN_FILES ${DOC_BUILDDIR}) + #################################################################################################### + # Sphinx configuration + #################################################################################################### + + # Determine environment variables so that Sphinx can load the gdal Python module without installing it. + include(GdalSetRuntimeEnv) + gdal_set_runtime_env(PYTHON_RUN_ENV) + + set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/build) + set(SPHINX_BUILD_OPTS "--jobs=auto" "--fail-on-warning" "--show-traceback") + file(MAKE_DIRECTORY ${SPHINX_BUILD_DIR}) + file(MAKE_DIRECTORY ${SPHINX_BUILD_DIR}/html_extra) + + file(GLOB_RECURSE SPHINX_SOURCE_FILES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/source/**/*.rst + ${CMAKE_CURRENT_SOURCE_DIR}/source/**/*.py) + + #################################################################################################### + # Doxygen XML and HTML outputs + #################################################################################################### + + # Create a dependency between source files and Doxygen + # This is more aggressive than needed, because we only build Doxygen for a subset of the source tree + file(GLOB_RECURSE DOXYGEN_SOURCE_FILES CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/**/*.cpp) + + # Use configure_file to copy the Doxygen file into our build directory. + # This causes CMake to re-run if the contents of the Doxyfile change. + configure_file(${CMAKE_SOURCE_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_base) + + # Read the contents of the copied Doxyfile, so that we can write modified versions + # for XML and HTML outputs + file(READ ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_base DOXYFILE_CONTENTS) + + # Doxygen XML outputs + # TODO replacement? + string(JOIN "\n" DOXYFILE_XML_CONTENTS + ${DOXYFILE_CONTENTS} + "FAIL_ON_WARNINGS=YES" + "WARN_AS_ERROR=FAIL_ON_WARNINGS_PRINT" + "GENERATE_HTML=NO" + "GENERATE_XML=YES" + "XML_OUTPUT=${SPHINX_BUILD_DIR}/xml" + "XML_PROGRAMLISTING=NO" + "PREDEFINED+=DOXYGEN_XML" + ) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_xml ${DOXYFILE_XML_CONTENTS}) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doxygen_xml.stamp + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_xml ${DOXYGEN_SOURCE_FILES} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_xml + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/doxygen_xml.stamp + ) + + add_custom_target(doxygen_xml + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doxygen_xml.stamp + ) + + # Doxygen HTML outputs + string(JOIN "\n" DOXYFILE_HTML_CONTENTS + "${DOXYFILE_CONTENTS}" + "FAIL_ON_WARNINGS=YES" + "WARN_AS_ERROR=FAIL_ON_WARNINGS_PRINT" + "HTML_OUTPUT=${SPHINX_BUILD_DIR}/html_extra/doxygen" + "INLINE_INHERITED_MEMB=YES" + ) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_html ${DOXYFILE_HTML_CONTENTS}) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doxygen_html.stamp + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_html ${DOXYGEN_SOURCE_FILES} + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_html + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/doxygen_html.stamp + ) + add_custom_target(doxygen_html + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doxygen_html.stamp + ) + + #################################################################################################### + # Sphinx outputs + #################################################################################################### + + # Sphinx HTML documentation + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html.stamp" + DEPENDS doxygen_xml python_binding + ${SPHINX_SOURCE_FILES} + COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} + ${SPHINX_BUILD} -M html + ${CMAKE_CURRENT_SOURCE_DIR}/source + ${CMAKE_CURRENT_BINARY_DIR}/build + ${SPHINX_BUILD_OPTS} + COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/html.stamp" + ) + + add_custom_target(html + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/html.stamp + ) + + # Sphinx PDF documentation + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/build/gdal.pdf + DEPENDS ${SPHINX_SOURCE_FILES} + COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${SPHINX_BUILD_DIR} + ${SPHINX_BUILD} -M latexpdf + ${CMAKE_CURRENT_SOURCE_DIR}/source + ${CMAKE_CURRENT_BINARY_DIR}/build + ${SPHINX_BUILD_OPTS} + ) + + add_custom_target(latexpdf DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/build/gdal.pdf) + + # Sphinx manpage documentation + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/man.stamp" + DEPENDS ${SPHINX_SOURCE_FILES} + COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${SPHINX_BUILD_DIR} + ${SPHINX_BUILD} -M man + ${CMAKE_CURRENT_SOURCE_DIR}/source + ${CMAKE_CURRENT_BINARY_DIR}/build + ${SPHINX_BUILD_OPTS} + COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/man.stamp" + ) + + add_custom_target(man DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/man.stamp) + + #################################################################################################### + # Documentation tests + #################################################################################################### + + # Spell check + add_test(NAME doc-spelling + COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} + ${SPHINX_BUILD} -b spelling + ${CMAKE_CURRENT_SOURCE_DIR}/source + ${CMAKE_CURRENT_BINARY_DIR}/build + ${SPHINX_BUILD_OPTS} + -D html_extra_path=extra_path + ) + endif () diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index ba8426fcf24d..000000000000 --- a/doc/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -PYTHON ?= python3 -SPHINXOPTS ?= --keep-going -j auto -W -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Use O="-D enable_redirects=1" with "make html" to create redirects - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile clean doxygen - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -doxygen: - $(MAKE) -B $(BUILDDIR)/.doxygen_up_to_date - -# Target run by the CI code_checks.yml workflow to check that there are no Doxygen warnings -# Requires Doxygen >= 1.9.3 -doxygen_check_warnings: - @echo "Checking that Doxygen runs without warnings..." - @$(MAKE) -B $(BUILDDIR)/.doxygen_up_to_date > /tmp/doxygen_gdal_log.txt 2>&1 - @if grep "warning:" /tmp/doxygen_gdal_log.txt; then \ - echo "Doxygen warnings found!"; \ - echo "---------"; \ - echo "Full log:"; \ - echo "---------"; \ - cat /tmp/doxygen_gdal_log.txt; \ - echo ""; \ - echo "--------------------"; \ - echo "Extract of warnings:"; \ - echo "--------------------"; \ - grep "warning:" /tmp/doxygen_gdal_log.txt; \ - echo "-----------------------"; \ - echo "Doxygen warnings found!"; \ - /bin/false; \ - else \ - echo "No Doxygen warnings found"; \ - fi - -$(BUILDDIR)/.doxygen_up_to_date: - @set -e ; \ - case $(BUILDDIR) in \ - "/"*) \ - BUILDDIR_ABS="$(BUILDDIR)"; \ - ;; \ - *) \ - BUILDDIR_ABS="${PWD}/$(BUILDDIR)" \ - ;; \ - esac; \ - rm -rf $(BUILDDIR)/xml; \ - mkdir -p $(BUILDDIR)/xml; \ - (cd .. && ((cat Doxyfile | sed "s/PREDEFINED = /PREDEFINED = DOXYGEN_XML /"; printf "GENERATE_HTML=NO\nGENERATE_XML=YES\nXML_OUTPUT=$$BUILDDIR_ABS/xml\nXML_PROGRAMLISTING=NO") | doxygen -)); \ - rm -rf $(BUILDDIR)/html_extra/doxygen; \ - mkdir -p $(BUILDDIR)/html_extra/doxygen; \ - (cd .. && ((cat Doxyfile; printf "HTML_OUTPUT=$$BUILDDIR_ABS/html_extra/doxygen\nINLINE_INHERITED_MEMB=YES") | doxygen -)); \ - echo "Doxygen replaces -- with . This is not desirable, so revert that;"; \ - for i in $(BUILDDIR)/xml/*.xml; do sed "s//--/g" < $$i > $$i.tmp; mv $$i.tmp $$i; done; \ - touch $(BUILDDIR)/.doxygen_up_to_date - - -.PHONY: html latexpdf -html: $(BUILDDIR)/.doxygen_up_to_date - BUILDDIR="${BUILDDIR}" $(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - ln -sf ../latex/gdal.pdf $(BUILDDIR)/html - -man: - BUILDDIR="${BUILDDIR}" $(SPHINXBUILD) -M man "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -latexpdf: - BUILDDIR="${BUILDDIR}" $(SPHINXBUILD) -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -spelling: $(BUILDDIR)/.doxygen_up_to_date - BUILDDIR="${BUILDDIR}" $(SPHINXBUILD) -b spelling "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -clean: - rm -rf "$(BUILDDIR)/xml" - rm -rf "$(BUILDDIR)/html_extra/doxygen" - rm -f "$(BUILDDIR)/.doxygen_up_to_date" - @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/requirements.txt b/doc/requirements.txt index da22d12e3326..3e0ab5e19607 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -9,6 +9,7 @@ sphinx-markdown-tables sphinx_rtd_theme sphinxcontrib-bibtex sphinxcontrib-jquery +sphinx-rtd-theme >= 3.0.0 # We use a slightly forked version # sphinxcontrib-programoutput sphinxcontrib-spelling diff --git a/doc/rtd/pre_build.sh b/doc/rtd/pre_build.sh index 3faeba2ffb56..35e397b1b706 100755 --- a/doc/rtd/pre_build.sh +++ b/doc/rtd/pre_build.sh @@ -22,6 +22,7 @@ cmake \ .. cmake --build . -j$(nproc) +cmake --build . --target doxygen_xml doxygen_html cmake --install . # set rpath for python libraries @@ -34,6 +35,10 @@ python3 -c "from osgeo import gdal; print(gdal.__version__)" mkdir -p ../doc/build/html_extra unzip -d ../doc/build/html_extra swig/java/javadoc.zip +# copy doxygen outputs into source tree +cp -r doc/build/xml ../doc/build +cp -r doc/build/html_extra/doxygen ../doc/build/html_extra + # copy gdalicon.png into html_extra (used by test suite) cp ../data/gdalicon.png ../doc/build/html_extra/ diff --git a/doc/source/conf.py b/doc/source/conf.py index 6b08257ad38e..69f49843141d 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -15,6 +15,10 @@ import shutil import sys +build_dir = os.environ.get("BUILDDIR", "../build") +if build_dir == "build": + build_dir = "../build" + sys.path.insert(0, os.path.abspath("_extensions")) @@ -167,7 +171,7 @@ def check_python_bindings(): html_static_path = ["_static"] # For generated content and robots.txt -html_extra_path = ["../build/html_extra", "extra_path"] +html_extra_path = [os.path.join(build_dir, "html_extra"), "extra_path"] # If true, links to the reST sources are added to the pages. html_show_sourcelink = False @@ -727,9 +731,6 @@ def check_python_bindings(): # Setup the breathe extension -build_dir = os.environ.get("BUILDDIR", "../build") -if build_dir == "build": - build_dir = "../build" breathe_projects = {"api": os.path.join(build_dir, "xml")} breathe_default_project = "api" diff --git a/ogr/Doxyfile b/ogr/Doxyfile deleted file mode 100644 index 41422c130392..000000000000 --- a/ogr/Doxyfile +++ /dev/null @@ -1,1241 +0,0 @@ -# Doxyfile 1.4.2 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = OGR - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, -# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, -# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, -# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, -# Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behavior. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behavior instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. - -SHOW_DIRECTORIES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . \ - ogrsf_frmts \ - ogrsf_frmts/generic \ - ogrsf_frmts/geojson/ogrgeojsonwriter.cpp \ - ogrsf_frmts/kml/ogr2kmlgeometry.cpp \ - ../port - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm - -FILE_PATTERNS = *.h \ - *.cpp \ - *.c \ - *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = . - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. -# -# http://trac.osgeo.org/gdal/ticket/2723 - -REFERENCES_LINK_SOURCE = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = ../doc/gdal_footer.html - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = HAVE_DLFCN_H \ - CPL_DLL \ - CPL_C_START \ - CPL_C_END \ - __cplusplus \ - DOXYGEN_SKIP \ - HAVE_CURL - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = CPL_PRINT_FUNC_FORMAT - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/local/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO From 60da6b2078d57c18d31925d8dfa9439f67794e76 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Mar 2025 10:27:18 -0400 Subject: [PATCH 07/17] Doc build: Add doczip CMake target, replacing build_doc_snapshot.sh --- HOWTO-RELEASE | 14 +++++++------- doc/CMakeLists.txt | 36 +++++++++++++++++++++++++++++++----- doc/build_doc_snapshot.sh | 31 ------------------------------- 3 files changed, 38 insertions(+), 43 deletions(-) delete mode 100755 doc/build_doc_snapshot.sh diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE index dc39dea92af4..cc93f7e5ef71 100644 --- a/HOWTO-RELEASE +++ b/HOWTO-RELEASE @@ -90,8 +90,12 @@ Process : If make is not GNU make, e.g., export MAKE=gmake + ant used for building Javadocs + doxygen + jdk used for building Javadocs + python available as "python", or e.g. export PYTHON=python3.9 python3 available as "python3" in path (export PYTHON=python3.9 @@ -128,13 +132,9 @@ Process : 12.2) Create a snapshot of the documentation (only for feature releases) - 1. Refresh - https://download.osgeo.org/gdal/for_doc/javadoc.zip - by building the Java bindings, with -DGDAL_JAVA_GENERATE_JAVADOC=ON. - javadoc.zip is in the swig/java subdirectory of the build directory. - 2. cd doc - 3. ./build_doc_snapshot 310 - This generates gdal310doc.zip + 1. From the build directory, run + cmake --build . --target doczip + This generates doc/gdal3110doc.zip 12.3) Publish the resulting files on download.osgeo.org, in /osgeo/download/gdal/X.Y.Z (where X.Y.Z is the version number) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 3af0e82e5ae9..72c03bd6db00 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -34,7 +34,7 @@ if (BUILD_DOCS) gdal_set_runtime_env(PYTHON_RUN_ENV) set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/build) - set(SPHINX_BUILD_OPTS "--jobs=auto" "--fail-on-warning" "--show-traceback") + set(SPHINX_BUILD_OPTS "--jobs=auto" "--show-traceback") file(MAKE_DIRECTORY ${SPHINX_BUILD_DIR}) file(MAKE_DIRECTORY ${SPHINX_BUILD_DIR}/html_extra) @@ -115,8 +115,9 @@ if (BUILD_DOCS) COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} ${SPHINX_BUILD} -M html ${CMAKE_CURRENT_SOURCE_DIR}/source - ${CMAKE_CURRENT_BINARY_DIR}/build + ${SPHINX_BUILD_DIR} ${SPHINX_BUILD_OPTS} + "--fail-on-warning" COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/html.stamp" ) @@ -125,17 +126,17 @@ if (BUILD_DOCS) ) # Sphinx PDF documentation + set(GDAL_DOC_PDF ${CMAKE_CURRENT_BINARY_DIR}/build/latex/gdal.pdf) add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/build/gdal.pdf + OUTPUT ${GDAL_DOC_PDF} DEPENDS ${SPHINX_SOURCE_FILES} COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${SPHINX_BUILD_DIR} ${SPHINX_BUILD} -M latexpdf ${CMAKE_CURRENT_SOURCE_DIR}/source ${CMAKE_CURRENT_BINARY_DIR}/build - ${SPHINX_BUILD_OPTS} ) - add_custom_target(latexpdf DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/build/gdal.pdf) + add_custom_target(latexpdf DEPENDS ${GDAL_DOC_PDF}) # Sphinx manpage documentation add_custom_command( @@ -151,6 +152,31 @@ if (BUILD_DOCS) add_custom_target(man DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/man.stamp) + #################################################################################################### + # Packaged documentation (e.g. "gdal3100doc.zip") + #################################################################################################### + + string(REPLACE "." "" _GDAL_VERSION_NO_DOTS ${GDAL_VERSION_NO_DEV_SUFFIX}) + set(DOC_ZIP "gdal${_GDAL_VERSION_NO_DOTS}doc.zip") + + # The Javadoc path is copied from swig/java/CMakeLists.txt, which hasn't been read + # at the time this is executed. + set(JAVADOC_ZIP ${CMAKE_CURRENT_BINARY_DIR}/../swig/java/javadoc.zip) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${DOC_ZIP} + DEPENDS ${GDAL_DOC_PDF} + ${CMAKE_CURRENT_BINARY_DIR}/html.stamp + java_binding ${JAVADOC_ZIP} + COMMAND ${CMAKE_COMMAND} -E make_directory gdaldoc + COMMAND ${CMAKE_COMMAND} -E make_directory gdaldoc/java + COMMAND ${CMAKE_COMMAND} -E chdir gdaldoc/java ${CMAKE_COMMAND} -E tar x ${JAVADOC_ZIP} --format=zip + COMMAND ${CMAKE_COMMAND} -E copy ${GDAL_DOC_PDF} gdaldoc/gdal.pdf + COMMAND ${CMAKE_COMMAND} -E copy_directory ${SPHINX_BUILD_DIR}/html gdaldoc + COMMAND ${CMAKE_COMMAND} -E tar c ${DOC_ZIP} --format=zip gdaldoc) + + add_custom_target(doczip DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOC_ZIP}) + #################################################################################################### # Documentation tests #################################################################################################### diff --git a/doc/build_doc_snapshot.sh b/doc/build_doc_snapshot.sh deleted file mode 100755 index 4d6805ccc1c9..000000000000 --- a/doc/build_doc_snapshot.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -set -eu - -TAG=$1 - -ARCHIVE="gdal${TAG}doc.zip" -echo "Building ${ARCHIVE}..." - -TMPDIR=gdaldoc - -rm -f .doxygen_up_to_date -rm -rf build/html -rm -rf build/latex -make html -make latexpdf - -rm -rf "${TMPDIR}" -mkdir ${TMPDIR} -cp -r build/html/* ${TMPDIR} -rm -f ${TMPDIR}/gdal.pdf -cp build/latex/gdal.pdf ${TMPDIR} -ORIG_DIR=$PWD -cd ${TMPDIR} -wget https://download.osgeo.org/gdal/for_doc/javadoc.zip -O /tmp/javadoc.zip -unzip -q /tmp/javadoc.zip -cd ${ORIG_DIR} - -rm -f "${ARCHIVE}" -zip -r "${ARCHIVE}" ${TMPDIR}/* -rm -rf "${TMPDIR}" From efc7eaf138574132d090ea3b0033e7155843427a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Mar 2025 11:40:41 -0400 Subject: [PATCH 08/17] Doc build: Require apps to build docs --- doc/CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 72c03bd6db00..3c987054adac 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -31,7 +31,7 @@ if (BUILD_DOCS) # Determine environment variables so that Sphinx can load the gdal Python module without installing it. include(GdalSetRuntimeEnv) - gdal_set_runtime_env(PYTHON_RUN_ENV) + gdal_set_runtime_env(BUILD_RUN_ENV) set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/build) set(SPHINX_BUILD_OPTS "--jobs=auto" "--show-traceback") @@ -110,9 +110,9 @@ if (BUILD_DOCS) # Sphinx HTML documentation add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html.stamp" - DEPENDS doxygen_xml python_binding + DEPENDS gdalapps doxygen_xml python_binding ${SPHINX_SOURCE_FILES} - COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} + COMMAND ${CMAKE_COMMAND} -E env ${BUILD_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} ${SPHINX_BUILD} -M html ${CMAKE_CURRENT_SOURCE_DIR}/source ${SPHINX_BUILD_DIR} @@ -129,8 +129,8 @@ if (BUILD_DOCS) set(GDAL_DOC_PDF ${CMAKE_CURRENT_BINARY_DIR}/build/latex/gdal.pdf) add_custom_command( OUTPUT ${GDAL_DOC_PDF} - DEPENDS ${SPHINX_SOURCE_FILES} - COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${SPHINX_BUILD_DIR} + DEPENDS gdalapps doxygen_xml ${SPHINX_SOURCE_FILES} + COMMAND ${CMAKE_COMMAND} -E env ${BUILD_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} ${SPHINX_BUILD} -M latexpdf ${CMAKE_CURRENT_SOURCE_DIR}/source ${CMAKE_CURRENT_BINARY_DIR}/build @@ -141,8 +141,8 @@ if (BUILD_DOCS) # Sphinx manpage documentation add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/man.stamp" - DEPENDS ${SPHINX_SOURCE_FILES} - COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${SPHINX_BUILD_DIR} + DEPENDS gdalapps doxygen_xml ${SPHINX_SOURCE_FILES} + COMMAND ${CMAKE_COMMAND} -E env ${BUILD_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} ${SPHINX_BUILD} -M man ${CMAKE_CURRENT_SOURCE_DIR}/source ${CMAKE_CURRENT_BINARY_DIR}/build @@ -183,7 +183,7 @@ if (BUILD_DOCS) # Spell check add_test(NAME doc-spelling - COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} + COMMAND ${CMAKE_COMMAND} -E env ${BUILD_RUN_ENV} BUILDDIR=${SPHINX_BUILD_DIR} ${SPHINX_BUILD} -b spelling ${CMAKE_CURRENT_SOURCE_DIR}/source ${CMAKE_CURRENT_BINARY_DIR}/build From 1806ba8e1f17669d585f250efe11282f14a48743 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Mar 2025 11:41:02 -0400 Subject: [PATCH 09/17] mkgdaldist.sh: Use CMake to build man pages --- mkgdaldist.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mkgdaldist.sh b/mkgdaldist.sh index a47aaeab4c26..63fa0d762440 100755 --- a/mkgdaldist.sh +++ b/mkgdaldist.sh @@ -141,11 +141,17 @@ CWD=${PWD} # echo "* Generating man pages..." -(cd doc; SPHINXOPTS='--keep-going -j auto' make man) +mkdir cmake-build-man +cmake -DCMAKE_BUILD_TYPE=Debug \ + -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \ + -DOGR_BUILD_OPTIONAL_DRIVERS=OFF \ + -DBUILD_APPS=ON \ + -DBUILD_TESTING=OFF \ + -B cmake-build-man -S . +cmake --build cmake-build-man --target man mkdir -p man/man1 -cp doc/build/man/*.1 man/man1 -rm -rf doc/build -rm -f doc/.doxygen_up_to_date +cp cmake-build-man/doc/build/man/*.1 man/man1 +rm -rf cmake-build-man if test ! -f "man/man1/gdalinfo.1"; then echo " make man failed" From 8456bb6fda84e5b16372bcc874cd285bdd643738 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Mar 2025 11:59:21 -0400 Subject: [PATCH 10/17] mkgdaldist.sh: Build doc snapshot with man pages to avoid building GDAL twice --- HOWTO-RELEASE | 10 ++-------- mkgdaldist.sh | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE index cc93f7e5ef71..fb68467106cf 100644 --- a/HOWTO-RELEASE +++ b/HOWTO-RELEASE @@ -109,7 +109,7 @@ Process : md5sum (GNU version) in path (not a POSIX requirement) -12.1) Create the source distributions using the mkgdaldist.sh script. +12.1) Create the source distributions and documentation snapshot using the mkgdaldist.sh script. The argument should be the version number (i.e. 1.4.2). As our process involves doing betas or RCs, use the -rc option so that the filenames include this information (after promotion to official release, filename renaming will have @@ -130,13 +130,7 @@ Process : a previous release (diff -Nur gdal-3.0.1 gdal-3.0.2). This is more easily doable for a bugfix release. -12.2) Create a snapshot of the documentation (only for feature releases) - - 1. From the build directory, run - cmake --build . --target doczip - This generates doc/gdal3110doc.zip - -12.3) Publish the resulting files on download.osgeo.org, +12.2) Publish the resulting files on download.osgeo.org, in /osgeo/download/gdal/X.Y.Z (where X.Y.Z is the version number) with ~/.ssh/config containing: diff --git a/mkgdaldist.sh b/mkgdaldist.sh index 63fa0d762440..5eb6127ae31f 100755 --- a/mkgdaldist.sh +++ b/mkgdaldist.sh @@ -137,24 +137,28 @@ rm -rf ci CWD=${PWD} # -# Generate man pages +# Generate man pages and doc snapshot # -echo "* Generating man pages..." +echo "* Generating man pages and doc snapshot..." -mkdir cmake-build-man +mkdir cmake-build-doc cmake -DCMAKE_BUILD_TYPE=Debug \ -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \ -DOGR_BUILD_OPTIONAL_DRIVERS=OFF \ -DBUILD_APPS=ON \ -DBUILD_TESTING=OFF \ - -B cmake-build-man -S . -cmake --build cmake-build-man --target man + -DBUILD_PYTHON_BINDINGS=ON \ + -DBUILD_JAVA_BINDINGS=ON \ + -DGDAL_JAVA_GENERATE_JAVADOC=ON \ + -B cmake-build-doc -S . +cmake --build cmake-build-doc --target man doczip mkdir -p man/man1 -cp cmake-build-man/doc/build/man/*.1 man/man1 -rm -rf cmake-build-man +cp cmake-build-doc/doc/build/man/*.1 man/man1 +cp cmake-build-doc/doc/gdal${COMPRESSED_VERSION}doc.zip . +rm -rf cmake-build-doc if test ! -f "man/man1/gdalinfo.1"; then - echo " make man failed" + echo " man build failed" fi cd "$CWD" From 63ed9d4a46b016f84b6375be0b8e7edcd6c50c62 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 18 Mar 2025 18:20:31 +0100 Subject: [PATCH 11/17] mask.py: pytest.mark.parametize a test --- autotest/gcore/mask.py | 47 +++++++++++------------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/autotest/gcore/mask.py b/autotest/gcore/mask.py index 999da3cb1589..75c32386e412 100755 --- a/autotest/gcore/mask.py +++ b/autotest/gcore/mask.py @@ -531,7 +531,9 @@ def test_mask_14(): # Test creation of internal TIFF overview, mask band and mask band of overview -def mask_and_ovr(order, method): +@pytest.mark.parametrize("order", [1, 2, 3, 4]) +@pytest.mark.parametrize("method", ["NEAR", "AVERAGE"]) +def test_mask_and_ovr(order, method): src_ds = gdal.Open("data/byte.tif") @@ -544,8 +546,15 @@ def mask_and_ovr(order, method): if order == 1: ds.CreateMaskBand(gdal.GMF_PER_DATASET) ds.BuildOverviews(method, overviewlist=[2, 4]) - ds.GetRasterBand(1).GetOverview(0).CreateMaskBand(gdal.GMF_PER_DATASET) - ds.GetRasterBand(1).GetOverview(1).CreateMaskBand(gdal.GMF_PER_DATASET) + with gdal.quiet_errors(): + assert ( + ds.GetRasterBand(1).GetOverview(0).CreateMaskBand(gdal.GMF_PER_DATASET) + == gdal.CE_Failure + ) + assert ( + ds.GetRasterBand(1).GetOverview(1).CreateMaskBand(gdal.GMF_PER_DATASET) + == gdal.CE_Failure + ) elif order == 2: ds.BuildOverviews(method, overviewlist=[2, 4]) ds.CreateMaskBand(gdal.GMF_PER_DATASET) @@ -594,38 +603,6 @@ def mask_and_ovr(order, method): drv.Delete("tmp/byte_with_ovr_and_mask.tif") -def test_mask_15(): - return mask_and_ovr(1, "NEAREST") - - -def test_mask_16(): - return mask_and_ovr(2, "NEAREST") - - -def test_mask_17(): - return mask_and_ovr(3, "NEAREST") - - -def test_mask_18(): - return mask_and_ovr(4, "NEAREST") - - -def test_mask_15_avg(): - return mask_and_ovr(1, "AVERAGE") - - -def test_mask_16_avg(): - return mask_and_ovr(2, "AVERAGE") - - -def test_mask_17_avg(): - return mask_and_ovr(3, "AVERAGE") - - -def test_mask_18_avg(): - return mask_and_ovr(4, "AVERAGE") - - ############################################################################### # Test NODATA_VALUES mask From 3b9f06127d569e720f36194e26ad3592ec5e21d4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 18 Mar 2025 18:34:58 +0100 Subject: [PATCH 12/17] gcore: add more explicit error message when attempting to write an implicit mask band Fixes #11973 --- autotest/gcore/mask.py | 59 ++++++++++++++++++++++++++++++ autotest/gdrivers/vrtwarp.py | 22 +++++++++++ frmts/vrt/vrtdataset.h | 3 ++ frmts/vrt/vrtwarped.cpp | 20 ++++++++++ gcore/gdal_priv.h | 16 ++++++++ gcore/gdalallvalidmaskband.cpp | 14 +++++++ gcore/gdalnodatamaskband.cpp | 14 +++++++ gcore/gdalnodatavaluesmaskband.cpp | 14 +++++++ gcore/gdalrasterband.cpp | 45 ++++++++++++++++------- gcore/gdalrescaledalphaband.cpp | 13 +++++++ 10 files changed, 206 insertions(+), 14 deletions(-) diff --git a/autotest/gcore/mask.py b/autotest/gcore/mask.py index 75c32386e412..b5dad850f8d4 100755 --- a/autotest/gcore/mask.py +++ b/autotest/gcore/mask.py @@ -1010,3 +1010,62 @@ def test(): test() else: test() + + +############################################################################### + + +@gdaltest.enable_exceptions() +def test_mask_write_to_all_valid_mask_band(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + with pytest.raises( + Exception, + match=r"GDALRasterBand::Fill\(\): attempt to write to an all-valid implicit mask band.", + ): + ds.GetRasterBand(1).GetMaskBand().Fill(0) + with pytest.raises( + Exception, + match=r"GDALRasterBand::RasterIO\(\): attempt to write to an all-valid implicit mask band.", + ): + ds.GetRasterBand(1).GetMaskBand().WriteRaster(0, 0, 1, 1, b"\0") + + +############################################################################### + + +@gdaltest.enable_exceptions() +def test_mask_write_to_nodata_mask_band(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + ds.GetRasterBand(1).SetNoDataValue(0) + with pytest.raises( + Exception, + match=r"GDALRasterBand::Fill\(\): attempt to write to a nodata implicit mask band.", + ): + ds.GetRasterBand(1).GetMaskBand().Fill(0) + with pytest.raises( + Exception, + match=r"GDALRasterBand::RasterIO\(\): attempt to write to a nodata implicit mask band.", + ): + ds.GetRasterBand(1).GetMaskBand().WriteRaster(0, 0, 1, 1, b"\0") + + +############################################################################### + + +@gdaltest.enable_exceptions() +def test_mask_write_to_nodata_values_mask_band(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 2) + ds.SetMetadataItem("NODATA_VALUES", "0 0") + with pytest.raises( + Exception, + match=r"GDALRasterBand::Fill\(\): attempt to write to a nodata implicit mask band.", + ): + ds.GetRasterBand(1).GetMaskBand().Fill(0) + with pytest.raises( + Exception, + match=r"GDALRasterBand::RasterIO\(\): attempt to write to a nodata implicit mask band.", + ): + ds.GetRasterBand(1).GetMaskBand().WriteRaster(0, 0, 1, 1, b"\0") diff --git a/autotest/gdrivers/vrtwarp.py b/autotest/gdrivers/vrtwarp.py index b5f424d3b42b..47008e95c577 100755 --- a/autotest/gdrivers/vrtwarp.py +++ b/autotest/gdrivers/vrtwarp.py @@ -782,3 +782,25 @@ def test_vrtwarp_add_band_gdt_unknown(): vrt_ds = gdal.AutoCreateWarpedVRT(ds) with pytest.raises(Exception, match="Illegal GDT_Unknown/GDT_TypeCount argument"): vrt_ds.AddBand(gdal.GDT_Unknown) + + +############################################################################### + + +@gdaltest.enable_exceptions() +def test_vrtwarp_write_to_band(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 1, gdal.GDT_Byte) + ds.SetGeoTransform([0, 1, 0, 0, 0, -1]) + ds.GetRasterBand(1).SetNoDataValue(-9999) + vrt_ds = gdal.AutoCreateWarpedVRT(ds) + with pytest.raises( + Exception, + match=r"GDALRasterBand::Fill\(\): attempt to write to a VRTWarpedRasterBand.", + ): + vrt_ds.GetRasterBand(1).Fill(0) + with pytest.raises( + Exception, + match=r"GDALRasterBand::RasterIO\(\): attempt to write to a VRTWarpedRasterBand.", + ): + vrt_ds.GetRasterBand(1).WriteRaster(0, 0, 1, 1, b"\0") diff --git a/frmts/vrt/vrtdataset.h b/frmts/vrt/vrtdataset.h index b827eb036f30..782c0da7c469 100644 --- a/frmts/vrt/vrtdataset.h +++ b/frmts/vrt/vrtdataset.h @@ -1090,6 +1090,9 @@ class CPL_DLL VRTWarpedRasterBand final : public VRTRasterBand virtual int GetOverviewCount() override; virtual GDALRasterBand *GetOverview(int) override; + bool + EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override; + private: int m_nIRasterIOCounter = 0; //! Protects against infinite recursion inside IRasterIO() diff --git a/frmts/vrt/vrtwarped.cpp b/frmts/vrt/vrtwarped.cpp index 77c9b332861d..d4798caa8b58 100644 --- a/frmts/vrt/vrtwarped.cpp +++ b/frmts/vrt/vrtwarped.cpp @@ -2286,6 +2286,26 @@ CPLErr VRTWarpedRasterBand::IWriteBlock(int nBlockXOff, int nBlockYOff, return CE_None; } +/************************************************************************/ +/* EmitErrorMessageIfWriteNotSupported() */ +/************************************************************************/ + +bool VRTWarpedRasterBand::EmitErrorMessageIfWriteNotSupported( + const char *pszCaller) const +{ + VRTWarpedDataset *poWDS = static_cast(poDS); + // Cf comment in IWriteBlock() + if (poWDS->m_poWarper->GetOptions()->nDstAlphaBand != nBand) + { + ReportError(CE_Failure, CPLE_NoWriteAccess, + "%s: attempt to write to a VRTWarpedRasterBand.", + pszCaller); + + return true; + } + return false; +} + /************************************************************************/ /* GetBestOverviewLevel() */ /************************************************************************/ diff --git a/gcore/gdal_priv.h b/gcore/gdal_priv.h index a4327b666a04..2327a719983b 100644 --- a/gcore/gdal_priv.h +++ b/gcore/gdal_priv.h @@ -1670,6 +1670,10 @@ class CPL_DLL GDALRasterBand : public GDALMajorObject virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize, int nMaskFlagStop, double *pdfDataPct); + + virtual bool + EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const; + //! @cond Doxygen_Suppress CPLErr OverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, @@ -2006,6 +2010,9 @@ class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; + bool + EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override; + CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand) public: @@ -2050,6 +2057,9 @@ class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand GDALDataType, GSpacing, GSpacing, GDALRasterIOExtraArg *psExtraArg) override; + bool + EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override; + public: explicit GDALNoDataMaskBand(GDALRasterBand *); explicit GDALNoDataMaskBand(GDALRasterBand *, double dfNoDataValue); @@ -2081,6 +2091,9 @@ class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand protected: CPLErr IReadBlock(int, int, void *) override; + bool + EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override; + public: explicit GDALNoDataValuesMaskBand(GDALDataset *); ~GDALNoDataValuesMaskBand() override; @@ -2113,6 +2126,9 @@ class GDALRescaledAlphaBand : public GDALRasterBand GDALDataType, GSpacing, GSpacing, GDALRasterIOExtraArg *psExtraArg) override; + bool + EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override; + public: explicit GDALRescaledAlphaBand(GDALRasterBand *); ~GDALRescaledAlphaBand() override; diff --git a/gcore/gdalallvalidmaskband.cpp b/gcore/gdalallvalidmaskband.cpp index b34bee6a18c4..b482f0bad6fe 100644 --- a/gcore/gdalallvalidmaskband.cpp +++ b/gcore/gdalallvalidmaskband.cpp @@ -82,6 +82,20 @@ CPLErr GDALAllValidMaskBand::IRasterIO(GDALRWFlag eRWFlag, int, int, int, int, return CE_None; } +/************************************************************************/ +/* EmitErrorMessageIfWriteNotSupported() */ +/************************************************************************/ + +bool GDALAllValidMaskBand::EmitErrorMessageIfWriteNotSupported( + const char *pszCaller) const +{ + ReportError(CE_Failure, CPLE_NoWriteAccess, + "%s: attempt to write to an all-valid implicit mask band.", + pszCaller); + + return true; +} + /************************************************************************/ /* GetMaskBand() */ /************************************************************************/ diff --git a/gcore/gdalnodatamaskband.cpp b/gcore/gdalnodatamaskband.cpp index 3805ff010390..cccbbeb0ba57 100644 --- a/gcore/gdalnodatamaskband.cpp +++ b/gcore/gdalnodatamaskband.cpp @@ -556,4 +556,18 @@ CPLErr GDALNoDataMaskBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, return CE_None; } +/************************************************************************/ +/* EmitErrorMessageIfWriteNotSupported() */ +/************************************************************************/ + +bool GDALNoDataMaskBand::EmitErrorMessageIfWriteNotSupported( + const char *pszCaller) const +{ + ReportError(CE_Failure, CPLE_NoWriteAccess, + "%s: attempt to write to a nodata implicit mask band.", + pszCaller); + + return true; +} + //! @endcond diff --git a/gcore/gdalnodatavaluesmaskband.cpp b/gcore/gdalnodatavaluesmaskband.cpp index 1843aa1b39f1..0cb02f1157b1 100644 --- a/gcore/gdalnodatavaluesmaskband.cpp +++ b/gcore/gdalnodatavaluesmaskband.cpp @@ -241,4 +241,18 @@ CPLErr GDALNoDataValuesMaskBand::IReadBlock(int nXBlockOff, int nYBlockOff, return CE_None; } +/************************************************************************/ +/* EmitErrorMessageIfWriteNotSupported() */ +/************************************************************************/ + +bool GDALNoDataValuesMaskBand::EmitErrorMessageIfWriteNotSupported( + const char *pszCaller) const +{ + ReportError(CE_Failure, CPLE_NoWriteAccess, + "%s: attempt to write to a nodata implicit mask band.", + pszCaller); + + return true; +} + //! @endcond diff --git a/gcore/gdalrasterband.cpp b/gcore/gdalrasterband.cpp index 3e26a211bfe0..2108415cba41 100644 --- a/gcore/gdalrasterband.cpp +++ b/gcore/gdalrasterband.cpp @@ -377,11 +377,8 @@ CPLErr GDALRasterBand::RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, eFlushBlockErr = CE_None; return eErr; } - if (CPL_UNLIKELY(eAccess != GA_Update)) + if (EmitErrorMessageIfWriteNotSupported("GDALRasterBand::RasterIO()")) { - ReportError(CE_Failure, CPLE_AppDefined, - "Write operation not permitted on dataset opened " - "in read-only mode"); return CE_Failure; } } @@ -1248,13 +1245,9 @@ CPLErr GDALRasterBand::WriteBlock(int nXBlockOff, int nYBlockOff, void *pImage) return (CE_Failure); } - if (eAccess == GA_ReadOnly) + if (EmitErrorMessageIfWriteNotSupported("GDALRasterBand::WriteBlock()")) { - ReportError(CE_Failure, CPLE_NoWriteAccess, - "Attempt to write to read only dataset in" - "GDALRasterBand::WriteBlock().\n"); - - return (CE_Failure); + return CE_Failure; } if (eFlushBlockErr != CE_None) @@ -1299,6 +1292,33 @@ CPLErr CPL_STDCALL GDALWriteBlock(GDALRasterBandH hBand, int nXOff, int nYOff, return (poBand->WriteBlock(nXOff, nYOff, pData)); } +/************************************************************************/ +/* EmitErrorMessageIfWriteNotSupported() */ +/************************************************************************/ + +/** + * Emit an error message if a write operation to this band is not supported. + * + * The base implementation will emit an error message if the access mode is + * read-only. Derived classes may implement it to provide a custom message. + * + * @param pszCaller Calling function. + * @return true if an error message has been emitted. + */ +bool GDALRasterBand::EmitErrorMessageIfWriteNotSupported( + const char *pszCaller) const +{ + if (eAccess == GA_ReadOnly) + { + ReportError(CE_Failure, CPLE_NoWriteAccess, + "%s: attempt to write to dataset opened in read-only mode.", + pszCaller); + + return true; + } + return false; +} + /************************************************************************/ /* GetActualBlockSize() */ /************************************************************************/ @@ -2079,11 +2099,8 @@ CPLErr GDALRasterBand::Fill(double dfRealValue, double dfImaginaryValue) // file.) // Check we can write to the file. - if (eAccess == GA_ReadOnly) + if (EmitErrorMessageIfWriteNotSupported("GDALRasterBand::Fill()")) { - ReportError(CE_Failure, CPLE_NoWriteAccess, - "Attempt to write to read only dataset in " - "GDALRasterBand::Fill()."); return CE_Failure; } diff --git a/gcore/gdalrescaledalphaband.cpp b/gcore/gdalrescaledalphaband.cpp index 4351cc66465e..fa1eb8acece4 100644 --- a/gcore/gdalrescaledalphaband.cpp +++ b/gcore/gdalrescaledalphaband.cpp @@ -126,4 +126,17 @@ CPLErr GDALRescaledAlphaBand::IRasterIO( nPixelSpace, nLineSpace, psExtraArg); } +/************************************************************************/ +/* EmitErrorMessageIfWriteNotSupported() */ +/************************************************************************/ + +bool GDALRescaledAlphaBand::EmitErrorMessageIfWriteNotSupported( + const char *pszCaller) const +{ + ReportError(CE_Failure, CPLE_NoWriteAccess, + "%s: attempt to write to a GDALRescaledAlphaBand.", pszCaller); + + return true; +} + //! @endcond From fd644368b86b6609fb7b9575266fbfbcd456b1d1 Mon Sep 17 00:00:00 2001 From: AbelPau Date: Tue, 18 Mar 2025 15:00:12 +0100 Subject: [PATCH 13/17] MiraMonVector: writting VRS in metadata file + error in the zMin, zMax values of the header --- .../miramon/mm_gdal_driver_structs.h | 3 ++ ogr/ogrsf_frmts/miramon/mm_wrlayr.c | 29 +++++++++++++++++++ ogr/ogrsf_frmts/miramon/ogrmiramonlayer.cpp | 24 +++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/ogr/ogrsf_frmts/miramon/mm_gdal_driver_structs.h b/ogr/ogrsf_frmts/miramon/mm_gdal_driver_structs.h index 84548492f338..1c51c74a4ebc 100644 --- a/ogr/ogrsf_frmts/miramon/mm_gdal_driver_structs.h +++ b/ogr/ogrsf_frmts/miramon/mm_gdal_driver_structs.h @@ -45,6 +45,7 @@ CPL_C_START // Necessary for compiling in GDAL project #define KEY_CreationDate "CreationDate" #define SECTION_SPATIAL_REFERENCE_SYSTEM "SPATIAL_REFERENCE_SYSTEM" #define SECTION_HORIZONTAL "HORIZONTAL" +#define SECTION_VERTICAL "VERTICAL" #define KEY_HorizontalSystemIdentifier "HorizontalSystemIdentifier" #define SECTION_TAULA_PRINCIPAL "TAULA_PRINCIPAL" #define KEY_IdGrafic "IdGrafic" @@ -291,6 +292,7 @@ struct MiraMonVectorMetaData char *pXUnit; // X units if pszSRS is empty. char *pYUnit; // Y units if pszSRS is empty. If Y units is empty, // X unit will be assigned as Y unit by default. + char *pZUnit; // In 3D cases, Z unit can be assigned. struct MMBoundingBox hBB; // Bounding box of the entire layer @@ -739,6 +741,7 @@ struct MiraMonVectLayerInfo // EPSG code of the spatial reference system. char *pSRS; int nSRS_EPSG; // Ref. system if has EPSG code. + char *pZUnit; // In case of 3D data, Z unit can be assigned. // Used to write the precision of the reserved fields in the DBF #define MM_SRS_LAYER_IS_UNKNOWN_TYPE 0 diff --git a/ogr/ogrsf_frmts/miramon/mm_wrlayr.c b/ogr/ogrsf_frmts/miramon/mm_wrlayr.c index d7f39050180b..16310ddc421b 100644 --- a/ogr/ogrsf_frmts/miramon/mm_wrlayr.c +++ b/ogr/ogrsf_frmts/miramon/mm_wrlayr.c @@ -2437,6 +2437,12 @@ int MMDestroyLayer(struct MiraMonVectLayerInfo *hMiraMonLayer) hMiraMonLayer->pSRS = nullptr; } + if (hMiraMonLayer->pZUnit) + { + free_function(hMiraMonLayer->pZUnit); + hMiraMonLayer->pZUnit = nullptr; + } + if (hMiraMonLayer->pMultRecordIndex) { free_function(hMiraMonLayer->pMultRecordIndex); @@ -4260,6 +4266,11 @@ static int MMCreateFeaturePolOrArc(struct MiraMonVectLayerInfo *hMiraMonLayer, if (pZDesc[pArcTopHeader->nElemCount].dfBBmaxz < *pZ) pZDesc[pArcTopHeader->nElemCount].dfBBmaxz = *pZ; + if (pMMArc->pZSection.ZHeader.dfBBminz > *pZ) + pMMArc->pZSection.ZHeader.dfBBminz = *pZ; + if (pMMArc->pZSection.ZHeader.dfBBmaxz < *pZ) + pMMArc->pZSection.ZHeader.dfBBmaxz = *pZ; + // Only one altitude (the same for all vertices) is written if (hMMFeature->bAllZHaveSameValue) break; @@ -4522,6 +4533,11 @@ static int MMCreateFeaturePoint(struct MiraMonVectLayerInfo *hMiraMonLayer, pZDescription[nElemCount].dfBBminz = *pZ; pZDescription[nElemCount].dfBBmaxz = *pZ; + if (hMiraMonLayer->MMPoint.pZSection.ZHeader.dfBBminz > *pZ) + hMiraMonLayer->MMPoint.pZSection.ZHeader.dfBBminz = *pZ; + if (hMiraMonLayer->MMPoint.pZSection.ZHeader.dfBBmaxz < *pZ) + hMiraMonLayer->MMPoint.pZSection.ZHeader.dfBBmaxz = *pZ; + // Specification ask for a negative number. pZDescription[nElemCount].nZCount = -1; if (nElemCount == 0) @@ -5686,6 +5702,7 @@ static int MMWriteMetadataFile(struct MiraMonVectorMetaData *hMMMD) if (hMMMD->ePlainLT != MM_LayerType_Node && hMMMD->ePlainLT != MM_LayerType_Pol) { + // SPATIAL_REFERENCE_SYSTEM:HORIZONTAL fprintf_function(pF, LineReturn "[%s:%s]" LineReturn, SECTION_SPATIAL_REFERENCE_SYSTEM, SECTION_HORIZONTAL); if (!ReturnMMIDSRSFromEPSGCodeSRS(hMMMD->pSRS, aMMIDSRS) && @@ -5711,6 +5728,17 @@ static int MMWriteMetadataFile(struct MiraMonVectorMetaData *hMMMD) hMMMD->pYUnit); } } + + // SPATIAL_REFERENCE_SYSTEM:VERTICAL + // Llegim les unitats del Sist. ref. vertical + if (hMMMD->pZUnit) + { + fprintf_function(pF, LineReturn "[%s:%s]" LineReturn, + SECTION_SPATIAL_REFERENCE_SYSTEM, + SECTION_VERTICAL); + fprintf_function(pF, "%s=%s" LineReturn, KEY_unitats, + hMMMD->pZUnit); + } } if (hMMMD->ePlainLT == MM_LayerType_Pol && hMMMD->aArcFile) @@ -5969,6 +5997,7 @@ static int MMWriteVectorMetadataFile(struct MiraMonVectLayerInfo *hMiraMonLayer, memset(&hMMMD, 0, sizeof(hMMMD)); hMMMD.ePlainLT = layerPlainType; hMMMD.pSRS = hMiraMonLayer->pSRS; + hMMMD.pZUnit = hMiraMonLayer->pZUnit; hMMMD.nMMLanguage = hMiraMonLayer->nMMLanguage; hMMMD.szLayerTitle = hMiraMonLayer->szLayerTitle; diff --git a/ogr/ogrsf_frmts/miramon/ogrmiramonlayer.cpp b/ogr/ogrsf_frmts/miramon/ogrmiramonlayer.cpp index eb495f7aa083..74471a95a78a 100644 --- a/ogr/ogrsf_frmts/miramon/ogrmiramonlayer.cpp +++ b/ogr/ogrsf_frmts/miramon/ogrmiramonlayer.cpp @@ -159,6 +159,30 @@ OGRMiraMonLayer::OGRMiraMonLayer(GDALDataset *poDS, const char *pszFilename, const char *pszAuthorityName = poSRS->GetAuthorityName(nullptr); const char *pszAuthorityCode = poSRS->GetAuthorityCode(nullptr); + // Reading Z units (in case of 3D vector file) + if (poSRS->GetAuthorityCode("VERT_CS") != nullptr) + { + const char *pszUnits = nullptr; + const double dfUnits = poSRS->GetLinearUnits(&pszUnits); + const auto IsAlmostEqual = [](double x, double y) + { return std::fabs(x - y) <= 1e-10; }; + if (pszUnits) + { + if (!strcmp(pszUnits, "metre") && IsAlmostEqual(dfUnits, 1)) + { + hMiraMonLayerPNT.pZUnit = strdup("m"); + hMiraMonLayerARC.pZUnit = strdup("m"); + hMiraMonLayerPOL.pZUnit = strdup("m"); + } + else + { + hMiraMonLayerPNT.pZUnit = strdup(pszUnits); + hMiraMonLayerARC.pZUnit = strdup(pszUnits); + hMiraMonLayerPOL.pZUnit = strdup(pszUnits); + } + } + } + if (pszAuthorityName && pszAuthorityCode && EQUAL(pszAuthorityName, "EPSG")) { From e8f6c09ca17d918d759c312a267f04164c193396 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 18 Mar 2025 20:20:06 +0100 Subject: [PATCH 14/17] gdal CLI subcommands: add a --help-doc hidden option used by program-output directives Fixes #11980 --- apps/gdalalg_raster_pipeline.cpp | 38 +++++- apps/gdalalg_raster_pipeline.h | 3 + apps/gdalalg_vector_pipeline.cpp | 38 +++++- apps/gdalalg_vector_pipeline.h | 3 + autotest/cpp/test_gdal_algorithm.cpp | 2 +- doc/source/programs/gdal.rst | 13 +- doc/source/programs/gdal_convert.rst | 20 +--- doc/source/programs/gdal_info.rst | 18 +-- doc/source/programs/gdal_raster.rst | 18 +-- doc/source/programs/gdal_raster_calc.rst | 4 +- doc/source/programs/gdal_raster_contour.rst | 43 +------ doc/source/programs/gdal_raster_edit.rst | 22 +--- doc/source/programs/gdal_raster_info.rst | 38 +----- doc/source/programs/gdal_raster_mosaic.rst | 32 +---- doc/source/programs/gdal_raster_overview.rst | 7 +- .../programs/gdal_raster_overview_add.rst | 26 +--- .../programs/gdal_raster_overview_delete.rst | 24 +--- doc/source/programs/gdal_raster_pipeline.rst | 81 ++----------- doc/source/programs/gdal_raster_reproject.rst | 37 +----- doc/source/programs/gdal_raster_resize.rst | 31 +---- doc/source/programs/gdal_raster_stack.rst | 31 +---- doc/source/programs/gdal_vector.rst | 14 +-- doc/source/programs/gdal_vector_clip.rst | 47 +------- doc/source/programs/gdal_vector_convert.rst | 31 +---- doc/source/programs/gdal_vector_filter.rst | 37 +----- doc/source/programs/gdal_vector_info.rst | 28 +---- doc/source/programs/gdal_vector_pipeline.rst | 113 ++---------------- doc/source/programs/gdal_vector_rasterize.rst | 53 +------- doc/source/programs/gdal_vector_select.rst | 37 +----- doc/source/programs/gdal_vector_sql.rst | 35 +----- gcore/gdalalgorithm.cpp | 52 ++++---- gcore/gdalalgorithm.h | 34 ++++++ 32 files changed, 181 insertions(+), 829 deletions(-) diff --git a/apps/gdalalg_raster_pipeline.cpp b/apps/gdalalg_raster_pipeline.cpp index d836f8bf57e1..c72e6efa3bc8 100644 --- a/apps/gdalalg_raster_pipeline.cpp +++ b/apps/gdalalg_raster_pipeline.cpp @@ -178,7 +178,14 @@ bool GDALRasterPipelineAlgorithm::ParseCommandLineArguments( { if (args.size() == 1 && (args[0] == "-h" || args[0] == "--help" || args[0] == "help" || args[0] == "--json-usage")) + { return GDALAlgorithm::ParseCommandLineArguments(args); + } + else if (args.size() == 1 && STARTS_WITH(args[0].c_str(), "--help-doc=")) + { + m_helpDocCategory = args[0].substr(strlen("--help-doc=")); + return GDALAlgorithm::ParseCommandLineArguments({"--help-doc"}); + } for (const auto &arg : args) { @@ -386,12 +393,40 @@ bool GDALRasterPipelineAlgorithm::ParseCommandLineArguments( std::string GDALRasterPipelineAlgorithm::GetUsageForCLI( bool shortUsage, const UsageOptions &usageOptions) const { + UsageOptions stepUsageOptions; + stepUsageOptions.isPipelineStep = true; + + if (!m_helpDocCategory.empty() && m_helpDocCategory != "main") + { + auto alg = GetStepAlg(m_helpDocCategory); + std::string ret; + if (alg) + { + alg->SetCallPath({m_helpDocCategory}); + alg->GetArg("help-doc")->Set(true); + return alg->GetUsageForCLI(shortUsage, stepUsageOptions); + } + else + { + fprintf(stderr, "ERROR: unknown pipeline step '%s'\n", + m_helpDocCategory.c_str()); + return CPLSPrintf("ERROR: unknown pipeline step '%s'\n", + m_helpDocCategory.c_str()); + } + } + std::string ret = GDALAlgorithm::GetUsageForCLI(shortUsage, usageOptions); if (shortUsage) return ret; ret += "\n is of the form: read [READ-OPTIONS] " "( ! [STEP-OPTIONS] )* ! write [WRITE-OPTIONS]\n"; + + if (m_helpDocCategory == "main") + { + return ret; + } + ret += '\n'; ret += "Example: 'gdal raster pipeline --progress ! read in.tif ! \\\n"; ret += " reproject --dst-crs=EPSG:32632 ! "; @@ -399,9 +434,6 @@ std::string GDALRasterPipelineAlgorithm::GetUsageForCLI( ret += '\n'; ret += "Potential steps are:\n"; - UsageOptions stepUsageOptions; - stepUsageOptions.isPipelineStep = true; - for (const std::string &name : m_stepRegistry.GetNames()) { auto alg = GetStepAlg(name); diff --git a/apps/gdalalg_raster_pipeline.h b/apps/gdalalg_raster_pipeline.h index 7129ac081908..ccef6b191d1a 100644 --- a/apps/gdalalg_raster_pipeline.h +++ b/apps/gdalalg_raster_pipeline.h @@ -107,6 +107,9 @@ class GDALRasterPipelineAlgorithm final { return m_outputDataset; } + + private: + std::string m_helpDocCategory{}; }; //! @endcond diff --git a/apps/gdalalg_vector_pipeline.cpp b/apps/gdalalg_vector_pipeline.cpp index f7a639c36b94..86176995b851 100644 --- a/apps/gdalalg_vector_pipeline.cpp +++ b/apps/gdalalg_vector_pipeline.cpp @@ -207,7 +207,14 @@ bool GDALVectorPipelineAlgorithm::ParseCommandLineArguments( { if (args.size() == 1 && (args[0] == "-h" || args[0] == "--help" || args[0] == "help" || args[0] == "--json-usage")) + { return GDALAlgorithm::ParseCommandLineArguments(args); + } + else if (args.size() == 1 && STARTS_WITH(args[0].c_str(), "--help-doc=")) + { + m_helpDocCategory = args[0].substr(strlen("--help-doc=")); + return GDALAlgorithm::ParseCommandLineArguments({"--help-doc"}); + } for (const auto &arg : args) { @@ -459,12 +466,40 @@ bool GDALVectorPipelineAlgorithm::ParseCommandLineArguments( std::string GDALVectorPipelineAlgorithm::GetUsageForCLI( bool shortUsage, const UsageOptions &usageOptions) const { + UsageOptions stepUsageOptions; + stepUsageOptions.isPipelineStep = true; + + if (!m_helpDocCategory.empty() && m_helpDocCategory != "main") + { + auto alg = GetStepAlg(m_helpDocCategory); + std::string ret; + if (alg) + { + alg->SetCallPath({m_helpDocCategory}); + alg->GetArg("help-doc")->Set(true); + return alg->GetUsageForCLI(shortUsage, stepUsageOptions); + } + else + { + fprintf(stderr, "ERROR: unknown pipeline step '%s'\n", + m_helpDocCategory.c_str()); + return CPLSPrintf("ERROR: unknown pipeline step '%s'\n", + m_helpDocCategory.c_str()); + } + } + std::string ret = GDALAlgorithm::GetUsageForCLI(shortUsage, usageOptions); if (shortUsage) return ret; ret += "\n is of the form: read [READ-OPTIONS] " "( ! [STEP-OPTIONS] )* ! write [WRITE-OPTIONS]\n"; + + if (m_helpDocCategory == "main") + { + return ret; + } + ret += '\n'; ret += "Example: 'gdal vector pipeline --progress ! read in.gpkg ! \\\n"; ret += " reproject --dst-crs=EPSG:32632 ! "; @@ -472,9 +507,6 @@ std::string GDALVectorPipelineAlgorithm::GetUsageForCLI( ret += '\n'; ret += "Potential steps are:\n"; - UsageOptions stepUsageOptions; - stepUsageOptions.isPipelineStep = true; - for (const std::string &name : m_stepRegistry.GetNames()) { auto alg = GetStepAlg(name); diff --git a/apps/gdalalg_vector_pipeline.h b/apps/gdalalg_vector_pipeline.h index 8bbf6f249f4c..8e5df1d82c27 100644 --- a/apps/gdalalg_vector_pipeline.h +++ b/apps/gdalalg_vector_pipeline.h @@ -110,6 +110,9 @@ class GDALVectorPipelineAlgorithm final { return m_outputDataset; } + + private: + std::string m_helpDocCategory{}; }; /************************************************************************/ diff --git a/autotest/cpp/test_gdal_algorithm.cpp b/autotest/cpp/test_gdal_algorithm.cpp index edaf85cd3756..3d44ab739d5c 100644 --- a/autotest/cpp/test_gdal_algorithm.cpp +++ b/autotest/cpp/test_gdal_algorithm.cpp @@ -2935,7 +2935,7 @@ TEST_F(test_gdal_algorithm, algorithm_c_api) char **argNames = GDALAlgorithmGetArgNames(hAlg.get()); ASSERT_NE(argNames, nullptr); - EXPECT_EQ(CSLCount(argNames), 13); + EXPECT_EQ(CSLCount(argNames), 14); CSLDestroy(argNames); EXPECT_EQ(GDALAlgorithmGetArg(hAlg.get(), "non_existing"), nullptr); diff --git a/doc/source/programs/gdal.rst b/doc/source/programs/gdal.rst index 972a12fafd6b..2feaff2444e1 100644 --- a/doc/source/programs/gdal.rst +++ b/doc/source/programs/gdal.rst @@ -15,18 +15,7 @@ gdal Synopsis -------- -.. code-block:: - - Usage: gdal - where is one of: - - convert: Convert a dataset (shortcut for 'gdal raster convert' or 'gdal vector convert'). - - info: Return information on a dataset (shortcut for 'gdal raster info' or 'gdal vector info'). - - pipeline: Execute a pipeline (shortcut for 'gdal vector pipeline'). - - raster: Raster commands. - - vector: Vector commands. - - 'gdal ' can also be used as a shortcut for 'gdal info '. - And 'gdal read ! ...' as a shortcut for 'gdal pipeline ! ...'. +.. program-output:: gdal --help-doc Examples -------- diff --git a/doc/source/programs/gdal_convert.rst b/doc/source/programs/gdal_convert.rst index 56914f51a7ba..384f12aa8808 100644 --- a/doc/source/programs/gdal_convert.rst +++ b/doc/source/programs/gdal_convert.rst @@ -18,25 +18,7 @@ Acts as a shortcut for :ref:`gdal_raster_convert_subcommand` or Synopsis -------- -.. code-block:: - - Usage: gdal convert [OPTIONS] - - Convert a dataset (shortcut for 'gdal raster convert' or 'gdal vector convert'). - - Positional arguments: - -i, --input Input raster, vector or multidimensional raster dataset [required] - -o, --output Output raster, vector or multidimensional raster dataset (created by algorithm) [required] - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - - For all options, run 'gdal raster convert --help' or 'gdal vector convert --help' +.. program-output:: gdal convert --help-doc Examples -------- diff --git a/doc/source/programs/gdal_info.rst b/doc/source/programs/gdal_info.rst index 80d01c0b9e95..d599f71d928d 100644 --- a/doc/source/programs/gdal_info.rst +++ b/doc/source/programs/gdal_info.rst @@ -18,23 +18,7 @@ Acts as a shortcut for :ref:`gdal_raster_info_subcommand` or Synopsis -------- -.. code-block:: - - Usage: gdal info [OPTIONS] - - Return information on a dataset (shortcut for 'gdal raster info' or 'gdal vector info'). - - Positional arguments: - -i, --input Input raster, vector or multidimensional raster dataset [required] - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - - Options: - -f, --of, --format, --output-format Output format. OUTPUT-FORMAT=json|text (default: json) - - For all options, run 'gdal raster info --help' or 'gdal vector info --help' +.. program-output:: gdal info --help-doc Examples -------- diff --git a/doc/source/programs/gdal_raster.rst b/doc/source/programs/gdal_raster.rst index 624ceb793467..c6c4c9f87382 100644 --- a/doc/source/programs/gdal_raster.rst +++ b/doc/source/programs/gdal_raster.rst @@ -15,23 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster - where is one of: - - calc: Perform raster algebra. - - clip: Clip a raster dataset. - - contour: Creates a vector contour from a raster elevation model (DEM). - - convert: Convert a raster dataset. - - edit: Edit a raster dataset. - - info: Return information on a raster dataset. - - mosaic: Build a mosaic, either virtual (VRT) or materialized. - - overview: Manage overviews of a raster dataset. - - pipeline: Process a raster dataset. - - reproject: Reproject a raster dataset. - - resize: Resize a raster dataset. - - stack: Combine together input bands into a multi-band output, either virtual (VRT) or materialized. - +.. program-output:: gdal raster --help-doc Available sub-commands ---------------------- diff --git a/doc/source/programs/gdal_raster_calc.rst b/doc/source/programs/gdal_raster_calc.rst index 0d1b8c6092cb..b6570dc9c98b 100644 --- a/doc/source/programs/gdal_raster_calc.rst +++ b/doc/source/programs/gdal_raster_calc.rst @@ -15,9 +15,7 @@ Synopsis -------- -.. program-output:: gdal raster calc --help - :ellipsis: -5 - +.. program-output:: gdal raster calc --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_contour.rst b/doc/source/programs/gdal_raster_contour.rst index 3fd9a4feda41..ef3f314c01ef 100644 --- a/doc/source/programs/gdal_raster_contour.rst +++ b/doc/source/programs/gdal_raster_contour.rst @@ -15,48 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster contour [OPTIONS] - - Creates a vector contour from a raster elevation model (DEM). - - Positional arguments: - -i, --input Input raster dataset [required] - -o, --output Output raster dataset (created by algorithm) [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - -b, --band Specify input band number (default: 1) - -l, --nln, --layer Layer name - --elevation-name Name of the elevation field - --min-name Name of the minimum elevation field - --max-name Name of the maximum elevation field - --3d Force production of 3D vectors instead of 2D - --srcnodata Input pixel value to treat as 'nodata' - --interval Elevation interval between contours - Mutually exclusive with --levels, --exp-base - --levels List of contour levels [may be repeated] - Mutually exclusive with --interval, --exp-base - -e, --exp-base Base for exponential contour level generation - Mutually exclusive with --interval, --levels - --off, --offset Offset to apply to contour levels - -p, --polygonize Create polygons instead of lines - --group-transactions Group n features per transaction (default 100 000) - --overwrite Whether overwriting existing output is allowed - - Advanced Options: - --oo, --open-option Open options [may be repeated] - --if, --input-format Input formats [may be repeated] +.. program-output:: gdal raster contour --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_edit.rst b/doc/source/programs/gdal_raster_edit.rst index 72b1d33f1b7e..354b12734673 100644 --- a/doc/source/programs/gdal_raster_edit.rst +++ b/doc/source/programs/gdal_raster_edit.rst @@ -15,27 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster edit [OPTIONS] - - Edit a raster dataset. - - Positional arguments: - --dataset Dataset (in-place updated) [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - - Options: - --crs Override CRS (without reprojection) - --bbox Bounding box as xmin,ymin,xmax,ymax - --metadata = Add/update dataset metadata item [may be repeated] - --unset-metadata Remove dataset metadata item [may be repeated] - +.. program-output:: gdal raster edit --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_info.rst b/doc/source/programs/gdal_raster_info.rst index 716b513ba1fc..f52fa3b4ca1c 100644 --- a/doc/source/programs/gdal_raster_info.rst +++ b/doc/source/programs/gdal_raster_info.rst @@ -15,43 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster info [OPTIONS] - - Return information on a raster dataset. - - Positional arguments: - -i, --input Input raster dataset [required] - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - - Options: - -f, --of, --format, --output-format Output format. OUTPUT-FORMAT=json|text (default: json) - --mm, --min-max Compute minimum and maximum value - --stats Retrieve or compute statistics, using all pixels - Mutually exclusive with --approx-stats - --approx-stats Retrieve or compute statistics, using a subset of pixels - Mutually exclusive with --stats - --hist Retrieve or compute histogram - - Advanced Options: - --oo, --open-option Open options [may be repeated] - --if, --input-format Input formats [may be repeated] - --no-gcp Suppress ground control points list printing - --no-md Suppress metadata printing - --no-ct Suppress color table printing - --no-fl Suppress file list printing - --checksum Compute pixel checksum - --list-mdd List all metadata domains available for the dataset - --mdd Report metadata for the specified domain. 'all' can be used to report metadata in all domains - - Esoteric Options: - --no-nodata Suppress retrieving nodata value - --no-mask Suppress mask band information - --subdataset Use subdataset of specified index (starting at 1), instead of the source dataset itself +.. program-output:: gdal raster info --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_mosaic.rst b/doc/source/programs/gdal_raster_mosaic.rst index abdf14d848a2..1539861ce2c2 100644 --- a/doc/source/programs/gdal_raster_mosaic.rst +++ b/doc/source/programs/gdal_raster_mosaic.rst @@ -15,37 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster mosaic [OPTIONS] - - Build a mosaic, either virtual (VRT) or materialized - - Positional arguments: - -i, --input Input raster datasets (or specify a @ to point to a file containing filenames) [1.. values] - -o, --output Output raster dataset (created by algorithm) [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - -b, --band Specify input band(s) number. [may be repeated] - --overwrite Whether overwriting existing output is allowed - --resolution ,|same|average|highest|lowest> Target resolution (in destination CRS units) (default: same) - --bbox Target bounding box as xmin,ymin,xmax,ymax (in destination CRS units) - --target-aligned-pixels Round target extent to target resolution - --srcnodata Set nodata values for input bands. [1.. values] - --dstnodata Set nodata values at the destination band level. [1.. values] - --hidenodata Makes the destination band not report the NoData. - --addalpha Adds an alpha mask band to the destination when the source raster have none. - +.. program-output:: gdal raster mosaic --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_overview.rst b/doc/source/programs/gdal_raster_overview.rst index ec7133c0caeb..b507f498733c 100644 --- a/doc/source/programs/gdal_raster_overview.rst +++ b/doc/source/programs/gdal_raster_overview.rst @@ -15,12 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster - where is one of: - - add: Adding overviews. - - delete: Deleting overviews. +.. program-output:: gdal raster overview --help-doc Available sub-commands ---------------------- diff --git a/doc/source/programs/gdal_raster_overview_add.rst b/doc/source/programs/gdal_raster_overview_add.rst index 0868d269ac35..3d470b0a91d2 100644 --- a/doc/source/programs/gdal_raster_overview_add.rst +++ b/doc/source/programs/gdal_raster_overview_add.rst @@ -15,31 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster overview add [OPTIONS] - - Adding overviews. - - Positional arguments: - --dataset Dataset (in-place updated, unless --external) [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - --external Add external overviews - -r, --resampling Resampling method. RESAMPLING=nearest|average|cubic|cubicspline|lanczos|bilinear|gauss|average_magphase|rms|mode - --levels Levels / decimation factors [may be repeated] - --min-size Maximum width or height of the smallest overview level. - - Advanced Options: - --oo, --open-option Open options [may be repeated] +.. program-output:: gdal raster overview add --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_overview_delete.rst b/doc/source/programs/gdal_raster_overview_delete.rst index 62844fa6c086..a4b12ef72c2e 100644 --- a/doc/source/programs/gdal_raster_overview_delete.rst +++ b/doc/source/programs/gdal_raster_overview_delete.rst @@ -15,29 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster overview delete [OPTIONS] - - Deleting overviews. - - Positional arguments: - --dataset Dataset (in-place updated, unless --external) [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - --external Remove external overviews - - Advanced Options: - --oo, --open-option Open options [may be repeated] - +.. program-output:: gdal raster overview delete --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_pipeline.rst b/doc/source/programs/gdal_raster_pipeline.rst index 0ac16a4a3692..d6491965bca7 100644 --- a/doc/source/programs/gdal_raster_pipeline.rst +++ b/doc/source/programs/gdal_raster_pipeline.rst @@ -15,21 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster pipeline [OPTIONS] - - Process a raster dataset. - - Positional arguments: - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - --progress Display progress bar - - is of the form: read [READ-OPTIONS] ( ! [STEP-OPTIONS] )* ! write [WRITE-OPTIONS] - +.. program-output:: gdal raster pipeline --help-doc=main A pipeline chains several steps, separated with the ``!`` (exclamation mark) character. The first step must be ``read``, and the last one ``write``. @@ -38,88 +24,35 @@ Potential steps are: * read [OPTIONS] -.. code-block:: - - Read a raster dataset. - - Positional arguments: - -i, --input Input raster dataset [required] - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] +.. program-output:: gdal raster pipeline --help-doc=read * clip [OPTIONS] -.. code-block:: - - Clip a raster dataset. - - Options: - --bbox Clipping bounding box as xmin,ymin,xmax,ymax - Mutually exclusive with --like - --bbox-crs CRS of clipping bounding box - --like Raster dataset to use as a template for bounds - Mutually exclusive with --bbox +.. program-output:: gdal raster pipeline --help-doc=clip Details for options can be found in :ref:`gdal_raster_clip_subcommand`. * edit [OPTIONS] -.. code-block:: - - Edit a raster dataset. - - Options: - --crs Override CRS (without reprojection) - --bbox Bounding box as xmin,ymin,xmax,ymax - --metadata = Add/update dataset metadata item [may be repeated] - --unset-metadata Remove dataset metadata item [may be repeated] +.. program-output:: gdal raster pipeline --help-doc=edit Details for options can be found in :ref:`gdal_raster_edit_subcommand`. * reproject [OPTIONS] -.. code-block:: - - Reproject a raster dataset. - - Options: - -s, --src-crs Source CRS - -d, --dst-crs Destination CRS - -r, --resampling Resampling method. RESAMPLING=near|bilinear|cubic|cubicspline|lanczos|average|rms|mode|min|max|med|q1|q3|sum (default: nearest) - --resolution , Target resolution (in destination CRS units) - --bbox ,,, Target bounding box (in destination CRS units) - --target-aligned-pixels Round target extent to target resolution +.. program-output:: gdal raster pipeline --help-doc=reproject Details for options can be found in :ref:`gdal_raster_reproject_subcommand`. * resize [OPTIONS] -.. code-block:: - - Resize a raster dataset without changing the georeferenced extents. - - Options: - --size , Target size in pixels [required] - -r, --resampling Resampling method. RESAMPLING=nearest|bilinear|cubic|cubicspline|lanczos|average|mode (default: nearest) +.. program-output:: gdal raster pipeline --help-doc=resize Details for options can be found in :ref:`gdal_raster_resize_subcommand`. * write [OPTIONS] -.. code-block:: - - Write a raster dataset. - - Positional arguments: - -o, --output Output raster dataset [required] - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - +.. program-output:: gdal raster pipeline --help-doc=write Description diff --git a/doc/source/programs/gdal_raster_reproject.rst b/doc/source/programs/gdal_raster_reproject.rst index c83b9bdff4a6..38b32caacb63 100644 --- a/doc/source/programs/gdal_raster_reproject.rst +++ b/doc/source/programs/gdal_raster_reproject.rst @@ -15,42 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster reproject [OPTIONS] - - Reproject a raster dataset. - - Positional arguments: - -i, --input Input raster dataset [required] - -o, --output Output raster dataset [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - -s, --src-crs Source CRS - -d, --dst-crs Destination CRS - -r, --resampling Resampling method. RESAMPLING=nearest|bilinear|cubic|cubicspline|lanczos|average|rms|mode|min|max|med|q1|q3|sum (default: nearest) - --resolution , Target resolution (in destination CRS units) - Mutually exclusive with --size - --size , Target size in pixels - Mutually exclusive with --resolution - --bbox ,,, Target bounding box (in destination CRS units) - --bbox-crs CRS of target bounding box - --target-aligned-pixels Round target extent to target resolution - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] - +.. program-output:: gdal raster reproject --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_resize.rst b/doc/source/programs/gdal_raster_resize.rst index 6f046ba7b49b..fb6d843f2b7b 100644 --- a/doc/source/programs/gdal_raster_resize.rst +++ b/doc/source/programs/gdal_raster_resize.rst @@ -15,36 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster resize [OPTIONS] - - Resize a raster dataset. - - Positional arguments: - -i, --input Input raster dataset [required] - -o, --output Output raster dataset [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --size , Target size in pixels [required] - -r, --resampling Resampling method. RESAMPLING=nearest|bilinear|cubic|cubicspline|lanczos|average|mode (default: nearest) - - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] - +.. program-output:: gdal raster resize --help-doc Description ----------- diff --git a/doc/source/programs/gdal_raster_stack.rst b/doc/source/programs/gdal_raster_stack.rst index 835a9945203c..e5dc512c1a6b 100644 --- a/doc/source/programs/gdal_raster_stack.rst +++ b/doc/source/programs/gdal_raster_stack.rst @@ -16,36 +16,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal raster stack [OPTIONS] - - Combine together input bands into a multi-band output, either virtual (VRT) or materialized. - - Positional arguments: - -i, --input Input raster datasets (or specify a @ to point to a file containing filenames) [1.. values] - -o, --output Output raster dataset (created by algorithm) [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - -b, --band Specify input band(s) number. [may be repeated] - --overwrite Whether overwriting existing output is allowed - --resolution ,|same|average|highest|lowest> Target resolution (in destination CRS units) (default: same) - --bbox Target bounding box as xmin,ymin,xmax,ymax (in destination CRS units) - --target-aligned-pixels Round target extent to target resolution - --srcnodata Set nodata values for input bands. [1.. values] - --dstnodata Set nodata values at the destination band level. [1.. values] - --hidenodata Makes the destination band not report the NoData. - +.. program-output:: gdal raster stack --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector.rst b/doc/source/programs/gdal_vector.rst index a23c830cc08d..e15420184fec 100644 --- a/doc/source/programs/gdal_vector.rst +++ b/doc/source/programs/gdal_vector.rst @@ -15,19 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector - where is one of: - - clip: Clip a vector dataset. - - convert: Convert a vector dataset. - - filter: Filter a vector dataset. - - info: Return information on a vector dataset. - - pipeline: Process a vector dataset. - - rasterize: Burns vector geometries into a raster. - - reproject: Reproject a vector dataset. - - select: Select a subset of fields from a vector dataset. - - sql: Apply SQL statement(s) to a dataset. +.. program-output:: gdal vector --help-doc Available sub-commands ---------------------- diff --git a/doc/source/programs/gdal_vector_clip.rst b/doc/source/programs/gdal_vector_clip.rst index b8d51e1da013..211630d4de90 100644 --- a/doc/source/programs/gdal_vector_clip.rst +++ b/doc/source/programs/gdal_vector_clip.rst @@ -15,52 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector clip [OPTIONS] - - Clip a vector dataset. - - Positional arguments: - -i, --input Input vector dataset [required] - -o, --output Output vector dataset [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -l, --layer, --input-layer Input layer name(s) [may be repeated] - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --lco, --layer-creation-option = Layer creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --update Whether to open existing dataset in update mode - --overwrite-layer Whether overwriting existing layer is allowed - --append Whether appending to existing layer is allowed - --output-layer Output layer name - --bbox Clipping bounding box as xmin,ymin,xmax,ymax - Mutually exclusive with --geometry, --like - --bbox-crs CRS of clipping bounding box - --geometry Clipping geometry (WKT or GeoJSON) - Mutually exclusive with --bbox, --like - --geometry-crs CRS of clipping geometry - --like Dataset to use as a template for bounds - Mutually exclusive with --bbox, --geometry - --like-sql SELECT statement to run on the 'like' dataset - --like-layer Name of the layer of the 'like' dataset - --like-where Expression for a WHERE SQL clause to run on the 'like' dataset - - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] - - +.. program-output:: gdal vector clip --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector_convert.rst b/doc/source/programs/gdal_vector_convert.rst index f475ecccc818..5894b2518a00 100644 --- a/doc/source/programs/gdal_vector_convert.rst +++ b/doc/source/programs/gdal_vector_convert.rst @@ -15,36 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector convert [OPTIONS] - - Convert a vector dataset. - - Positional arguments: - -i, --input Input vector dataset [required] - -o, --output Output vector dataset [required] - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --lco, --layer-creation-option = Layer creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --update Whether updating existing dataset is allowed - --overwrite-layer Whether overwriting existing layer is allowed - --append Whether appending to existing layer is allowed - -l, --layer, --input-layer Input layer name(s) [may be repeated] - --output-layer Output layer name - - Advanced Options: - --oo, --open-option Open options [may be repeated] - --if, --input-format Input formats [may be repeated] - +.. program-output:: gdal vector convert --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector_filter.rst b/doc/source/programs/gdal_vector_filter.rst index f8bac444d42f..37ecbfe12696 100644 --- a/doc/source/programs/gdal_vector_filter.rst +++ b/doc/source/programs/gdal_vector_filter.rst @@ -15,42 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector filter [OPTIONS] - - Clip a vector dataset. - - Positional arguments: - -i, --input Input vector dataset [required] - -o, --output Output vector dataset [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -l, --layer, --input-layer Input layer name(s) [may be repeated] - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --lco, --layer-creation-option = Layer creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --update Whether to open existing dataset in update mode - --overwrite-layer Whether overwriting existing layer is allowed - --append Whether appending to existing layer is allowed - --output-layer Output layer name - --bbox Bounding box as xmin,ymin,xmax,ymax - --where |@ Attribute query in a restricted form of the queries used in the SQL WHERE statement - --fields Selected fields [may be repeated] - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] - +.. program-output:: gdal vector filter --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector_info.rst b/doc/source/programs/gdal_vector_info.rst index b7feea6105ba..ea191a82d116 100644 --- a/doc/source/programs/gdal_vector_info.rst +++ b/doc/source/programs/gdal_vector_info.rst @@ -15,33 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector info [OPTIONS] - - Return information on a vector dataset. - - Positional arguments: - -i, --input Input vector dataset [required] - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - - Options: - -f, --of, --format, --output-format Output format. OUTPUT-FORMAT=json|text (default: json) - -l, --layer Layer name [may be repeated] - Mutually exclusive with --sql - --features List all features (beware of RAM consumption on large layers) - --sql Execute the indicated SQL statement and return the result - Mutually exclusive with --layer - --where |<@filename> Attribute query in a restricted form of the queries used in the SQL WHERE statement - --dialect SQL dialect - --update Open the dataset in update mode - - Advanced Options: - --oo, --open-option Open options [may be repeated] - --if, --input-format Input formats [may be repeated] +.. program-output:: gdal vector info --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector_pipeline.rst b/doc/source/programs/gdal_vector_pipeline.rst index eb542661bf5f..5f514fab9051 100644 --- a/doc/source/programs/gdal_vector_pipeline.rst +++ b/doc/source/programs/gdal_vector_pipeline.rst @@ -15,21 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector pipeline [OPTIONS] - - Process a vector dataset. - - Positional arguments: - - Common Options: - -h, --help Display help message and exit - --json-usage Display usage as JSON document and exit - --progress Display progress bar - - is of the form: read [READ-OPTIONS] ( ! [STEP-OPTIONS] )* ! write [WRITE-OPTIONS] - +.. program-output:: gdal vector pipeline --help-doc=main A pipeline chains several steps, separated with the ``!`` (exclamation mark) character. The first step must be ``read``, and the last one ``write``. @@ -38,122 +24,39 @@ Potential steps are: * read [OPTIONS] -.. code-block:: - - Read a vector dataset. - - Positional arguments: - -i, --input Input vector dataset [required] - - Options: - -l, --layer, --input-layer Input layer name(s) [may be repeated] - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] +.. program-output:: gdal vector pipeline --help-doc=read * clip [OPTIONS] -.. code-block:: - - Clip a vector dataset. - - Options: - --bbox Clipping bounding box as xmin,ymin,xmax,ymax - Mutually exclusive with --geometry, --like - --bbox-crs CRS of clipping bounding box - --geometry Clipping geometry (WKT or GeoJSON) - Mutually exclusive with --bbox, --like - --geometry-crs CRS of clipping geometry - --like Dataset to use as a template for bounds - Mutually exclusive with --bbox, --geometry - --like-sql SELECT statement to run on the 'like' dataset - --like-layer Name of the layer of the 'like' dataset - --like-where Expression for a WHERE SQL clause to run on the 'like' dataset - +.. program-output:: gdal vector pipeline --help-doc=clip Details for options can be found in :ref:`gdal_vector_clip_subcommand`. * filter [OPTIONS] -.. code-block:: - - Filter a vector dataset. - - Options: - --bbox Bounding box as xmin,ymin,xmax,ymax - --where |@ Attribute query in a restricted form of the queries used in the SQL WHERE statement - +.. program-output:: gdal vector pipeline --help-doc=filter Details for options can be found in :ref:`gdal_vector_filter_subcommand`. - * reproject [OPTIONS] -.. code-block:: - - Reproject a vector dataset. - - Options: - -s, --src-crs Source CRS - -d, --dst-crs Destination CRS [required] - +.. program-output:: gdal vector pipeline --help-doc=reproject * select [OPTIONS] -.. code-block:: - - Select a subset of fields from a vector dataset. - - Positional arguments: - --fields Fields to select (or exclude if --exclude) [may be repeated] [required] - - Options: - --exclude Exclude specified fields - Mutually exclusive with --ignore-missing-fields - --ignore-missing-fields Ignore missing fields - Mutually exclusive with --exclude - +.. program-output:: gdal vector pipeline --help-doc=select Details for options can be found in :ref:`gdal_vector_select_subcommand`. - * sql [OPTIONS] -.. code-block:: - - Apply SQL statement(s) to a dataset. - - Positional arguments: - --sql |@ SQL statement(s) [may be repeated] [required] - - Options: - -l, --output-layer Output layer name(s) [may be repeated] - --dialect SQL dialect (e.g. OGRSQL, SQLITE) - +.. program-output:: gdal vector pipeline --help-doc=sql Details for options can be found in :ref:`gdal_vector_sql_subcommand`. - * write [OPTIONS] -.. code-block:: - - Write a vector dataset. - - Positional arguments: - -o, --output Output vector dataset [required] - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --lco, --layer-creation-option = Layer creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --update Whether updating existing dataset is allowed - --overwrite-layer Whether overwriting existing layer is allowed - --append Whether appending to existing layer is allowed - -l, --output-layer Output layer name - +.. program-output:: gdal vector pipeline --help-doc=write Description ----------- diff --git a/doc/source/programs/gdal_vector_rasterize.rst b/doc/source/programs/gdal_vector_rasterize.rst index 57f2e1736b88..e2366a3d5c39 100644 --- a/doc/source/programs/gdal_vector_rasterize.rst +++ b/doc/source/programs/gdal_vector_rasterize.rst @@ -15,58 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector rasterize [OPTIONS] - - Burns vector geometries into a raster. - - Positional arguments: - -i, --input Input vector dataset [required] - -o, --output Output raster dataset [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - -b, --band The band(s) to burn values into [may be repeated] - --invert Invert the rasterization - --all-touched Enables the ALL_TOUCHED rasterization option - --burn Burn value [may be repeated] - -a, --attribute-name Attribute name - --3d Indicates that a burn value should be extracted from the Z values of the feature - --add Add to existing raster - -l, --layer, --layer-name Layer name - Mutually exclusive with --sql - --where SQL where clause - --sql SQL select statement - Mutually exclusive with --layer-name - --dialect SQL dialect - --nodata Assign a specified nodata value to output bands - --init Pre-initialize output bands with specified value [may be repeated] - --crs Override the projection for the output file - --transformer-option = Set a transformer option suitable to pass to GDALCreateGenImgProjTransformer2 [may be repeated] - --extent ,,, Set the target georeferenced extent [4 values] - --resolution , Set the target resolution [2 values] - Mutually exclusive with --size - --tap, --target-aligned-pixels (target aligned pixels) Align the coordinates of the extent of the output file to the values of the resolution - --size , Set the target size in pixels and lines [2 values] - Mutually exclusive with --resolution - --ot, --datatype, --output-data-type Output data type. OUTPUT-DATA-TYPE=Byte|Int8|UInt16|Int16|UInt32|Int32|UInt64|Int64|CInt16|CInt32|Float32|Float64|CFloat32|CFloat64 - --optimization Force the algorithm used (results are identical). OPTIMIZATION=AUTO|RASTER|VECTOR (default: AUTO) - --update Whether to open existing dataset in update mode - --overwrite Whether overwriting existing output is allowed - - Advanced Options: - --oo, --open-option Open options [may be repeated] - --if, --input-format Input formats [may be repeated] +.. program-output:: gdal vector rasterize --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector_select.rst b/doc/source/programs/gdal_vector_select.rst index 5d6f8d5a09b6..2d91d54136c3 100644 --- a/doc/source/programs/gdal_vector_select.rst +++ b/doc/source/programs/gdal_vector_select.rst @@ -15,42 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector select [OPTIONS] - - Positional arguments: - -i, --input Input vector dataset [required] - -o, --output Output vector dataset [required] - --fields Fields to select (or exclude if --exclude) [may be repeated] [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -l, --layer, --input-layer Input layer name(s) [may be repeated] - -f, --of, --format, --output-format Output format ("stream" allowed) - --co, --creation-option = Creation option [may be repeated] - --lco, --layer-creation-option = Layer creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --update Whether to open existing dataset in update mode - --overwrite-layer Whether overwriting existing layer is allowed - --append Whether appending to existing layer is allowed - --output-layer Output layer name - --exclude Exclude specified fields - Mutually exclusive with --ignore-missing-fields - --ignore-missing-fields Ignore missing fields - Mutually exclusive with --exclude - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] - +.. program-output:: gdal vector select --help-doc Description ----------- diff --git a/doc/source/programs/gdal_vector_sql.rst b/doc/source/programs/gdal_vector_sql.rst index 0b6424af70b8..db945fe88eb7 100644 --- a/doc/source/programs/gdal_vector_sql.rst +++ b/doc/source/programs/gdal_vector_sql.rst @@ -15,40 +15,7 @@ Synopsis -------- -.. code-block:: - - Usage: gdal vector sql [OPTIONS] |@ - - Apply SQL statement(s) to a dataset. - - Positional arguments: - -i, --input Input vector dataset [required] - -o, --output Output vector dataset [required] - --sql |@ SQL statement(s) [may be repeated] [required] - - Common Options: - -h, --help Display help message and exit - --version Display GDAL version and exit - --json-usage Display usage as JSON document and exit - --drivers Display driver list as JSON document and exit - --config = Configuration option [may be repeated] - --progress Display progress bar - - Options: - -f, --of, --format, --output-format Output format - --co, --creation-option = Creation option [may be repeated] - --lco, --layer-creation-option = Layer creation option [may be repeated] - --overwrite Whether overwriting existing output is allowed - --update Whether to open existing dataset in update mode - --overwrite-layer Whether overwriting existing layer is allowed - --append Whether appending to existing layer is allowed - --output-layer Output layer name(s) [may be repeated] - --dialect SQL dialect (e.g. OGRSQL, SQLITE) - - Advanced Options: - --if, --input-format Input formats [may be repeated] - --oo, --open-option Open options [may be repeated] - +.. program-output:: gdal vector sql --help-doc Description ----------- diff --git a/gcore/gdalalgorithm.cpp b/gcore/gdalalgorithm.cpp index 48d5438d4160..32f529a9ebaf 100644 --- a/gcore/gdalalgorithm.cpp +++ b/gcore/gdalalgorithm.cpp @@ -829,6 +829,10 @@ GDALAlgorithm::GDALAlgorithm(const std::string &name, .SetOnlyForCLI() .SetCategory(GAAC_COMMON) .AddAction([this]() { m_specialActionRequested = true; }); + AddArg("help-doc", 0, _("Display help message for use by documentation"), + &m_helpDocRequested) + .SetHidden() + .AddAction([this]() { m_specialActionRequested = true; }); AddArg("version", 0, _("Display GDAL version and exit"), &m_dummyBoolean) .SetOnlyForCLI() .SetCategory(GAAC_COMMON); @@ -2826,7 +2830,7 @@ bool GDALAlgorithm::Run(GDALProgressFunc pfnProgress, void *pProgressData) if (m_selectedSubAlg) return m_selectedSubAlg->Run(pfnProgress, pProgressData); - if (m_helpRequested) + if (m_helpRequested || m_helpDocRequested) { printf("%s", GetUsageForCLI(false).c_str()); /*ok*/ return true; @@ -2880,7 +2884,7 @@ GDALAlgorithm::GetArgNamesForCLI() const size_t maxOptLen = 0; for (const auto &arg : m_args) { - if (arg->IsHiddenForCLI()) + if (arg->IsHidden() || arg->IsHiddenForCLI()) continue; std::string opt; bool addComma = false; @@ -2947,7 +2951,7 @@ GDALAlgorithm::GetUsageForCLI(bool shortUsage, bool hasNonPositionals = false; for (const auto &arg : m_args) { - if (!arg->IsHiddenForCLI() && !arg->IsPositional()) + if (!arg->IsHidden() && !arg->IsHiddenForCLI() && !arg->IsPositional()) hasNonPositionals = true; } @@ -3158,7 +3162,8 @@ GDALAlgorithm::GetUsageForCLI(bool shortUsage, std::string otherArgs; for (const auto &otherArg : m_args) { - if (otherArg->IsHiddenForCLI() || otherArg.get() == arg) + if (otherArg->IsHidden() || otherArg->IsHiddenForCLI() || + otherArg.get() == arg) continue; if (otherArg->GetMutualExclusionGroup() == mutualExclusionGroup) @@ -3261,21 +3266,25 @@ GDALAlgorithm::GetUsageForCLI(bool shortUsage, osRet += '\n'; } - if (!m_helpURL.empty()) + if (!m_helpDocRequested) { - osRet += "\nFor more details, consult "; - osRet += GetHelpFullURL(); - osRet += '\n'; - } + if (!m_helpURL.empty()) + { + osRet += "\nFor more details, consult "; + osRet += GetHelpFullURL(); + osRet += '\n'; + } - if (!m_callPath.empty() && m_callPath[0] == "gdal") - { - osRet += "\nWARNING: the gdal command is provisionally provided as an " - "alternative interface to GDAL and OGR command line " - "utilities.\nThe project reserves the right to modify, " - "rename, reorganize, and change the behavior of the utility\n" - "until it is officially frozen in a future feature release of " - "GDAL.\n"; + if (!m_callPath.empty() && m_callPath[0] == "gdal") + { + osRet += + "\nWARNING: the gdal command is provisionally provided as an " + "alternative interface to GDAL and OGR command line " + "utilities.\nThe project reserves the right to modify, " + "rename, reorganize, and change the behavior of the utility\n" + "until it is officially frozen in a future feature release of " + "GDAL.\n"; + } } return osRet; @@ -3434,7 +3443,8 @@ std::string GDALAlgorithm::GetUsageAsJSON() const CPLJSONArray jArgs; for (const auto &arg : m_args) { - if (!arg->IsOnlyForCLI() && arg->IsInput() && !arg->IsOutput()) + if (!arg->IsHidden() && !arg->IsOnlyForCLI() && arg->IsInput() && + !arg->IsOutput()) jArgs.Add(ProcessArg(arg.get())); } oRoot.Add("input_arguments", jArgs); @@ -3444,7 +3454,8 @@ std::string GDALAlgorithm::GetUsageAsJSON() const CPLJSONArray jArgs; for (const auto &arg : m_args) { - if (!arg->IsOnlyForCLI() && !arg->IsInput() && arg->IsOutput()) + if (!arg->IsHidden() && !arg->IsOnlyForCLI() && !arg->IsInput() && + arg->IsOutput()) jArgs.Add(ProcessArg(arg.get())); } oRoot.Add("output_arguments", jArgs); @@ -3454,7 +3465,8 @@ std::string GDALAlgorithm::GetUsageAsJSON() const CPLJSONArray jArgs; for (const auto &arg : m_args) { - if (!arg->IsOnlyForCLI() && arg->IsInput() && arg->IsOutput()) + if (!arg->IsHidden() && !arg->IsOnlyForCLI() && arg->IsInput() && + arg->IsOutput()) jArgs.Add(ProcessArg(arg.get())); } oRoot.Add("input_output_arguments", jArgs); diff --git a/gcore/gdalalgorithm.h b/gcore/gdalalgorithm.h index 4b4341681f8c..99ad39143a18 100644 --- a/gcore/gdalalgorithm.h +++ b/gcore/gdalalgorithm.h @@ -705,6 +705,14 @@ class CPL_DLL GDALAlgorithmArgDecl final return *this; } + /** Declare that the argument is hidden. Default is no + */ + GDALAlgorithmArgDecl &SetHidden() + { + m_hidden = true; + return *this; + } + /** Indicate whether the value of the argument is read-only during the * execution of the algorithm. Default is true. */ @@ -900,6 +908,13 @@ class CPL_DLL GDALAlgorithmArgDecl final return m_hasDefaultValue; } + /** Return whether the argument is hidden. + */ + inline bool IsHidden() const + { + return m_hidden; + } + /** Return whether the argument must not be mentioned in CLI usage. * For example, "output-value" for "gdal raster info", which is only * meant when the algorithm is used from a non-CLI context. @@ -1018,6 +1033,7 @@ class CPL_DLL GDALAlgorithmArgDecl final bool m_required = false; bool m_positional = false; bool m_hasDefaultValue = false; + bool m_hidden = false; bool m_hiddenForCLI = false; bool m_onlyForCLI = false; bool m_isInput = true; @@ -1201,6 +1217,12 @@ class CPL_DLL GDALAlgorithmArg /* non-final */ return m_decl.HasDefaultValue(); } + /** Alias for GDALAlgorithmArgDecl::IsHidden() */ + inline bool IsHidden() const + { + return m_decl.IsHidden(); + } + /** Alias for GDALAlgorithmArgDecl::IsHiddenForCLI() */ inline bool IsHiddenForCLI() const { @@ -1599,6 +1621,13 @@ class CPL_DLL GDALInConstructionAlgorithmArg final : public GDALAlgorithmArg return *this; } + /** Alias for GDALAlgorithmArgDecl::SetHidden() */ + GDALInConstructionAlgorithmArg &SetHidden() + { + m_decl.SetHidden(); + return *this; + } + /** Alias for GDALAlgorithmArgDecl::SetHiddenForCLI() */ GDALInConstructionAlgorithmArg &SetHiddenForCLI(bool hiddenForCLI = true) { @@ -2010,6 +2039,7 @@ class CPL_DLL GDALAlgorithmRegistry { target->m_specialActionRequested = m_specialActionRequested; target->m_helpRequested = m_helpRequested; + target->m_helpDocRequested = m_helpDocRequested; target->m_JSONUsageRequested = m_JSONUsageRequested; return true; } @@ -2228,6 +2258,10 @@ class CPL_DLL GDALAlgorithmRegistry bool m_displayInJSONUsage = true; bool m_specialActionRequested = false; bool m_helpRequested = false; + + // Used by program-output directives in .rst files + bool m_helpDocRequested = false; + bool m_JSONUsageRequested = false; bool m_dummyBoolean = false; // Used for --version bool m_parseForAutoCompletion = false; From 58265dc0e181136c2c4724671674eba24caf1f33 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 18 Mar 2025 20:38:09 +0100 Subject: [PATCH 15/17] gdal C++ traditional utilities: add a --help-doc hidden option used by program-output directives Fixes #11980 --- apps/gdalargumentparser.cpp | 12 ++++++ apps/gdaltransform.cpp | 29 ++++++++----- apps/gnmanalyse.cpp | 12 +++++- apps/gnmmanage.cpp | 15 ++++++- doc/source/programs/gdal_create.rst | 16 +------ doc/source/programs/gdal_footprint.rst | 17 +------- doc/source/programs/gdal_rasterize.rst | 14 +----- doc/source/programs/gdal_translate.rst | 33 +------------- doc/source/programs/gdal_viewshed.rst | 13 +----- doc/source/programs/gdaladdo.rst | 11 +---- doc/source/programs/gdalinfo.rst | 10 +---- doc/source/programs/gdallocationinfo.rst | 11 +---- doc/source/programs/gdalmdiminfo.rst | 7 +-- doc/source/programs/gdalmdimtranslate.rst | 15 +------ doc/source/programs/gdaltindex.rst | 17 +------- doc/source/programs/gdaltransform.rst | 11 +---- doc/source/programs/gdalwarp.rst | 32 +------------- doc/source/programs/gnmanalyse.rst | 10 +---- doc/source/programs/gnmmanage.rst | 14 +----- doc/source/programs/nearblack.rst | 8 +--- doc/source/programs/ogr2ogr.rst | 52 +---------------------- doc/source/programs/ogrinfo.rst | 16 +------ doc/source/programs/ogrtindex.rst | 11 +---- 23 files changed, 74 insertions(+), 312 deletions(-) diff --git a/apps/gdalargumentparser.cpp b/apps/gdalargumentparser.cpp index f7e037827739..969b465d6b39 100644 --- a/apps/gdalargumentparser.cpp +++ b/apps/gdalargumentparser.cpp @@ -43,6 +43,18 @@ GDALArgumentParser::GDALArgumentParser(const std::string &program_name, }) .help(_("Shows short help message and exits.")); + // Used by program-output directives in .rst files + add_argument("--help-doc") + .flag() + .hidden() + .action( + [this](const auto &) + { + std::cout << usage() << std::endl; + std::exit(0); + }) + .help(_("Display help message for use by documentation.")); + add_argument("--long-usage") .flag() .action( diff --git a/apps/gdaltransform.cpp b/apps/gdaltransform.cpp index 7b77da3dd10e..9f514177fa02 100644 --- a/apps/gdaltransform.cpp +++ b/apps/gdaltransform.cpp @@ -34,20 +34,25 @@ /* Usage() */ /************************************************************************/ -static void Usage(bool bIsError, const char *pszErrorMsg = nullptr) +static void Usage(bool bIsError, const char *pszErrorMsg = nullptr, + bool bHelpDoc = false) { fprintf(bIsError ? stderr : stdout, "Usage: gdaltransform [--help] [--help-general]\n" - " [-i] [-s_srs ] [-t_srs ] [-to " - ">NAME>=]...\n" - " [-s_coord_epoch ] [-t_coord_epoch ]\n" - " [-ct ] [-order ] [-tps] [-rpc] [-geoloc] \n" - " [-gcp [elevation]]...\n" - " [-output_xy] [-E] [-field_sep ] [-ignore_extra_input]\n" - " [ []]\n" - "\n"); - + " [-i] [-s_srs ] [-t_srs ] " + "[-to >NAME>=]...\n" + " [-s_coord_epoch ] [-t_coord_epoch ]\n" + " [-ct ] [-order ] [-tps] [-rpc] [-geoloc] \n" + " [-gcp [elevation]]...\n" + " [-output_xy] [-E] [-field_sep ] " + "[-ignore_extra_input]\n" + " [ []]\n"); + + if (bHelpDoc) + exit(0); + + fprintf(bIsError ? stderr : stdout, "\n"); if (pszErrorMsg != nullptr) fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg); @@ -146,6 +151,10 @@ MAIN_START(argc, argv) { Usage(false); } + else if (EQUAL(argv[i], "--help-doc")) + { + Usage(false, nullptr, true); + } else if (EQUAL(argv[i], "-t_srs")) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); diff --git a/apps/gnmanalyse.cpp b/apps/gnmanalyse.cpp index a318dde69e21..d1b64dfc2c7b 100644 --- a/apps/gnmanalyse.cpp +++ b/apps/gnmanalyse.cpp @@ -29,7 +29,7 @@ enum operation /* Usage() */ /************************************************************************/ static void Usage(bool bIsError, const char *pszAdditionalMsg = nullptr, - bool bShort = true) + bool bShort = true, bool bHelpDoc = false) { fprintf( bIsError ? stderr : stdout, @@ -43,6 +43,11 @@ static void Usage(bool bIsError, const char *pszAdditionalMsg = nullptr, " [-dsco =]... [-lco =]...\n" " \n"); + if (bHelpDoc) + { + exit(0); + } + if (bShort) { printf("\nNote: gnmanalyse --long-usage for full help.\n"); @@ -411,6 +416,11 @@ MAIN_START(nArgc, papszArgv) Usage(false); } + else if (EQUAL(papszArgv[iArg], "--help-doc")) + { + Usage(false, nullptr, true, true); + } + else if (EQUAL(papszArgv[iArg], "--long-usage")) { Usage(false, nullptr, false); diff --git a/apps/gnmmanage.cpp b/apps/gnmmanage.cpp index bbfabe36f283..869a72a19d13 100644 --- a/apps/gnmmanage.cpp +++ b/apps/gnmmanage.cpp @@ -41,9 +41,10 @@ enum operation /************************************************************************/ static void Usage(bool bIsError, const char *pszAdditionalMsg = nullptr, - bool bShort = true) CPL_NO_RETURN; + bool bShort = true, bool bHelpDoc = false) CPL_NO_RETURN; -static void Usage(bool bIsError, const char *pszAdditionalMsg, bool bShort) +static void Usage(bool bIsError, const char *pszAdditionalMsg, bool bShort, + bool bHelpDoc) { fprintf( bIsError ? stderr : stdout, @@ -63,6 +64,11 @@ static void Usage(bool bIsError, const char *pszAdditionalMsg, bool bShort) " [change [-bl ][-unbl ][-unblall]]\n" " [ []...]\n"); + if (bHelpDoc) + { + exit(0); + } + if (bShort) { fprintf(bIsError ? stderr : stdout, @@ -229,6 +235,11 @@ MAIN_START(nArgc, papszArgv) Usage(false); } + else if (EQUAL(papszArgv[iArg], "--help-doc")) + { + Usage(false, nullptr, true, true); + } + else if (EQUAL(papszArgv[iArg], "--long-usage")) { Usage(false, nullptr, false); diff --git a/doc/source/programs/gdal_create.rst b/doc/source/programs/gdal_create.rst index 784520f11509..c667d196af4f 100644 --- a/doc/source/programs/gdal_create.rst +++ b/doc/source/programs/gdal_create.rst @@ -15,21 +15,7 @@ gdal_create Synopsis -------- -.. code-block:: - - - gdal_create [--help] [--help-general] - [-of ] - [-outsize ] - [-bands ] - [-burn ]... - [-ot {Byte/Int8/Int16/UInt16/UInt32/Int32/UInt64/Int64/Float32/Float64/ - CInt16/CInt32/CFloat32/CFloat64}] [-strict] - [-a_srs ] [-a_ullr ] [-a_nodata ] - [-mo =]... [-q] - [-co =]... - [-if ] - +.. program-output:: gdal_create --help-doc Description ----------- diff --git a/doc/source/programs/gdal_footprint.rst b/doc/source/programs/gdal_footprint.rst index 241fb813e743..f94309cc21c1 100644 --- a/doc/source/programs/gdal_footprint.rst +++ b/doc/source/programs/gdal_footprint.rst @@ -15,22 +15,7 @@ gdal_footprint Synopsis -------- -.. code-block:: - - - gdal_footprint [--help] [--help-general] - [-b ]... [-combine_bands union|intersection] - [-oo =]... [-ovr ] - [-srcnodata "[ ]..."] - [-t_cs pixel|georef] [-t_srs ] [-split_polys] - [-convex_hull] [-densify ] [-simplify ] - [-min_ring_area ] [-max_points |unlimited] - [-of ] [-lyr_name ] - [-location_field_name ] [-no_location] - [-write_absolute_path] - [-dsco =]... [-lco =]... [-overwrite] [-q] - - +.. program-output:: gdal_footprint --help-doc Description ----------- diff --git a/doc/source/programs/gdal_rasterize.rst b/doc/source/programs/gdal_rasterize.rst index 88df60b82762..e152759a456d 100644 --- a/doc/source/programs/gdal_rasterize.rst +++ b/doc/source/programs/gdal_rasterize.rst @@ -13,19 +13,7 @@ gdal_rasterize Synopsis -------- -.. code-block:: - - gdal_rasterize [--help] [--help-general] - [-b ]... [-i] [-at] - [-oo =]... - {[-burn ]... | [-a ] | [-3d]} [-add] - [-l ]... [-where ] [-sql |@] - [-dialect ] [-of ] [-a_srs ] [-to =]... - [-co =]... [-a_nodata ] [-init ]... - [-te ] [-tr ] [-tap] [-ts ] - [-ot {Byte/Int8/Int16/UInt16/UInt32/Int32/UInt64/Int64/Float32/Float64/ - CInt16/CInt32/CFloat32/CFloat64}] [-optim {AUTO|VECTOR|RASTER}] [-q] - +.. program-output:: gdal_rasterize --help-doc Description ----------- diff --git a/doc/source/programs/gdal_translate.rst b/doc/source/programs/gdal_translate.rst index 5e2c1d745c52..ba9777049099 100644 --- a/doc/source/programs/gdal_translate.rst +++ b/doc/source/programs/gdal_translate.rst @@ -13,38 +13,7 @@ gdal_translate Synopsis -------- -.. code-block:: - - gdal_translate [--help] [--long-usage] [--help-general] - [-ot Byte|Int8|[U]Int{16|32|64}|CInt{16|32}|[C]Float{32|64}] - [-if ]... [-of ] [--quiet] - [-b ]... [-mask ] [-expand gray|rgb|rgba] - [[-strict]|[-not_strict]] - [-outsize ] [-tr ] - [-ovr |AUTO|AUTO-|NONE] [-sds] - [-r nearest,bilinear,cubic,cubicspline,lanczos,average,mode] - [[-scale [ [ ]]]...| - [-scale_X [ [ ]]]...| - [-unscale]] - [[-exponent ]|[-exponent_X ]...] - [-srcwin ] - [-projwin ] - [-projwin_srs ] [-epo] [-eco] [-a_srs ] - [-a_coord_epoch ] [-a_ullr ] - [-a_nodata |none] - [-a_gt ] - [-a_scale ] [-a_offset ] [-nogcp] - [-gcp []]... - [-colorinterp {red|green|blue|alpha|gray|undefined|pan| - coastal|rededge|nir|swir|mwir|lwir|...},...] - [-colorinterp_X {red|green|blue|alpha|gray|undefined|pan| - coastal|rededge|nir|swir|mwir|lwir|...}]... - [[-stats]|[-approx_stats]] - [-norat] [-noxmp] [-co =]... - [-mo =]... [-dmo :=]... - [-oo =]... - - +.. program-output:: gdal_translate --help-doc Description ----------- diff --git a/doc/source/programs/gdal_viewshed.rst b/doc/source/programs/gdal_viewshed.rst index 365ad0fdb017..0dc64b7c1bd2 100644 --- a/doc/source/programs/gdal_viewshed.rst +++ b/doc/source/programs/gdal_viewshed.rst @@ -15,18 +15,7 @@ gdal_viewshed Synopsis -------- -.. code-block:: - - gdal_viewshed [--help] [--help-general] [-b ] - [-a_nodata ] [-f ] - [-oz ] [-tz ] [-md ] - -ox -oy - [-vv ] [-iv ] - [-ov ] [-cc ] - [-os ] [-j ] - [-co =]... - [-q] [-om ] - +.. program-output:: gdal_viewshed --help-doc Description ----------- diff --git a/doc/source/programs/gdaladdo.rst b/doc/source/programs/gdaladdo.rst index 9745d046a01f..786dbccdbcf6 100644 --- a/doc/source/programs/gdaladdo.rst +++ b/doc/source/programs/gdaladdo.rst @@ -13,16 +13,7 @@ gdaladdo Synopsis -------- -.. code-block:: - - gdaladdo [--help] [--help-general] - [-r {nearest|average|rms|gauss|bilinear|cubic|cubicspline| - lanczos|average_mp|average_magphase|mode}] - [-ro] [-clean] [-q] [-oo =]... [-minsize ] - [--partial-refresh-from-source-timestamp] - [--partial-refresh-from-projwin ] - [--partial-refresh-from-source-extent [,]...] - []... +.. program-output:: gdaladdo --help-doc Description ----------- diff --git a/doc/source/programs/gdalinfo.rst b/doc/source/programs/gdalinfo.rst index 6ccef3d6593a..78217b346351 100644 --- a/doc/source/programs/gdalinfo.rst +++ b/doc/source/programs/gdalinfo.rst @@ -13,15 +13,7 @@ gdalinfo Synopsis -------- -.. code-block:: - - gdalinfo [--help] [--help-general] - [-json] [-mm] [-stats | -approx_stats] [-hist] - [-nogcp] [-nomd] [-norat] [-noct] [-nofl] [-nonodata] [-nomask] - [-checksum] [-listmdd] [-mdd |all] - [-proj4] [-wkt_format {WKT1|WKT2|}]... - [-sd ] [-oo =]... [-if ]... - +.. program-output:: gdalinfo --help-doc Description ----------- diff --git a/doc/source/programs/gdallocationinfo.rst b/doc/source/programs/gdallocationinfo.rst index c89f5740fd6c..a1284426c866 100644 --- a/doc/source/programs/gdallocationinfo.rst +++ b/doc/source/programs/gdallocationinfo.rst @@ -13,16 +13,7 @@ gdallocationinfo Synopsis -------- -.. code-block:: - - Usage: gdallocationinfo [--help] [--help-general] - [-xml] [-lifonly] [-valonly] - [-E] [-field_sep ] [-ignore_extra_input] - [-b ]... [-overview ] - [-r {nearest|bilinear|cubic|cubicspline}] - [[-l_srs ] | [-geoloc] | [-wgs84]] - [-oo =]... [ ] - +.. program-output:: gdallocationinfo --help-doc Description ----------- diff --git a/doc/source/programs/gdalmdiminfo.rst b/doc/source/programs/gdalmdiminfo.rst index 57a8abc12d0c..3d5293d1e027 100644 --- a/doc/source/programs/gdalmdiminfo.rst +++ b/doc/source/programs/gdalmdiminfo.rst @@ -15,12 +15,7 @@ gdalmdiminfo Synopsis -------- -.. code-block:: - - gdalmdiminfo [--help] [--help-general] - [-oo =]... [-arrayoption =]... - [-detailed] [-nopretty] [-array ] [-limit ] - [-stats] [-if ]... +.. program-output:: gdalmdiminfo --help-doc Description ----------- diff --git a/doc/source/programs/gdalmdimtranslate.rst b/doc/source/programs/gdalmdimtranslate.rst index 9e1e814aa8c5..5ddad05b92ed 100644 --- a/doc/source/programs/gdalmdimtranslate.rst +++ b/doc/source/programs/gdalmdimtranslate.rst @@ -15,20 +15,7 @@ gdalmdimtranslate Synopsis -------- -.. code-block:: - - gdalmdimtranslate [--help] [--help-general] - [-if ]... [-of ] - [-co =]... - [-array ]... - [-arrayoption =]... - [-group ]... - [-subset ]... - [-scaleaxes ] - [-oo =]... - [-strict] - - +.. program-output:: gdalmdimtranslate --help-doc Description ----------- diff --git a/doc/source/programs/gdaltindex.rst b/doc/source/programs/gdaltindex.rst index b9908ef57c0a..f451d0e85816 100644 --- a/doc/source/programs/gdaltindex.rst +++ b/doc/source/programs/gdaltindex.rst @@ -13,22 +13,7 @@ gdaltindex Synopsis -------- -.. code-block:: - - gdaltindex [--help] [--help-general] - [-overwrite] [-recursive] [-filename_filter ]... - [-min_pixel_size ] [-max_pixel_size ] - [-f ] [-tileindex ] [-write_absolute_path] - [-skip_different_projection] [-t_srs ] - [-src_srs_name ] [-src_srs_format {AUTO|WKT|EPSG|PROJ}] - [-lyr_name ] [-lco =]... - [-gti_filename ] - [-tr ] [-te ] - [-ot ] [-bandcount ] [-nodata [,...]] - [-colorinterp [,...]] [-mask] - [-mo =]... - [-fetch_md ]... - []... +.. program-output:: gdaltindex --help-doc Description ----------- diff --git a/doc/source/programs/gdaltransform.rst b/doc/source/programs/gdaltransform.rst index 22eb21670c70..3a7f4d81f45b 100644 --- a/doc/source/programs/gdaltransform.rst +++ b/doc/source/programs/gdaltransform.rst @@ -13,16 +13,7 @@ gdaltransform Synopsis -------- -.. code-block:: - - gdaltransform [--help] [--help-general] - [-i] [-s_srs ] [-t_srs ] [-to =]... - [-s_coord_epoch ] [-t_coord_epoch ] - [-ct ] [-order ] [-tps] [-rpc] [-geoloc] - [-gcp [elevation]]... - [-output_xy] [-E] [-field_sep ] [-ignore_extra_input] - [ []] - +.. program-output:: gdaltransform --help-doc Description ----------- diff --git a/doc/source/programs/gdalwarp.rst b/doc/source/programs/gdalwarp.rst index 5c915c39d9a2..94d7499dff5b 100644 --- a/doc/source/programs/gdalwarp.rst +++ b/doc/source/programs/gdalwarp.rst @@ -13,37 +13,7 @@ gdalwarp Synopsis -------- -.. code-block:: - - gdalwarp [--help] [--long-usage] [--help-general] - [--quiet] [-overwrite] [-of ] - [-co =]... [-s_srs ] [-t_srs ] - [[-srcalpha]|[-nosrcalpha]] - [-dstalpha] [-tr |square] [-ts ] - [-te ] [-te_srs ] - [-r near|bilinear|cubic|cubicspline|lanczos|average|rms|mode| - min|max|med|q1|q3|sum] - [-ot Byte|Int8|[U]Int{16|32|64}|CInt{16|32}|[C]Float{32|64}] - ... - - Advanced options: - [-wo =]... [-multi] [-s_coord_epoch ] - [-t_coord_epoch ] [-ct ] - [[-tps]|[-rpc]|[-geoloc]] - [-order <1|2|3>] [-refine_gcps []] - [-to =]... [-et ] - [-wm ] [-srcnodata "[ ]..."] - [-dstnodata "[ ]..."] [-tap] - [-wt Byte|Int8|[U]Int{16|32|64}|CInt{16|32}|[C]Float{32|64}] - [-cutline |] [-cutline_srs ] - [-cwhere ] - [[-cl ]|[-csql ]] - [-cblend ] [-crop_to_cutline] [-nomd] - [-cvmd ] [-setci] [-oo =]... - [-doo =]... [-ovr |AUTO|AUTO-|NONE] - [[-vshift]|[-novshiftgrid]] - [-if ]... [-srcband ]... [-dstband ]... - +.. program-output:: gdalwarp --help-doc Description ----------- diff --git a/doc/source/programs/gnmanalyse.rst b/doc/source/programs/gnmanalyse.rst index 60ba5b215ada..8a288ff58b53 100644 --- a/doc/source/programs/gnmanalyse.rst +++ b/doc/source/programs/gnmanalyse.rst @@ -13,15 +13,7 @@ gnmanalyse Synopsis -------- -.. code-block:: - - gnmanalyse [--help] [--help-general] [-q] [-quiet] [--long-usage] - [dijkstra =]...] - [kpaths [-alo =]...] - [resource [-alo =]...] - [-ds ][-f ][-l ] - [-dsco =]... [-lco =]... - +.. program-output:: gnmanalyse --help-doc Description ----------- diff --git a/doc/source/programs/gnmmanage.rst b/doc/source/programs/gnmmanage.rst index 37414f0b7165..0e910fdc7f1c 100644 --- a/doc/source/programs/gnmmanage.rst +++ b/doc/source/programs/gnmmanage.rst @@ -13,19 +13,7 @@ gnmmanage Synopsis -------- -.. code-block:: - - gnmmanage [--help] [--help-general] [-q] [-quiet] [--long-usage] - [info] - [create [-f ] [-t_srs ] [-dsco =]... ] - [import ] [-l ] - [connect [-c ] [-ic ] [-dir ]] - [disconnect ] - [rule ] - [autoconnect ] - [delete] - [change [-bl ][-unbl ][-unblall]] - [ []...] +.. program-output:: gnmmanage --help-doc Description ----------- diff --git a/doc/source/programs/nearblack.rst b/doc/source/programs/nearblack.rst index 378ebfd07ae3..97a9dae4db28 100644 --- a/doc/source/programs/nearblack.rst +++ b/doc/source/programs/nearblack.rst @@ -13,13 +13,7 @@ nearblack Synopsis -------- -.. code-block:: - - nearblack [--help] [--help-general] - [-of ] [-white | [-color ,,...]...] - [-near ] [-nb ] - [-setalpha] [-setmask] [-alg twopasses|floodfill] - [-o ] [-q] [-co =]... +.. program-output:: nearblack --help-doc Description ----------- diff --git a/doc/source/programs/ogr2ogr.rst b/doc/source/programs/ogr2ogr.rst index 33fbeec56807..307c36874ac2 100644 --- a/doc/source/programs/ogr2ogr.rst +++ b/doc/source/programs/ogr2ogr.rst @@ -13,57 +13,7 @@ ogr2ogr Synopsis -------- -.. code-block:: - - ogr2ogr [--help] [--long-usage] [--help-general] - [-of ] - [-dsco =]... [-lco =]... - [[-append]|[-upsert]|[-overwrite]] - [-update] [-sql |@] [-dialect ] - [-spat ] - [-where |@] [-select ] - [-nln ] [-nlt ]... - [-s_srs ] - [[-a_srs ]|[-t_srs ]] - []... - - Field related options: - [-addfields] [-relaxedFieldNameMatch] - [-fieldTypeToString All|[,]...] - [-mapFieldType |All=[,=]...] - [-fieldmap [,]...] - [-splitlistfields] [-maxsubfields ] [-emptyStrAsNull] - [-forceNullable] [-unsetFieldWidth] - [-unsetDefault] [-resolveDomains] - [-dateTimeTo UTC|UTC(+|-)|UTC(+|-):] [-noNativeData] - - Advanced geometry and SRS related options: - [-dim layer_dim|2|XY|3|XYZ|XYM|XYZM] - [-s_coord_epoch ] [-a_coord_epoch ] - [-t_coord_epoch ] [-ct ] - [-spat_srs ] [-geomfield ] - [-segmentize ] [-simplify ] - [-makevalid] [-skipinvalid] - [-wrapdateline] [-datelineoffset ] - [-clipsrc [ ]|||spat_extent] - [-clipsrcsql ] [-clipsrclayer ] - [-clipsrcwhere ] - [-clipdst [ ]||] - [-clipdstsql ] [-clipdstlayer ] - [-clipdstwhere ] - [-explodecollections] [-zfield ] - [-gcp []]... - [-tps] [-order 1|2|3] - [-xyRes [ m|mm|deg]] [-zRes [ m|mm]] [-mRes ] - [-unsetCoordPrecision] - - Other options: - [--quiet] [-progress] [-if ]... - [-oo =]... [-doo =]... - [-fid ] [-preserve_fid] [-unsetFid] - [[-skipfailures]|[-gt |unlimited]] - [-limit ] [-ds_transaction] - [-mo =]... [-nomd] +.. program-output:: ogr2ogr --help-doc Description ----------- diff --git a/doc/source/programs/ogrinfo.rst b/doc/source/programs/ogrinfo.rst index 549e6dbad959..4da31a9a58e4 100644 --- a/doc/source/programs/ogrinfo.rst +++ b/doc/source/programs/ogrinfo.rst @@ -14,21 +14,7 @@ ogrinfo Synopsis -------- -.. code-block:: - - ogrinfo [--help] [--long-usage] [--help-general] - [-json] [-ro] [-update] [--quiet] [-fid ] - [-spat ] [-geomfield ] - [-where ] - [[-sql ]|[-rl]] - [-dialect ] [-al] - [[-summary]|[-features]] - [-limit ] [-fields YES|NO] - [-geom YES|NO|SUMMARY|WKT|ISO_WKT] [-oo ]... [-nomd] - [-listmdd] [-mdd ]... [-nocount] [-noextent] [-extent3D] - [-nogeomtype] [-wkt_format WKT1|WKT2|WKT2_2015|WKT2_2019] - [-fielddomain ] [-if ]... - filename []... +.. program-output:: ogrinfo --help-doc Description ----------- diff --git a/doc/source/programs/ogrtindex.rst b/doc/source/programs/ogrtindex.rst index 98c7e5199870..ad890d063913 100644 --- a/doc/source/programs/ogrtindex.rst +++ b/doc/source/programs/ogrtindex.rst @@ -13,16 +13,7 @@ ogrtindex Synopsis -------- -.. code-block:: - - ogrtindex [--help] [--help-general] - [-lnum ]... [-lname ]... [-f ] - [-write_absolute_path] [-skip_different_projection] - [-t_srs ] - [-src_srs_name ] [-src_srs_format {AUTO|WKT|EPSG|PROJ}] - [-accept_different_schemas] - ... - +.. program-output:: ogrtindex --help-doc Description ----------- From 2f0ceecba1f8bc6dec9446a69984c67015c6cf68 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 15 Mar 2025 07:00:35 -0400 Subject: [PATCH 16/17] Doc: Update instructions on Sphinx build --- .../development/building_from_source.rst | 2 + doc/source/development/dev_documentation.rst | 71 ++++++++++--------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/doc/source/development/building_from_source.rst b/doc/source/development/building_from_source.rst index 2bf4634847a8..cad9db0d2e4c 100644 --- a/doc/source/development/building_from_source.rst +++ b/doc/source/development/building_from_source.rst @@ -54,6 +54,8 @@ From the build directory you can now configure CMake, build and install the bina cmake --build . cmake --build . --target install +.. _minimal_build: + .. note:: For a minimal build, add these options to the initial ``cmake`` command: ``-DGDAL_BUILD_OPTIONAL_DRIVERS=OFF -DOGR_BUILD_OPTIONAL_DRIVERS=OFF``. diff --git a/doc/source/development/dev_documentation.rst b/doc/source/development/dev_documentation.rst index 78bc10d43ab9..8efbf89045b5 100644 --- a/doc/source/development/dev_documentation.rst +++ b/doc/source/development/dev_documentation.rst @@ -19,8 +19,22 @@ the ``doc`` subdirectory. Building documentation ###################### -Documentation can be generated with Makefile targets, from the ``doc`` subdirectory -of the GDAL source repository (only on Unix systems). +Documentation can be generated with the CMake targets listed below. These +targets are only available if the CMake ``BUILD_DOCS=ON`` variable is set, +which is the default if Doxygen and Sphinx are detected. + +.. note:: + + CMake will attempt to detect Sphinx at configuration time (i.e, when ``cmake`` + is first run). If Sphinx is provided via a Conda or a Python virtual environment, + that environment should be activated during CMake configuration. + +.. note:: + + Because some documentation pages execute GDAL command-line utilities or Python + code when generating, these GDAL components must also be available to build the + documentation without warnings. See :ref:`build instructions ` for hints on reducing + this build time. The following targets are available: @@ -29,35 +43,22 @@ The following targets are available: * ``man``: build MAN pages into the ``doc/build/man`` directory. -* ``latexpdf``: build PDF documentation into the ``doc/build/pdf`` directory +* ``latexpdf``: build PDF documentation into the ``doc/build/latex`` directory -* ``doxygen``: regenerate API Doxygen XML and HTML output, that is used by the - ``html`` target. Doxygen content is not automatically rebuilt when source files - are modified, hence this target must be explicitly run to refresh it. +* ``doxygen_xml`` : regenerate API Doxygen XML outputs, used by the above targets. -* ``doxygen_check_warnings``: same as ``doxygen``, but errors out when Doxygen - emits a warning (the ``doxygen`` target is tolerant to Doxygen warnings). - This can be useful to reproduce one of the continuous integration checks that - verifies that there are no Doxygen warnings. - Requires Doxygen >= 1.9.3 to be warning free. +* ``doxygen_html``: generate Doxygen HTML documentation (this is distinct from the + API documentation included in the ``html`` target above). -* ``spelling``: runs spell checking on the documentation, covering as well as - documentation generated from C/C++ API (Doxygen) and Python API. Words unknown - to the spell checker but still considered valid should be added to the allow - list in :file:`doc/source/spelling_wordlist.txt` +If ``BUILD_TESTING`` is enabled, the documentation can be spell-checked using +the ``doc-spelling`` test (invoked using ``ctest -V -R doc-spelling --output-on-failure``.) +Documentation generated from C/C++ API (Doxygen) and Python API is included in +the check. Words unknown to the spell checker but still considered valid should +be added to the list in :file:`doc/source/spelling_wordlist.txt` -* ``clean``: clean the ``doc/build`` directory. - -It is also possible to run those targets as CMake targets. In that case, the -output directory will be the ``doc/build`` subdirectory of the CMake -build directory. To only clean the documentation, the ``clean_doc`` target can -be invoked. -Note: those CMake targets are only available if the CMake BUILD_DOCS=ON variable -is set (it is set by default if build preconditions are met, that is if Doxygen, -Sphinx and make are available) - -To visualize documentation changes while editing, it may be useful to install the |sphinx-autobuild| python package. -Once installed, running ``sphinx-autobuild -b html source build`` from the ``doc`` subdirectory will build documentation +To visualize documentation changes while editing, it may be useful to install the |sphinx-autobuild| Python package. +Once installed, running ``sphinx-autobuild -b html source_dir build_dir`` with appropriate values of ``source_dir`` and +``build_dir`` will build documentation and serve it on a local web server at ``http://127.0.0.1:8000``. The pages served will be automatically refreshed as changes are made to underlying ``rst`` documentation files. @@ -72,13 +73,17 @@ Docstrings may be found in two locations. If the function was defined in Python placed within the function definition. If the function is defined in C++ only, then the docstring should be placed in a separate file containing only docstrings (located in :source_file:`swig/include/python/docs`). -Sphinx loads the Python bindings when generating documentation, so for it to see any changes -the following steps must be completed: -- rebuild the Python bindings from the build directory (``cmake --build . --target python_binding``) -- make the updated Python bindings visible to Python, either by installing them, or by running ``scripts/setdevenv.sh`` - from the build directory -- update the timestamp of the ``rst`` files associated with the page where the documentation appears (e.g., ``touch doc/source/api/python/osgeo.ogr.rst``) +Sphinx loads the Python bindings when generating documentation, so for it to see any changes +the updated Python module must be loadable by the Python interpreter Sphinx is using. When building +documentation using CMake (e..g, ``cmake --build . --target html``) this will be done automatically. +If using ``sphinx-build`` or ``sphinx-autobuild`` manually, the updated Python bindings must be +rebuilt (``cmake --build . --target python_binding``) and made visible to Python, either by installing +them or by sourcing ``scripts/setdevenv.sh`` from the build directory. + +Sphinx cannot detect changes to the Python module, so when iteratively rebuilding Python API documentation it is +necessary to manually update the timestamp of the ``rst`` files associated with the page where the modified +documentation appears (e.g., ``touch doc/source/api/python/osgeo.ogr.rst``) .. _rst_style: From 587c7c546ab63a83039bb34d384585f1e92b430d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 17 Mar 2025 08:21:10 -0400 Subject: [PATCH 17/17] CMake: Reduce scope of Doxygen source globs --- doc/CMakeLists.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 3c987054adac..866dcbd20c1c 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -39,16 +39,24 @@ if (BUILD_DOCS) file(MAKE_DIRECTORY ${SPHINX_BUILD_DIR}/html_extra) file(GLOB_RECURSE SPHINX_SOURCE_FILES CONFIGURE_DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/source/**/*.rst - ${CMAKE_CURRENT_SOURCE_DIR}/source/**/*.py) + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.rst + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.py) #################################################################################################### # Doxygen XML and HTML outputs #################################################################################################### # Create a dependency between source files and Doxygen - # This is more aggressive than needed, because we only build Doxygen for a subset of the source tree - file(GLOB_RECURSE DOXYGEN_SOURCE_FILES CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/**/*.cpp) + file(GLOB_RECURSE DOXYGEN_SOURCE_FILES CONFIGURE_DEPENDS + ${CMAKE_SOURCE_DIR}/alg/*.cpp + ${CMAKE_SOURCE_DIR}/app/*.cpp + ${CMAKE_SOURCE_DIR}/frmts/gdalallregister.cpp + ${CMAKE_SOURCE_DIR}/frmts/vrt/*.cpp + ${CMAKE_SOURCE_DIR}/gcore/*.cpp + ${CMAKE_SOURCE_DIR}/ogr/*.cpp + ${CMAKE_SOURCE_DIR}/port/*.cpp + ${CMAKE_SOURCE_DIR}/gnm/*.cpp + ) # Use configure_file to copy the Doxygen file into our build directory. # This causes CMake to re-run if the contents of the Doxyfile change.