From f56bceb502a628f6277d5ef410fee9f26b78ad62 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Jan 2025 15:47:15 +0100 Subject: [PATCH 1/7] gdal.h: add GDAL_DCAP_UPDATE and GDAL_DMD_UPDATE_ITEMS --- doc/source/api/raster_c_api.rst | 1 + gcore/gdal.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/doc/source/api/raster_c_api.rst b/doc/source/api/raster_c_api.rst index 8c2dc9b73209..a2ec82aa6b41 100644 --- a/doc/source/api/raster_c_api.rst +++ b/doc/source/api/raster_c_api.rst @@ -20,3 +20,4 @@ gdal.h: Raster C API nSrcWidth pSrc pDst + SetMetadataItem diff --git a/gcore/gdal.h b/gcore/gdal.h index fea2e37f7d10..02adb37c43f6 100644 --- a/gcore/gdal.h +++ b/gcore/gdal.h @@ -584,6 +584,14 @@ typedef enum /** Capability set by a driver that can copy over subdatasets. */ #define GDAL_DCAP_SUBCREATECOPY "DCAP_SUBCREATECOPY" +/** Capability set by a driver that supports the GDAL_OF_UPDATE flag and offers + * at least some update capabilities. + * Exact update capabilities can be determined by the GDAL_DMD_UPDATE_ITEMS + * metadata item + * @since GDAL 3.11 + */ +#define GDAL_DCAP_UPDATE "DCAP_UPDATE" + /** Capability set by a driver that can read/create datasets through the VSI*L * API. */ #define GDAL_DCAP_VIRTUALIO "DCAP_VIRTUALIO" @@ -899,6 +907,25 @@ typedef enum #define GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE "DMD_PLUGIN_INSTALLATION_MESSAGE" /*! @endcond */ +/** List of (space separated) items that a dataset opened in update mode supports + * updating. Possible values are: + * - for raster: "GeoTransform" (through GDALDataset::SetGeoTransform), + * "SRS" (GDALDataset::SetSpatialRef), "GCPs" (GDALDataset::SetGCPs()), + * "NoData" (GDALRasterBand::SetNoDataValue), + * "ColorInterpretation" (GDALRasterBand::SetColorInterpretation()), + * "RasterValues" (GF_Write flag of GDALDataset::RasterIO() and GDALRasterBand::RasterIO()), + * "DatasetMetadata" (GDALDataset::SetMetadata/SetMetadataItem), "BandMetadata" + * (GDALRasterBand::SetMetadata/SetMetadataItem) + * - for vector: "Features" (OGRLayer::SetFeature()), "DatasetMetadata", + * "LayerMetadata" + * + * No distinction is made if the update is done in the native format, + * or in a Persistent Auxiliary Metadata .aux.xml side car file. + * + * @since GDAL 3.11 + */ +#define GDAL_DMD_UPDATE_ITEMS "DMD_UPDATE_ITEMS" + /** Value for GDALDimension::GetType() specifying the X axis of a horizontal * CRS. * @since GDAL 3.1 From cce4995274ee306ba51dbb764d5d4db3d8ac9008 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Jan 2025 15:47:41 +0100 Subject: [PATCH 2/7] --formats: report update capabilities --- gcore/gdal_misc.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gcore/gdal_misc.cpp b/gcore/gdal_misc.cpp index 3d05c70e2a3d..09e65c2ca824 100644 --- a/gcore/gdal_misc.cpp +++ b/gcore/gdal_misc.cpp @@ -3851,6 +3851,8 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, oJCaps.Add("create"); if (CPLFetchBool(papszMD, GDAL_DCAP_CREATECOPY, false)) oJCaps.Add("create_copy"); + if (CPLFetchBool(papszMD, GDAL_DCAP_UPDATE, false)) + oJCaps.Add("update"); if (CPLFetchBool(papszMD, GDAL_DCAP_VIRTUALIO, false)) oJCaps.Add("virtual_io"); oJDriver.Add("capabilities", oJCaps); @@ -3880,7 +3882,8 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, } printf(/*ok*/ - "Supported Formats: (ro:read-only, rw:read-write, +:update, " + "Supported Formats: (ro:read-only, rw:read-write, " + "+:write from scratch, u:update, " "v:virtual-I/O s:subdatasets)\n"); for (int iDr = 0; iDr < GDALGetDriverCount(); iDr++) { @@ -3913,6 +3916,10 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, else pszWFlag = "o"; + const char *pszUpdate = ""; + if (CPLFetchBool(papszMD, GDAL_DCAP_UPDATE, false)) + pszUpdate = "u"; + if (CPLFetchBool(papszMD, GDAL_DCAP_VIRTUALIO, false)) pszVirtualIO = "v"; else @@ -3966,10 +3973,11 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, osExtensions += ')'; } - printf(" %s -%s- (%s%s%s%s): %s%s\n", /*ok*/ + printf(" %s -%s- (%s%s%s%s%s): %s%s\n", /*ok*/ GDALGetDriverShortName(hDriver), osKind.c_str(), - pszRFlag, pszWFlag, pszVirtualIO, pszSubdatasets, - GDALGetDriverLongName(hDriver), osExtensions.c_str()); + pszRFlag, pszWFlag, pszUpdate, pszVirtualIO, + pszSubdatasets, GDALGetDriverLongName(hDriver), + osExtensions.c_str()); } return 0; @@ -4047,6 +4055,8 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, printf(/*ok*/ " Supports: CreateCopy() - Create dataset by " "copying " "another.\n"); + if (CPLFetchBool(papszMD, GDAL_DCAP_UPDATE, false)) + printf(" Supports: Update\n"); /*ok*/ if (CPLFetchBool(papszMD, GDAL_DCAP_VIRTUALIO, false)) printf(" Supports: Virtual IO - eg. /vsimem/\n"); /*ok*/ if (CSLFetchNameValue(papszMD, GDAL_DMD_CREATIONDATATYPES)) @@ -4096,6 +4106,9 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, printf(" Supported SQL dialects: %s\n", /*ok*/ CSLFetchNameValue(papszMD, GDAL_DMD_SUPPORTED_SQL_DIALECTS)); + if (CSLFetchNameValue(papszMD, GDAL_DMD_UPDATE_ITEMS)) + printf(" Supported items for update: %s\n", /*ok*/ + CSLFetchNameValue(papszMD, GDAL_DMD_UPDATE_ITEMS)); for (const char *key : {GDAL_DMD_CREATIONOPTIONLIST, From ee2f14dda82f7e56c2573e753dd6f2d3ae9bcf78 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Jan 2025 15:47:51 +0100 Subject: [PATCH 3/7] SWIG: map GDAL_DCAP_UPDATE and GDAL_DMD_UPDATE_ITEMS --- swig/include/gdalconst.i | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/swig/include/gdalconst.i b/swig/include/gdalconst.i index 034ff05e76e1..3b0db9f0a946 100644 --- a/swig/include/gdalconst.i +++ b/swig/include/gdalconst.i @@ -203,6 +203,7 @@ %constant char *DMD_CREATIONFIELDDATATYPES = GDAL_DMD_CREATIONFIELDDATATYPES; %constant char *DMD_CREATIONFIELDDATASUBTYPES = GDAL_DMD_CREATIONFIELDDATASUBTYPES; %constant char *DMD_CREATION_FIELD_DEFN_FLAGS = GDAL_DMD_CREATION_FIELD_DEFN_FLAGS; +%constant char *DMD_UPDATE_ITEMS = GDAL_DMD_UPDATE_ITEMS; %constant char *DMD_SUBDATASETS = GDAL_DMD_SUBDATASETS; %constant char *DMD_CREATION_FIELD_DOMAIN_TYPES = GDAL_DMD_CREATION_FIELD_DOMAIN_TYPES; %constant char *DMD_ALTER_GEOM_FIELD_DEFN_FLAGS = GDAL_DMD_ALTER_GEOM_FIELD_DEFN_FLAGS; @@ -216,6 +217,7 @@ %constant char *DCAP_CREATECOPY = GDAL_DCAP_CREATECOPY; %constant char *DCAP_CREATECOPY_MULTIDIMENSIONAL = GDAL_DCAP_CREATECOPY_MULTIDIMENSIONAL; %constant char *DCAP_MULTIDIM_RASTER = GDAL_DCAP_MULTIDIM_RASTER; +%constant char *DCAP_UPDATE = GDAL_DCAP_UPDATE; %constant char *DCAP_SUBCREATECOPY = GDAL_DCAP_SUBCREATECOPY; %constant char *DCAP_VIRTUALIO = GDAL_DCAP_VIRTUALIO; %constant char *DCAP_RASTER = GDAL_DCAP_RASTER; @@ -306,6 +308,8 @@ #define GDAL_DMD_CREATIONFIELDDATASUBTYPES "DMD_CREATIONFIELDDATASUBTYPES" #define GDAL_DMD_CREATION_FIELD_DEFN_FLAGS "DMD_CREATION_FIELD_DEFN_FLAGS" #define DMD_CREATION_FIELD_DEFN_FLAGS "DMD_CREATIONFIELDDATASUBTYPES" +#define GDAL_DMD_UPDATE_ITEMS "DMD_UPDATE_ITEMS" +#define DMD_UPDATE_ITEMS "DMD_UPDATE_ITEMS" #define DMD_SUBDATASETS "DMD_SUBDATASETS" #define GDAL_DMD_SUBDATASETS "DMD_SUBDATASETS" #define DMD_CREATION_FIELD_DOMAIN_TYPES "DMD_CREATION_FIELD_DOMAIN_TYPES" @@ -327,6 +331,8 @@ #define GDAL_DCAP_CREATE_MULTIDIMENSIONAL "DCAP_CREATE_MULTIDIMENSIONAL" #define DCAP_CREATECOPY "DCAP_CREATECOPY" #define GDAL_DCAP_CREATECOPY "DCAP_CREATECOPY" +#define DCAP_UPDATE "DCAP_UPDATE" +#define GDAL_DCAP_UPDATE "DCAP_UPDATE" #define DCAP_CREATECOPY_MULTIDIMENSIONAL "DCAP_CREATECOPY_MULTIDIMENSIONAL" #define GDAL_DCAP_CREATECOPY_MULTIDIMENSIONAL "DCAP_CREATECOPY_MULTIDIMENSIONAL" #define DCAP_MULTIDIM_RASTER "DCAP_MULTIDIM_RASTER" From bf65ab975739e458913736b307406759ca61205e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Jan 2025 15:48:36 +0100 Subject: [PATCH 4/7] Drivers: declare GDAL_DCAP_UPDATE and GDAL_DMD_UPDATE_ITEMS where relevant --- .../expected_gdalinfo_formats.txt | 32 +++++++-------- .../ubuntu_24.04/expected_ogrinfo_formats.txt | 40 +++++++++---------- ...indows_conda_expected_gdalinfo_formats.txt | 34 ++++++++-------- ...windows_conda_expected_ogrinfo_formats.txt | 34 ++++++++-------- autotest/utilities/test_gdalinfo.py | 4 +- autotest/utilities/test_ogrinfo.py | 4 +- frmts/ecw/ecwdrivercore.cpp | 5 +++ frmts/gtiff/geotiff.cpp | 6 +++ frmts/hfa/hfadataset.cpp | 6 +++ frmts/kea/keadrivercore.cpp | 6 +++ frmts/netcdf/netcdfdrivercore.cpp | 5 +++ frmts/nitf/nitfdrivercore.cpp | 3 ++ frmts/pcidsk/pcidskdrivercore.cpp | 6 +++ frmts/pdf/pdfdrivercore.cpp | 4 ++ frmts/raw/ehdrdataset.cpp | 4 ++ frmts/raw/envidataset.cpp | 5 +++ frmts/raw/rrasterdataset.cpp | 5 +++ frmts/tiledb/tiledbdrivercore.cpp | 3 ++ frmts/vrt/vrtdriver.cpp | 6 +++ frmts/zarr/zarrdrivercore.cpp | 6 +++ ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp | 3 ++ ogr/ogrsf_frmts/geojson/ogrgeojsondriver.cpp | 3 ++ ogr/ogrsf_frmts/gpkg/ogrgeopackagedriver.cpp | 5 +++ ogr/ogrsf_frmts/hana/ogrhanadrivercore.cpp | 3 ++ .../libkml/ogrlibkmldrivercore.cpp | 3 ++ ogr/ogrsf_frmts/mitab/mitab_ogr_driver.cpp | 3 ++ .../ogrmssqlspatialdrivercore.cpp | 3 ++ ogr/ogrsf_frmts/mysql/ogrmysqldrivercore.cpp | 3 ++ ogr/ogrsf_frmts/oci/ogrocidrivercore.cpp | 3 ++ .../openfilegdb/ogropenfilegdbdrivercore.cpp | 3 ++ ogr/ogrsf_frmts/pg/ogrpgdrivercore.cpp | 3 ++ ogr/ogrsf_frmts/shape/ogrshapedriver.cpp | 3 ++ ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.cpp | 3 ++ 33 files changed, 185 insertions(+), 74 deletions(-) diff --git a/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt b/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt index 54759dcf3534..1d008a25fe48 100644 --- a/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt +++ b/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt @@ -1,15 +1,15 @@ -Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) - VRT -raster,multidimensional raster- (rw+v): Virtual Raster (*.vrt) +Supported Formats: (ro:read-only, rw:read-write, +:write from scratch, u:update, v:virtual-I/O s:subdatasets) + VRT -raster,multidimensional raster- (rw+uv): Virtual Raster (*.vrt) DERIVED -raster- (ro): Derived datasets using VRT pixel functions GTI -raster- (rov): GDAL Raster Tile Index (*.gti.gpkg, *.gti.fgb, *.gti) SNAP_TIFF -raster- (rov): Sentinel Application Processing GeoTIFF - GTiff -raster- (rw+vs): GeoTIFF (*.tif, *.tiff) + GTiff -raster- (rw+uvs): GeoTIFF (*.tif, *.tiff) COG -raster- (wv): Cloud optimized GeoTIFF generator (*.tif, *.tiff) LIBERTIFF -raster- (rov): GeoTIFF (using LIBERTIFF library) (*.tif, *.tiff) - NITF -raster- (rw+vs): National Imagery Transmission Format (*.ntf) + NITF -raster- (rw+uvs): National Imagery Transmission Format (*.ntf) RPFTOC -raster- (rovs): Raster Product Format TOC format (*.toc) ECRGTOC -raster- (rovs): ECRG TOC format (*.xml) - HFA -raster- (rw+v): Erdas Imagine Images (.img) (*.img) + HFA -raster- (rw+uv): Erdas Imagine Images (.img) (*.img) SAR_CEOS -raster- (rov): CEOS SAR Image CEOS -raster- (rov): CEOS Image JAXAPALSAR -raster- (rov): JAXA PALSAR Product Reader (Level 1.1/1.5) @@ -37,20 +37,20 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda AirSAR -raster- (rov): AirSAR Polarimetric Image RS2 -raster- (rovs): RadarSat 2 XML Product SAFE -raster- (rov): Sentinel-1 SAR SAFE Product - PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) + PCIDSK -raster,vector- (rw+uv): PCIDSK Database File (*.pix) PCRaster -raster- (rw+): PCRaster Raster File (*.map) ILWIS -raster- (rw+v): ILWIS Raster Map (*.mpr, *.mpl) SGI -raster- (rw+v): SGI Image File Format 1.0 (*.rgb) SRTMHGT -raster- (rwv): SRTMHGT File Format (*.hgt) Leveller -raster- (rw+v): Leveller heightfield (*.ter) Terragen -raster- (rw+v): Terragen heightfield (*.ter) - netCDF -raster,multidimensional raster,vector- (rw+vs): Network Common Data Format (*.nc) + netCDF -raster,multidimensional raster,vector- (rw+uvs): Network Common Data Format (*.nc) HDF4 -raster,multidimensional raster- (ros): Hierarchical Data Format Release 4 (*.hdf) HDF4Image -raster- (rw+): HDF4 Dataset ISIS3 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 3) (*.lbl, *.cub) ISIS2 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 2) PDS -raster- (rov): NASA Planetary Data System - PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + PDS4 -raster,vector- (rw+uvs): NASA Planetary Data System 4 (*.xml) VICAR -raster,vector- (rw+v): MIPL VICAR file TIL -raster- (rov): EarthWatch .TIL ERS -raster- (rw+v): ERMapper .ers Labelled (*.ers) @@ -73,7 +73,7 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda MAP -raster- (rov): OziExplorer .MAP KMLSUPEROVERLAY -raster- (rwv): Kml Super Overlay (*.kml, *.kmz) WEBP -raster- (rwv): WEBP (*.webp) - PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + PDF -raster,vector- (rw+uvs): Geospatial PDF (*.pdf) Rasterlite -raster- (rwvs): Rasterlite (*.sqlite) MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) PLMOSAIC -raster- (ro): Planet Labs Mosaics API @@ -104,7 +104,7 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda SNODAS -raster- (rov): Snow Data Assimilation System (*.hdr) KRO -raster- (rw+v): KOLOR Raw (*.kro) ROI_PAC -raster- (rw+v): ROI_PAC raster - RRASTER -raster- (rw+v): R Raster (*.grd) + RRASTER -raster- (rw+uv): R Raster (*.grd) BYN -raster- (rw+v): Natural Resources Canada's Geoid (*.byn, *.err) NOAA_B -raster- (rov): NOAA GEOCON/NADCON5 .b format (*.b) NSIDCbin -raster- (rov): NSIDC Sea Ice Concentrations binary (.bin) (*.bin) @@ -143,16 +143,16 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda STACTA -raster- (rovs): Spatio-Temporal Asset Catalog Tiled Assets (*.json) STACIT -raster- (rovs): Spatio-Temporal Asset Catalog Items JPEGXL -raster- (rwv): JPEG-XL (*.jxl) - GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) - SQLite -raster,vector- (rw+v): SQLite / Spatialite / RasterLite2 (*.sqlite, *.db) - OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + GPKG -raster,vector- (rw+uvs): GeoPackage (*.gpkg, *.gpkg.zip) + SQLite -raster,vector- (rw+uv): SQLite / Spatialite / RasterLite2 (*.sqlite, *.db) + OpenFileGDB -raster,vector- (rw+uv): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) PLSCENES -raster,vector- (ro): Planet Labs Scenes API NGW -raster,vector- (rw+s): NextGIS Web GenBin -raster- (rov): Generic Binary (.hdr Labelled) - ENVI -raster- (rw+v): ENVI .hdr Labelled - EHdr -raster- (rw+v): ESRI .hdr Labelled (*.bil) + ENVI -raster- (rw+uv): ENVI .hdr Labelled + EHdr -raster- (rw+uv): ESRI .hdr Labelled (*.bil) ISCE -raster- (rw+v): ISCE raster - Zarr -raster,multidimensional raster- (rw+vs): Zarr + Zarr -raster,multidimensional raster- (rw+uvs): Zarr RCM -raster- (rovs): Radarsat Constellation Mission XML Product HTTP -raster,vector- (ro): HTTP Fetching Wrapper diff --git a/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt b/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt index 7c177754dd40..cebb30291c8f 100644 --- a/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt +++ b/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt @@ -1,17 +1,17 @@ -Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) +Supported Formats: (ro:read-only, rw:read-write, +:write from scratch, u:update, v:virtual-I/O s:subdatasets) FITS -raster,vector- (rw+): Flexible Image Transport System (*.fits) - PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) - netCDF -raster,multidimensional raster,vector- (rw+vs): Network Common Data Format (*.nc) - PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + PCIDSK -raster,vector- (rw+uv): PCIDSK Database File (*.pix) + netCDF -raster,multidimensional raster,vector- (rw+uvs): Network Common Data Format (*.nc) + PDS4 -raster,vector- (rw+uvs): NASA Planetary Data System 4 (*.xml) VICAR -raster,vector- (rw+v): MIPL VICAR file JP2OpenJPEG -raster,vector- (rwv): JPEG-2000 driver based on JP2OpenJPEG library (*.jp2, *.j2k) - PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + PDF -raster,vector- (rw+uvs): Geospatial PDF (*.pdf) MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) EEDA -vector- (ro): Earth Engine Data API OGCAPI -raster,vector- (rov): OGCAPI - ESRI Shapefile -vector- (rw+v): ESRI Shapefile (*.shp, *.dbf, *.shz, *.shp.zip) - MapInfo File -vector- (rw+v): MapInfo File (*.tab, *.mif, *.mid) + ESRI Shapefile -vector- (rw+uv): ESRI Shapefile (*.shp, *.dbf, *.shz, *.shp.zip) + MapInfo File -vector- (rw+uv): MapInfo File (*.tab, *.mif, *.mid) UK .NTF -vector- (rov): UK .NTF LVBAG -vector- (rov): Kadaster LV BAG Extract 2.0 (*.xml) OGR_SDTS -vector- (rov): SDTS @@ -19,30 +19,30 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda DGN -vector- (rw+v): Microstation DGN (*.dgn) OGR_VRT -vector- (rov): VRT - Virtual Datasource (*.vrt) Memory -vector- (rw+): Memory - CSV -vector- (rw+v): Comma Separated Value (.csv) (*.csv, *.tsv, *.psv) + CSV -vector- (rw+uv): Comma Separated Value (.csv) (*.csv, *.tsv, *.psv) NAS -vector- (rov): NAS - ALKIS (*.xml) GML -vector- (rw+v): Geography Markup Language (GML) (*.gml, *.xml) GPX -vector- (rw+v): GPX (*.gpx) - LIBKML -vector- (rw+v): Keyhole Markup Language (LIBKML) (*.kml, *.kmz) + LIBKML -vector- (rw+uv): Keyhole Markup Language (LIBKML) (*.kml, *.kmz) KML -vector- (rw+v): Keyhole Markup Language (KML) (*.kml) - GeoJSON -vector- (rw+v): GeoJSON (*.json, *.geojson) + GeoJSON -vector- (rw+uv): GeoJSON (*.json, *.geojson) GeoJSONSeq -vector- (rw+v): GeoJSON Sequence (*.geojsonl, *.geojsons) ESRIJSON -vector- (rov): ESRIJSON (*.json) TopoJSON -vector- (rov): TopoJSON (*.json, *.topojson) Interlis 1 -vector- (rov): Interlis 1 (*.itf, *.ili) Interlis 2 -vector- (rov): Interlis 2 (*.xtf, *.xml, *.ili) OGR_GMT -vector- (rw+v): GMT ASCII Vectors (.gmt) (*.gmt) - GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) - SQLite -raster,vector- (rw+v): SQLite / Spatialite / RasterLite2 (*.sqlite, *.db) + GPKG -raster,vector- (rw+uvs): GeoPackage (*.gpkg, *.gpkg.zip) + SQLite -raster,vector- (rw+uv): SQLite / Spatialite / RasterLite2 (*.sqlite, *.db) ODBC -vector- (ro): Open Database Connectivity (ODBC) (*.mdb, *.accdb) WAsP -vector- (rw+v): WAsP .map format (*.map) PGeo -vector- (ro): ESRI Personal GeoDatabase (*.mdb) - MSSQLSpatial -vector- (rw+): Microsoft SQL Server Spatial Database (BCP) + MSSQLSpatial -vector- (rw+u): Microsoft SQL Server Spatial Database (BCP) OGR_OGDI -vector- (ro): OGDI Vectors (VPF, VMAP, DCW) - PostgreSQL -vector- (rw+): PostgreSQL/PostGIS - MySQL -vector- (rw+): MySQL - OCI -vector- (rw+): Oracle Spatial - OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + PostgreSQL -vector- (rw+u): PostgreSQL/PostGIS + MySQL -vector- (rw+u): MySQL + OCI -vector- (rw+u): Oracle Spatial + OpenFileGDB -raster,vector- (rw+uv): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) FileGDB -vector- (rw+): ESRI FileGDB (*.gdb) DXF -vector- (rw+v): AutoCAD DXF (*.dxf) CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) @@ -61,8 +61,8 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda SVG -vector- (rov): Scalable Vector Graphics (*.svg) Idrisi -vector- (rov): Idrisi Vector (.vct) (*.vct) XLS -vector- (ro): MS Excel format (*.xls) - ODS -vector- (rw+v): Open Document/ LibreOffice / OpenOffice Spreadsheet (*.ods) - XLSX -vector- (rw+v): MS Office Open XML spreadsheet (*.xlsx, *.xlsm) + ODS -vector- (rw+uv): Open Document/ LibreOffice / OpenOffice Spreadsheet (*.ods) + XLSX -vector- (rw+uv): MS Office Open XML spreadsheet (*.xlsx, *.xlsm) Elasticsearch -vector- (rw+): Elastic Search Carto -vector- (rw+): Carto AmigoCloud -vector- (rw+): AmigoCloud @@ -71,7 +71,7 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda JML -vector- (rw+v): OpenJUMP JML (*.jml) PLSCENES -raster,vector- (ro): Planet Labs Scenes API CSW -vector- (ro): OGC CSW (Catalog Service for the Web) - MongoDBv3 -vector- (ro): MongoDB (using libmongocxx v3 client) + MongoDBv3 -vector- (rou): MongoDB (using libmongocxx v3 client) VDV -vector- (rw+v): VDV-451/VDV-452/INTREST Data Format (*.txt, *.x10) GMLAS -vector- (rwv): Geography Markup Language (GML) driven by application schemas (*.gml, *.xml) MVT -vector- (rw+v): Mapbox Vector Tiles (*.mvt, *.mvt.gz, *.pbf) diff --git a/.github/workflows/windows_conda_expected_gdalinfo_formats.txt b/.github/workflows/windows_conda_expected_gdalinfo_formats.txt index 2077516a871d..8511ee4bfddc 100644 --- a/.github/workflows/windows_conda_expected_gdalinfo_formats.txt +++ b/.github/workflows/windows_conda_expected_gdalinfo_formats.txt @@ -1,15 +1,15 @@ -Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) - VRT -raster,multidimensional raster- (rw+v): Virtual Raster (*.vrt) +Supported Formats: (ro:read-only, rw:read-write, +:write from scratch, u:update, v:virtual-I/O s:subdatasets) + VRT -raster,multidimensional raster- (rw+uv): Virtual Raster (*.vrt) DERIVED -raster- (ro): Derived datasets using VRT pixel functions GTI -raster- (rov): GDAL Raster Tile Index (*.gti.gpkg, *.gti.fgb, *.gti) SNAP_TIFF -raster- (rov): Sentinel Application Processing GeoTIFF - GTiff -raster- (rw+vs): GeoTIFF (*.tif, *.tiff) + GTiff -raster- (rw+uvs): GeoTIFF (*.tif, *.tiff) COG -raster- (wv): Cloud optimized GeoTIFF generator (*.tif, *.tiff) LIBERTIFF -raster- (rov): GeoTIFF (using LIBERTIFF library) (*.tif, *.tiff) - NITF -raster- (rw+vs): National Imagery Transmission Format (*.ntf) + NITF -raster- (rw+uvs): National Imagery Transmission Format (*.ntf) RPFTOC -raster- (rovs): Raster Product Format TOC format (*.toc) ECRGTOC -raster- (rovs): ECRG TOC format (*.xml) - HFA -raster- (rw+v): Erdas Imagine Images (.img) (*.img) + HFA -raster- (rw+uv): Erdas Imagine Images (.img) (*.img) SAR_CEOS -raster- (rov): CEOS SAR Image CEOS -raster- (rov): CEOS Image JAXAPALSAR -raster- (rov): JAXA PALSAR Product Reader (Level 1.1/1.5) @@ -37,20 +37,20 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda AirSAR -raster- (rov): AirSAR Polarimetric Image RS2 -raster- (rovs): RadarSat 2 XML Product SAFE -raster- (rov): Sentinel-1 SAR SAFE Product - PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) + PCIDSK -raster,vector- (rw+uv): PCIDSK Database File (*.pix) PCRaster -raster- (rw+): PCRaster Raster File (*.map) ILWIS -raster- (rw+v): ILWIS Raster Map (*.mpr, *.mpl) SGI -raster- (rw+v): SGI Image File Format 1.0 (*.rgb) SRTMHGT -raster- (rwv): SRTMHGT File Format (*.hgt) Leveller -raster- (rw+v): Leveller heightfield (*.ter) Terragen -raster- (rw+v): Terragen heightfield (*.ter) - netCDF -raster,multidimensional raster,vector- (rw+s): Network Common Data Format (*.nc) + netCDF -raster,multidimensional raster,vector- (rw+us): Network Common Data Format (*.nc) HDF4 -raster,multidimensional raster- (ros): Hierarchical Data Format Release 4 (*.hdf) HDF4Image -raster- (rw+): HDF4 Dataset ISIS3 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 3) (*.lbl, *.cub) ISIS2 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 2) PDS -raster- (rov): NASA Planetary Data System - PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + PDS4 -raster,vector- (rw+uvs): NASA Planetary Data System 4 (*.xml) VICAR -raster,vector- (rw+v): MIPL VICAR file TIL -raster- (rov): EarthWatch .TIL ERS -raster- (rw+v): ERMapper .ers Labelled (*.ers) @@ -74,7 +74,7 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda MAP -raster- (rov): OziExplorer .MAP KMLSUPEROVERLAY -raster- (rwv): Kml Super Overlay (*.kml, *.kmz) WEBP -raster- (rwv): WEBP (*.webp) - PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + PDF -raster,vector- (rw+uvs): Geospatial PDF (*.pdf) Rasterlite -raster- (rwvs): Rasterlite (*.sqlite) MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) PLMOSAIC -raster- (ro): Planet Labs Mosaics API @@ -82,7 +82,7 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda WMTS -raster- (rwv): OGC Web Map Tile Service SENTINEL2 -raster- (rovs): Sentinel 2 MRF -raster- (rw+v): Meta Raster Format (*.mrf) - TileDB -raster,multidimensional raster,vector- (rw+vs): TileDB + TileDB -raster,multidimensional raster,vector- (rw+uvs): TileDB PNM -raster- (rw+v): Portable Pixmap Format (netpbm) (*.pgm, *.ppm, *.pnm) DOQ1 -raster- (rov): USGS DOQ (Old Style) DOQ2 -raster- (rov): USGS DOQ (New Style) @@ -106,13 +106,13 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda SNODAS -raster- (rov): Snow Data Assimilation System (*.hdr) KRO -raster- (rw+v): KOLOR Raw (*.kro) ROI_PAC -raster- (rw+v): ROI_PAC raster - RRASTER -raster- (rw+v): R Raster (*.grd) + RRASTER -raster- (rw+uv): R Raster (*.grd) BYN -raster- (rw+v): Natural Resources Canada's Geoid (*.byn, *.err) NOAA_B -raster- (rov): NOAA GEOCON/NADCON5 .b format (*.b) RIK -raster- (rov): Swedish Grid RIK (.rik) (*.rik) USGSDEM -raster- (rwv): USGS Optional ASCII DEM (and CDED) (*.dem) GXF -raster- (rov): GeoSoft Grid Exchange Format (*.gxf) - KEA -raster- (rw+v): KEA Image Format (.kea) (*.kea) + KEA -raster- (rw+uv): KEA Image Format (.kea) (*.kea) BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) S102 -raster,multidimensional raster- (rovs): S-102 Bathymetric Surface Product (*.h5) S104 -raster,multidimensional raster- (rov): S-104 Water Level Information for Surface Navigation Product (*.h5) @@ -143,15 +143,15 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda STACTA -raster- (rovs): Spatio-Temporal Asset Catalog Tiled Assets (*.json) STACIT -raster- (rovs): Spatio-Temporal Asset Catalog Items NSIDCbin -raster- (rov): NSIDC Sea Ice Concentrations binary (.bin) (*.bin) - GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) - OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + GPKG -raster,vector- (rw+uvs): GeoPackage (*.gpkg, *.gpkg.zip) + OpenFileGDB -raster,vector- (rw+uv): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) PLSCENES -raster,vector- (ro): Planet Labs Scenes API NGW -raster,vector- (rw+s): NextGIS Web GenBin -raster- (rov): Generic Binary (.hdr Labelled) - ENVI -raster- (rw+v): ENVI .hdr Labelled - EHdr -raster- (rw+v): ESRI .hdr Labelled (*.bil) + ENVI -raster- (rw+uv): ENVI .hdr Labelled + EHdr -raster- (rw+uv): ESRI .hdr Labelled (*.bil) ISCE -raster- (rw+v): ISCE raster - Zarr -raster,multidimensional raster- (rw+vs): Zarr + Zarr -raster,multidimensional raster- (rw+uvs): Zarr RCM -raster- (rovs): Radarsat Constellation Mission XML Product HTTP -raster,vector- (ro): HTTP Fetching Wrapper diff --git a/.github/workflows/windows_conda_expected_ogrinfo_formats.txt b/.github/workflows/windows_conda_expected_ogrinfo_formats.txt index 8835cecc2370..31b21a6d2c79 100644 --- a/.github/workflows/windows_conda_expected_ogrinfo_formats.txt +++ b/.github/workflows/windows_conda_expected_ogrinfo_formats.txt @@ -1,18 +1,18 @@ -Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) +Supported Formats: (ro:read-only, rw:read-write, +:write from scratch, u:update, v:virtual-I/O s:subdatasets) FITS -raster,vector- (rw+): Flexible Image Transport System (*.fits) - PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) - netCDF -raster,multidimensional raster,vector- (rw+s): Network Common Data Format (*.nc) - PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + PCIDSK -raster,vector- (rw+uv): PCIDSK Database File (*.pix) + netCDF -raster,multidimensional raster,vector- (rw+us): Network Common Data Format (*.nc) + PDS4 -raster,vector- (rw+uvs): NASA Planetary Data System 4 (*.xml) VICAR -raster,vector- (rw+v): MIPL VICAR file JP2OpenJPEG -raster,vector- (rwv): JPEG-2000 driver based on JP2OpenJPEG library (*.jp2, *.j2k) - PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + PDF -raster,vector- (rw+uvs): Geospatial PDF (*.pdf) MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) - TileDB -raster,multidimensional raster,vector- (rw+vs): TileDB + TileDB -raster,multidimensional raster,vector- (rw+uvs): TileDB BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) EEDA -vector- (ro): Earth Engine Data API OGCAPI -raster,vector- (rov): OGCAPI - ESRI Shapefile -vector- (rw+v): ESRI Shapefile (*.shp, *.dbf, *.shz, *.shp.zip) - MapInfo File -vector- (rw+v): MapInfo File (*.tab, *.mif, *.mid) + ESRI Shapefile -vector- (rw+uv): ESRI Shapefile (*.shp, *.dbf, *.shz, *.shp.zip) + MapInfo File -vector- (rw+uv): MapInfo File (*.tab, *.mif, *.mid) UK .NTF -vector- (rov): UK .NTF LVBAG -vector- (rov): Kadaster LV BAG Extract 2.0 (*.xml) OGR_SDTS -vector- (rov): SDTS @@ -20,26 +20,26 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda DGN -vector- (rw+v): Microstation DGN (*.dgn) OGR_VRT -vector- (rov): VRT - Virtual Datasource (*.vrt) Memory -vector- (rw+): Memory - CSV -vector- (rw+v): Comma Separated Value (.csv) (*.csv, *.tsv, *.psv) + CSV -vector- (rw+uv): Comma Separated Value (.csv) (*.csv, *.tsv, *.psv) NAS -vector- (rov): NAS - ALKIS (*.xml) GML -vector- (rw+v): Geography Markup Language (GML) (*.gml, *.xml) GPX -vector- (rw+v): GPX (*.gpx) KML -vector- (rw+v): Keyhole Markup Language (KML) (*.kml) - GeoJSON -vector- (rw+v): GeoJSON (*.json, *.geojson) + GeoJSON -vector- (rw+uv): GeoJSON (*.json, *.geojson) GeoJSONSeq -vector- (rw+v): GeoJSON Sequence (*.geojsonl, *.geojsons) ESRIJSON -vector- (rov): ESRIJSON (*.json) TopoJSON -vector- (rov): TopoJSON (*.json, *.topojson) Interlis 1 -vector- (rov): Interlis 1 (*.itf, *.ili) Interlis 2 -vector- (rov): Interlis 2 (*.xtf, *.xml, *.ili) OGR_GMT -vector- (rw+v): GMT ASCII Vectors (.gmt) (*.gmt) - GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) - SQLite -vector- (rw+v): SQLite / Spatialite (*.sqlite, *.db) + GPKG -raster,vector- (rw+uvs): GeoPackage (*.gpkg, *.gpkg.zip) + SQLite -vector- (rw+uv): SQLite / Spatialite (*.sqlite, *.db) ODBC -vector- (ro): Open Database Connectivity (ODBC) (*.mdb, *.accdb) WAsP -vector- (rw+v): WAsP .map format (*.map) PGeo -vector- (ro): ESRI Personal GeoDatabase (*.mdb) - MSSQLSpatial -vector- (rw+): Microsoft SQL Server Spatial Database (BCP) - PostgreSQL -vector- (rw+): PostgreSQL/PostGIS - OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + MSSQLSpatial -vector- (rw+u): Microsoft SQL Server Spatial Database (BCP) + PostgreSQL -vector- (rw+u): PostgreSQL/PostGIS + OpenFileGDB -raster,vector- (rw+uv): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) DXF -vector- (rw+v): AutoCAD DXF (*.dxf) CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) FlatGeobuf -vector- (rw+v): FlatGeobuf (*.fgb) @@ -56,8 +56,8 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda SVG -vector- (rov): Scalable Vector Graphics (*.svg) Idrisi -vector- (rov): Idrisi Vector (.vct) (*.vct) XLS -vector- (ro): MS Excel format (*.xls) - ODS -vector- (rw+v): Open Document/ LibreOffice / OpenOffice Spreadsheet (*.ods) - XLSX -vector- (rw+v): MS Office Open XML spreadsheet (*.xlsx, *.xlsm) + ODS -vector- (rw+uv): Open Document/ LibreOffice / OpenOffice Spreadsheet (*.ods) + XLSX -vector- (rw+uv): MS Office Open XML spreadsheet (*.xlsx, *.xlsm) Elasticsearch -vector- (rw+): Elastic Search Carto -vector- (rw+): Carto AmigoCloud -vector- (rw+): AmigoCloud diff --git a/autotest/utilities/test_gdalinfo.py b/autotest/utilities/test_gdalinfo.py index 9e0447302d48..c39d23f15de3 100755 --- a/autotest/utilities/test_gdalinfo.py +++ b/autotest/utilities/test_gdalinfo.py @@ -328,7 +328,7 @@ def test_gdalinfo_19(gdalinfo_path, tmp_path): def test_gdalinfo_20(gdalinfo_path): ret = gdaltest.runexternal(gdalinfo_path + " --formats", check_memleak=False) - assert "GTiff -raster- (rw+vs): GeoTIFF" in ret + assert "GTiff -raster- (rw+uvs): GeoTIFF" in ret ############################################################################### @@ -345,7 +345,7 @@ def test_gdalinfo_formats_json(gdalinfo_path): "short_name": "VRT", "long_name": "Virtual Raster", "scopes": ["raster", "multidimensional_raster"], - "capabilities": ["open", "create", "create_copy", "virtual_io"], + "capabilities": ["open", "create", "create_copy", "update", "virtual_io"], "file_extensions": ["vrt"], } in ret diff --git a/autotest/utilities/test_ogrinfo.py b/autotest/utilities/test_ogrinfo.py index bdb9d089cc28..6402127c05d5 100755 --- a/autotest/utilities/test_ogrinfo.py +++ b/autotest/utilities/test_ogrinfo.py @@ -305,7 +305,7 @@ def test_ogrinfo_18(ogrinfo_path, tmp_path): def test_ogrinfo_19(ogrinfo_path): ret = gdaltest.runexternal(ogrinfo_path + " --formats", check_memleak=False) - assert "ESRI Shapefile -vector- (rw+v): ESRI Shapefile" in ret + assert "ESRI Shapefile -vector- (rw+uv): ESRI Shapefile" in ret ############################################################################### @@ -322,7 +322,7 @@ def test_ogrinfo_formats_json(ogrinfo_path): "short_name": "ESRI Shapefile", "long_name": "ESRI Shapefile", "scopes": ["vector"], - "capabilities": ["open", "create", "virtual_io"], + "capabilities": ["open", "create", "update", "virtual_io"], "file_extensions": ["shp", "dbf", "shz", "shp.zip"], } in ret diff --git a/frmts/ecw/ecwdrivercore.cpp b/frmts/ecw/ecwdrivercore.cpp index ef23df51434a..d26147e27d1a 100644 --- a/frmts/ecw/ecwdrivercore.cpp +++ b/frmts/ecw/ecwdrivercore.cpp @@ -115,6 +115,11 @@ void ECWDriverSetCommonMetadata(GDALDriver *poDriver) // for ECWCreateCopyECW(). poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); #endif + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS " + "DatasetMetadata BandMetadata"); } /************************************************************************/ diff --git a/frmts/gtiff/geotiff.cpp b/frmts/gtiff/geotiff.cpp index 225d00dfa304..e7b66cb0bc05 100644 --- a/frmts/gtiff/geotiff.cpp +++ b/frmts/gtiff/geotiff.cpp @@ -1495,6 +1495,12 @@ void GDALRegister_GTiff() poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS GCPs NoData " + "ColorInterpretation RasterValues " + "DatasetMetadata BandMetadata"); + #ifdef INTERNAL_LIBTIFF poDriver->SetMetadataItem("LIBTIFF", "INTERNAL"); #else diff --git a/frmts/hfa/hfadataset.cpp b/frmts/hfa/hfadataset.cpp index 132796775eb0..ab72254bd0f5 100644 --- a/frmts/hfa/hfadataset.cpp +++ b/frmts/hfa/hfadataset.cpp @@ -5233,6 +5233,12 @@ void GDALRegister_HFA() poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS NoData " + "RasterValues " + "DatasetMetadata BandMetadata"); + poDriver->pfnOpen = HFADataset::Open; poDriver->pfnCreate = HFADataset::Create; poDriver->pfnCreateCopy = HFADataset::CreateCopy; diff --git a/frmts/kea/keadrivercore.cpp b/frmts/kea/keadrivercore.cpp index 6a8fb591255e..b96f0cf30344 100644 --- a/frmts/kea/keadrivercore.cpp +++ b/frmts/kea/keadrivercore.cpp @@ -84,6 +84,12 @@ void KEADriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS GCPs NoData " + "ColorInterpretation RasterValues " + "DatasetMetadata BandMetadata"); } /************************************************************************/ diff --git a/frmts/netcdf/netcdfdrivercore.cpp b/frmts/netcdf/netcdfdrivercore.cpp index 3c47fb1993db..235edc01fa6f 100644 --- a/frmts/netcdf/netcdfdrivercore.cpp +++ b/frmts/netcdf/netcdfdrivercore.cpp @@ -568,6 +568,11 @@ void netCDFDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE_MULTIDIMENSIONAL, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS " // if not already set... + "DatasetMetadata BandMetadata RasterValues"); } /************************************************************************/ diff --git a/frmts/nitf/nitfdrivercore.cpp b/frmts/nitf/nitfdrivercore.cpp index 9fbdeeefdee0..0b329b7c5f48 100644 --- a/frmts/nitf/nitfdrivercore.cpp +++ b/frmts/nitf/nitfdrivercore.cpp @@ -98,6 +98,9 @@ void NITFDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "RasterValues"); } /************************************************************************/ diff --git a/frmts/pcidsk/pcidskdrivercore.cpp b/frmts/pcidsk/pcidskdrivercore.cpp index e1e8eaca0e9b..b1eb1224985f 100644 --- a/frmts/pcidsk/pcidskdrivercore.cpp +++ b/frmts/pcidsk/pcidskdrivercore.cpp @@ -73,6 +73,12 @@ void PCIDSKDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = PCIDSKDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS " + "DatasetMetadata BandMetadata " + "RasterValues Features"); } /************************************************************************/ diff --git a/frmts/pdf/pdfdrivercore.cpp b/frmts/pdf/pdfdrivercore.cpp index 2cf400c959e3..fdfda5f3a5e8 100644 --- a/frmts/pdf/pdfdrivercore.cpp +++ b/frmts/pdf/pdfdrivercore.cpp @@ -230,6 +230,10 @@ void PDFDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS GCPs DatasetMetadata"); #endif poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); diff --git a/frmts/raw/ehdrdataset.cpp b/frmts/raw/ehdrdataset.cpp index c81e132c1e8a..5304be76f2b2 100644 --- a/frmts/raw/ehdrdataset.cpp +++ b/frmts/raw/ehdrdataset.cpp @@ -2030,6 +2030,10 @@ void GDALRegister_EHdr() "signed byte'/>" ""); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "GeoTransform SRS NoData " + "RasterValues"); + poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); poDriver->pfnOpen = EHdrDataset::Open; poDriver->pfnCreate = EHdrDataset::Create; diff --git a/frmts/raw/envidataset.cpp b/frmts/raw/envidataset.cpp index 184682e29b62..b43078c342a2 100644 --- a/frmts/raw/envidataset.cpp +++ b/frmts/raw/envidataset.cpp @@ -2941,6 +2941,11 @@ void GDALRegister_ENVI() " " ""); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS GCPs NoData " + "RasterValues DatasetMetadata"); + poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); poDriver->pfnOpen = ENVIDataset::Open; poDriver->pfnCreate = ENVIDataset::Create; diff --git a/frmts/raw/rrasterdataset.cpp b/frmts/raw/rrasterdataset.cpp index 198373f28ab7..2dcb768404ec 100644 --- a/frmts/raw/rrasterdataset.cpp +++ b/frmts/raw/rrasterdataset.cpp @@ -1555,5 +1555,10 @@ void GDALRegister_RRASTER() poDriver->pfnCreate = RRASTERDataset::Create; poDriver->pfnCreateCopy = RRASTERDataset::CreateCopy; + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "GeoTransform SRS NoData " + "RasterValues " + "DatasetMetadata"); + GetGDALDriverManager()->RegisterDriver(poDriver); } diff --git a/frmts/tiledb/tiledbdrivercore.cpp b/frmts/tiledb/tiledbdrivercore.cpp index 8aae2445faf1..0109c8f58fab 100644 --- a/frmts/tiledb/tiledbdrivercore.cpp +++ b/frmts/tiledb/tiledbdrivercore.cpp @@ -264,6 +264,9 @@ void TileDBDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "RasterValues Features"); + poDriver->SetMetadataItem( "TILEDB_VERSION", STRINGIFY(TILEDB_VERSION_MAJOR) "." STRINGIFY( diff --git a/frmts/vrt/vrtdriver.cpp b/frmts/vrt/vrtdriver.cpp index c084db88712a..b262b412ec40 100644 --- a/frmts/vrt/vrtdriver.cpp +++ b/frmts/vrt/vrtdriver.cpp @@ -552,6 +552,12 @@ void GDALRegister_VRT() poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_COORDINATE_EPOCH, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS GCPs NoData " + "ColorInterpretation " + "DatasetMetadata BandMetadata"); + const char *pszExpressionDialects = "ExpressionDialects"; #if defined(GDAL_VRT_ENABLE_MUPARSER) && defined(GDAL_VRT_ENABLE_EXPRTK) poDriver->SetMetadataItem(pszExpressionDialects, "muparser,exprtk"); diff --git a/frmts/zarr/zarrdrivercore.cpp b/frmts/zarr/zarrdrivercore.cpp index 81ddbca4f8ab..f9f6b896240c 100644 --- a/frmts/zarr/zarrdrivercore.cpp +++ b/frmts/zarr/zarrdrivercore.cpp @@ -112,6 +112,12 @@ void ZARRDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE_MULTIDIMENSIONAL, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "GeoTransform SRS NoData " + "RasterValues " + "DatasetMetadata BandMetadata"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp b/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp index 16160fb9833f..1c78e1e6a40c 100644 --- a/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp +++ b/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp @@ -446,6 +446,9 @@ void RegisterOGRCSV() "Boolean Int16 Float32"); poDriver->SetMetadataItem(GDAL_DCAP_HONOR_GEOM_COORDINATE_PRECISION, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->pfnOpen = OGRCSVDriverOpen; poDriver->pfnIdentify = OGRCSVDriverIdentify; poDriver->pfnCreate = OGRCSVDriverCreate; diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsondriver.cpp b/ogr/ogrsf_frmts/geojson/ogrgeojsondriver.cpp index 1b993844a311..df6c72c6fe1b 100644 --- a/ogr/ogrsf_frmts/geojson/ogrgeojsondriver.cpp +++ b/ogr/ogrsf_frmts/geojson/ogrgeojsondriver.cpp @@ -789,6 +789,9 @@ void RegisterOGRGeoJSON() poDriver->SetMetadataItem(GDAL_DCAP_FLUSHCACHE_CONSISTENT_STATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_HONOR_GEOM_COORDINATE_PRECISION, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->pfnOpen = OGRGeoJSONDriverOpen; poDriver->pfnIdentify = OGRGeoJSONDriverIdentify; poDriver->pfnCreate = OGRGeoJSONDriverCreate; diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagedriver.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagedriver.cpp index 5995438d38df..9752b6d1e780 100644 --- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagedriver.cpp +++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagedriver.cpp @@ -750,6 +750,11 @@ void RegisterOGRGeoPackage() poDriver->SetMetadataItem("SQLITE_HAS_COLUMN_METADATA", "YES"); #endif + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, + "DatasetMetadata BandMetadata RasterValues " + "LayerMetadata Features"); + poDriver->pfnOpen = OGRGeoPackageDriverOpen; poDriver->pfnIdentify = OGRGeoPackageDriverIdentify; poDriver->pfnCreate = OGRGeoPackageDriverCreate; diff --git a/ogr/ogrsf_frmts/hana/ogrhanadrivercore.cpp b/ogr/ogrsf_frmts/hana/ogrhanadrivercore.cpp index 9b004ae1adc9..8617a54ea4d5 100644 --- a/ogr/ogrsf_frmts/hana/ogrhanadrivercore.cpp +++ b/ogr/ogrsf_frmts/hana/ogrhanadrivercore.cpp @@ -115,6 +115,9 @@ void OGRHANADriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGRHanaDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/libkml/ogrlibkmldrivercore.cpp b/ogr/ogrsf_frmts/libkml/ogrlibkmldrivercore.cpp index 1f02330e24cb..6946bed2f566 100644 --- a/ogr/ogrsf_frmts/libkml/ogrlibkmldrivercore.cpp +++ b/ogr/ogrsf_frmts/libkml/ogrlibkmldrivercore.cpp @@ -302,6 +302,9 @@ void OGRLIBKMLDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGRLIBKMLDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/mitab/mitab_ogr_driver.cpp b/ogr/ogrsf_frmts/mitab/mitab_ogr_driver.cpp index 00958b20adee..06d3f9fe1212 100644 --- a/ogr/ogrsf_frmts/mitab/mitab_ogr_driver.cpp +++ b/ogr/ogrsf_frmts/mitab/mitab_ogr_driver.cpp @@ -252,6 +252,9 @@ void RegisterOGRTAB() poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_READ, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_WRITE, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->pfnOpen = OGRTABDriverOpen; poDriver->pfnIdentify = OGRTABDriverIdentify; poDriver->pfnCreate = OGRTABDriverCreate; diff --git a/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialdrivercore.cpp b/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialdrivercore.cpp index 7a316cdf7d27..42ab6ecbbd39 100644 --- a/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialdrivercore.cpp +++ b/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialdrivercore.cpp @@ -113,6 +113,9 @@ void OGRMSSQLSPATIALDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGRMSSQLSPATIALDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/mysql/ogrmysqldrivercore.cpp b/ogr/ogrsf_frmts/mysql/ogrmysqldrivercore.cpp index a88f05991cce..f7f2cada2343 100644 --- a/ogr/ogrsf_frmts/mysql/ogrmysqldrivercore.cpp +++ b/ogr/ogrsf_frmts/mysql/ogrmysqldrivercore.cpp @@ -93,6 +93,9 @@ void OGRMySQLDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGRMySQLDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/oci/ogrocidrivercore.cpp b/ogr/ogrsf_frmts/oci/ogrocidrivercore.cpp index 80a445636eed..a9bff9bf4a2c 100644 --- a/ogr/ogrsf_frmts/oci/ogrocidrivercore.cpp +++ b/ogr/ogrsf_frmts/oci/ogrocidrivercore.cpp @@ -124,6 +124,9 @@ void OGROCIDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGROCIDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/openfilegdb/ogropenfilegdbdrivercore.cpp b/ogr/ogrsf_frmts/openfilegdb/ogropenfilegdbdrivercore.cpp index 1d9736ee0dd3..fbac8037c310 100644 --- a/ogr/ogrsf_frmts/openfilegdb/ogropenfilegdbdrivercore.cpp +++ b/ogr/ogrsf_frmts/openfilegdb/ogropenfilegdbdrivercore.cpp @@ -281,6 +281,9 @@ void OGROpenFileGDBDriverSetCommonMetadata(GDALDriver *poDriver) "fields' default='NO'/>" ""); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + // Setting to another value than the default one doesn't really work // with the SDK // Option name='AREA_FIELD_NAME' type='string' description='Name of diff --git a/ogr/ogrsf_frmts/pg/ogrpgdrivercore.cpp b/ogr/ogrsf_frmts/pg/ogrpgdrivercore.cpp index 552a80540881..b2038a18a179 100644 --- a/ogr/ogrsf_frmts/pg/ogrpgdrivercore.cpp +++ b/ogr/ogrsf_frmts/pg/ogrpgdrivercore.cpp @@ -164,6 +164,9 @@ void OGRPGDriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGRPGDriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "LayerMetadata Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp b/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp index b51bdf35fd45..920fbd593da8 100644 --- a/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp +++ b/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp @@ -423,6 +423,9 @@ void RegisterOGRShape() poDriver->SetMetadataItem(GDAL_DMD_ALTER_GEOM_FIELD_DEFN_FLAGS, "SRS"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->pfnOpen = OGRShapeDriverOpen; poDriver->pfnIdentify = OGRShapeDriverIdentify; poDriver->pfnCreate = OGRShapeDriverCreate; diff --git a/ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.cpp b/ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.cpp index d83156fb6bc7..91cdca233490 100644 --- a/ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.cpp +++ b/ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.cpp @@ -470,6 +470,9 @@ void RegisterOGRSQLite() poDriver->SetMetadataItem("SQLITE_HAS_COLUMN_METADATA", "YES"); #endif + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->pfnOpen = OGRSQLiteDriverOpen; poDriver->pfnIdentify = OGRSQLiteDriverIdentify; poDriver->pfnCreate = OGRSQLiteDriverCreate; From c056f7d9023432bc4fa68e0dc1fd1b88cc083777 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Jan 2025 18:21:41 +0100 Subject: [PATCH 5/7] VDV: make driver not report OLCRandomWrite on IDF datasets --- frmts/pds/pdsdrivercore.cpp | 3 +++ ogr/ogrsf_frmts/mem/ogr_mem.h | 3 +++ ogr/ogrsf_frmts/mem/ogrmemdatasource.cpp | 17 +++++++++++++++++ .../mongodbv3/ogrmongodbv3drivercore.cpp | 3 +++ ogr/ogrsf_frmts/ods/ogrodsdriver.cpp | 3 +++ ogr/ogrsf_frmts/vdv/ogrvdvdatasource.cpp | 5 +++++ ogr/ogrsf_frmts/xlsx/ogrxlsxdriver.cpp | 3 +++ 7 files changed, 37 insertions(+) diff --git a/frmts/pds/pdsdrivercore.cpp b/frmts/pds/pdsdrivercore.cpp index 1c036758f427..7ffc3322eeae 100644 --- a/frmts/pds/pdsdrivercore.cpp +++ b/frmts/pds/pdsdrivercore.cpp @@ -318,6 +318,9 @@ void PDS4DriverSetCommonMetadata(GDALDriver *poDriver) poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/mem/ogr_mem.h b/ogr/ogrsf_frmts/mem/ogr_mem.h index 432601fb43f3..5e3cfb96eb68 100644 --- a/ogr/ogrsf_frmts/mem/ogr_mem.h +++ b/ogr/ogrsf_frmts/mem/ogr_mem.h @@ -185,6 +185,9 @@ class OGRMemDataSource CPL_NON_FINAL : public GDALDataset int TestCapability(const char *) override; + OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter, + const char *pszDialect) override; + bool AddFieldDomain(std::unique_ptr &&domain, std::string &failureReason) override; diff --git a/ogr/ogrsf_frmts/mem/ogrmemdatasource.cpp b/ogr/ogrsf_frmts/mem/ogrmemdatasource.cpp index 636ca4e3ea4a..3593f3943e4e 100644 --- a/ogr/ogrsf_frmts/mem/ogrmemdatasource.cpp +++ b/ogr/ogrsf_frmts/mem/ogrmemdatasource.cpp @@ -219,3 +219,20 @@ bool OGRMemDataSource::UpdateFieldDomain( m_oMapFieldDomains[domainName] = std::move(domain); return true; } + +/************************************************************************/ +/* ExecuteSQL() */ +/************************************************************************/ + +OGRLayer *OGRMemDataSource::ExecuteSQL(const char *pszStatement, + OGRGeometry *poSpatialFilter, + const char *pszDialect) +{ + if (EQUAL(pszStatement, "PRAGMA read_only=1")) // as used by VDV driver + { + for (int i = 0; i < nLayers; ++i) + papoLayers[i]->SetUpdatable(false); + return nullptr; + } + return GDALDataset::ExecuteSQL(pszStatement, poSpatialFilter, pszDialect); +} diff --git a/ogr/ogrsf_frmts/mongodbv3/ogrmongodbv3drivercore.cpp b/ogr/ogrsf_frmts/mongodbv3/ogrmongodbv3drivercore.cpp index 2c4c142d882d..20b97007497b 100644 --- a/ogr/ogrsf_frmts/mongodbv3/ogrmongodbv3drivercore.cpp +++ b/ogr/ogrsf_frmts/mongodbv3/ogrmongodbv3drivercore.cpp @@ -117,6 +117,9 @@ void OGRMongoDBv3DriverSetCommonMetadata(GDALDriver *poDriver) poDriver->pfnIdentify = OGRMongoDBv3DriverIdentify; poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); + + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); } /************************************************************************/ diff --git a/ogr/ogrsf_frmts/ods/ogrodsdriver.cpp b/ogr/ogrsf_frmts/ods/ogrodsdriver.cpp index af7625b12dcf..77ade27cac94 100644 --- a/ogr/ogrsf_frmts/ods/ogrodsdriver.cpp +++ b/ogr/ogrsf_frmts/ods/ogrodsdriver.cpp @@ -240,6 +240,9 @@ void RegisterOGRODS() poDriver->SetMetadataItem(GDAL_DMD_ALTER_FIELD_DEFN_FLAGS, "Name Type"); poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->SetMetadataItem( GDAL_DMD_OPENOPTIONLIST, "" diff --git a/ogr/ogrsf_frmts/vdv/ogrvdvdatasource.cpp b/ogr/ogrsf_frmts/vdv/ogrvdvdatasource.cpp index 040e1d0426bb..60a6e0654e23 100644 --- a/ogr/ogrsf_frmts/vdv/ogrvdvdatasource.cpp +++ b/ogr/ogrsf_frmts/vdv/ogrvdvdatasource.cpp @@ -226,8 +226,10 @@ void OGRIDFDataSource::Parse() } } + bool bIsMEMLayer = false; if (m_poTmpDS == nullptr) { + bIsMEMLayer = true; m_poTmpDS = poMEMDriver->Create("", 0, 0, 0, GDT_Unknown, nullptr); } @@ -583,6 +585,9 @@ void OGRIDFDataSource::Parse() m_poTmpDS->CommitTransaction(); + if (bIsMEMLayer) + m_poTmpDS->ExecuteSQL("PRAGMA read_only=1", nullptr, nullptr); + std::map::iterator oMapLinkCoordinateIter = oMapLinkCoordinate.begin(); for (; oMapLinkCoordinateIter != oMapLinkCoordinate.end(); diff --git a/ogr/ogrsf_frmts/xlsx/ogrxlsxdriver.cpp b/ogr/ogrsf_frmts/xlsx/ogrxlsxdriver.cpp index d969a9c6b457..bdad9da84f54 100644 --- a/ogr/ogrsf_frmts/xlsx/ogrxlsxdriver.cpp +++ b/ogr/ogrsf_frmts/xlsx/ogrxlsxdriver.cpp @@ -247,6 +247,9 @@ void RegisterOGRXLSX() poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); + poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES"); + poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features"); + poDriver->SetMetadataItem( GDAL_DMD_OPENOPTIONLIST, "" From dbbda6e52dd7776adca871a51bcdd07085c6ab67 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Jan 2025 15:48:17 +0100 Subject: [PATCH 6/7] Test infrastructure: check GDAL_DCAP_UPDATE and GDAL_DMD_UPDATE_ITEMS --- apps/test_ogrsf.cpp | 19 +++++++ autotest/gcore/misc.py | 68 +++++++++++++++++++++++++- autotest/gcore/test_driver_metadata.py | 27 ++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/apps/test_ogrsf.cpp b/apps/test_ogrsf.cpp index 777964088bfd..5983650038fe 100644 --- a/apps/test_ogrsf.cpp +++ b/apps/test_ogrsf.cpp @@ -4436,6 +4436,25 @@ static int TestOGRLayer(GDALDataset *poDS, OGRLayer *poLayer, int bIsSQLLayer) /* -------------------------------------------------------------------- */ if (LOG_ACTION(poLayer->TestCapability(OLCRandomWrite))) { + if (!poDS->GetDriver()->GetMetadataItem(GDAL_DCAP_UPDATE)) + { + printf("ERROR: Driver %s does not declare GDAL_DCAP_UPDATE\n", + poDS->GetDriver()->GetDescription()); + bRet = false; + } + else + { + const char *pszItems = + poDS->GetDriver()->GetMetadataItem(GDAL_DMD_UPDATE_ITEMS); + if (!pszItems || !strstr(pszItems, "Features")) + { + printf("ERROR: Driver %s does not declare Features in " + "GDAL_DMD_UPDATE_ITEMS\n", + poDS->GetDriver()->GetDescription()); + bRet = false; + } + } + bRet &= TestOGRLayerRandomWrite(poLayer); } diff --git a/autotest/gcore/misc.py b/autotest/gcore/misc.py index 54fd91bfde6e..380f6d4f3f1c 100755 --- a/autotest/gcore/misc.py +++ b/autotest/gcore/misc.py @@ -19,7 +19,7 @@ import gdaltest import pytest -from osgeo import gdal +from osgeo import gdal, osr ############################################################################### @@ -118,6 +118,10 @@ def get_filename(drv, dirname): filename += ".kmz" elif drv.ShortName == "RRASTER": filename += ".grd" + elif drv.ShortName == "KEA": + filename += ".kea" + elif drv.ShortName == "GPKG": + filename += ".gpkg" return filename @@ -314,6 +318,66 @@ def misc_6_internal(datatype, nBands, setDriversDone): dst_ds.GetMetadataItem("", None) dst_ds = None + if ( + has_succeeded + and nBands > 0 + and "DCAP_UPDATE" in md + and drv.ShortName + not in ( + "VRT", + "GPKG", + ) + ): + update_ds = gdal.Open(filename, gdal.GA_Update) + assert update_ds, (drv.ShortName, filename) + + flags_str = drv.GetMetadataItem(gdal.DMD_UPDATE_ITEMS) + if update_ds.RasterCount and "RasterValues" in flags_str: + assert ( + update_ds.GetRasterBand(1).WriteRaster( + 0, 0, 1, 1, b"\x00", buf_type=gdal.GDT_Byte + ) + == gdal.CE_None + ), (drv.ShortName, filename) + + if "GeoTransform" in flags_str and drv.ShortName not in ("netCDF",): + assert ( + update_ds.SetGeoTransform([0, 1, 0, 0, 0, -1]) == gdal.CE_None + ), ( + drv.ShortName, + filename, + ) + + if "SRS" in flags_str and drv.ShortName not in ("netCDF",): + srs = osr.SpatialReference() + srs.SetFromUserInput("WGS84") + assert update_ds.SetSpatialRef(srs) == gdal.CE_None, ( + drv.ShortName, + filename, + ) + + if update_ds.RasterCount and "NoData" in flags_str: + assert ( + update_ds.GetRasterBand(1).SetNoDataValue(0) == gdal.CE_None + ), ( + drv.ShortName, + filename, + ) + + if "DatasetMetadata" in flags_str: + assert update_ds.SetMetadata({"FOO": "BAR"}) == gdal.CE_None, ( + drv.ShortName, + filename, + ) + + if update_ds.RasterCount and "BandMetadata" in flags_str: + assert ( + update_ds.GetRasterBand(1).SetMetadata({"FOO": "BAR"}) + == gdal.CE_None + ), (drv.ShortName, filename) + + update_ds.Close() + size = 0 stat = gdal.VSIStatL(filename) if stat is not None: @@ -400,6 +464,7 @@ def misc_6_internal(datatype, nBands, setDriversDone): "USGSDEM", "KMLSUPEROVERLAY", "GMT", + "NULL", ]: dst_ds = drv.CreateCopy( filename, ds, callback=misc_6_interrupt_callback_class().cbk @@ -440,6 +505,7 @@ def misc_6_internal(datatype, nBands, setDriversDone): ) ) pytest.fail(reason) + ds = None diff --git a/autotest/gcore/test_driver_metadata.py b/autotest/gcore/test_driver_metadata.py index b8907c47e938..0d106228eb27 100644 --- a/autotest/gcore/test_driver_metadata.py +++ b/autotest/gcore/test_driver_metadata.py @@ -643,3 +643,30 @@ def test_metadata_creation_field_defn_flags(driver_name): if flags_str is not None: for flag in flags_str.split(" "): assert flag in supported_flags + + +@pytest.mark.parametrize("driver_name", ogr_driver_names) +def test_metadata_update_items(driver_name): + """Test if DMD_UPDATE_ITEMS metadataitem returns valid flags""" + + supported_flags = { + "GeoTransform", + "SRS", + "GCPs", + "NoData", + "ColorInterpretation", + "RasterValues", + "DatasetMetadata", + "BandMetadata", + "Features", + "LayerMetadata", + } + + driver = gdal.GetDriverByName(driver_name) + flags_str = driver.GetMetadataItem(gdal.DMD_UPDATE_ITEMS) + if flags_str is not None: + assert driver.GetMetadataItem(gdal.DCAP_UPDATE) + for flag in flags_str.split(" "): + assert flag in supported_flags + else: + assert not driver.GetMetadataItem(gdal.DCAP_UPDATE) From 0bfd41a3cd3a8834a0fcb5322ea962f315d4f7dd Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 26 Jan 2025 02:10:05 +0100 Subject: [PATCH 7/7] Add GDALDataset::ReportUpdateNotSupportedByDriver() and use it in drivers --- frmts/adrg/adrgdataset.cpp | 4 +--- frmts/adrg/srpdataset.cpp | 4 +--- frmts/aigrid/aigdataset.cpp | 4 +--- frmts/airsar/airsardataset.cpp | 4 +--- frmts/blx/blxdataset.cpp | 4 +--- frmts/bsb/bsbdataset.cpp | 4 +--- frmts/ceos/ceosdataset.cpp | 4 +--- frmts/ceos2/sar_ceosdataset.cpp | 5 +---- frmts/coasp/coasp_dataset.cpp | 4 +--- frmts/cosar/cosar_dataset.cpp | 4 +--- frmts/ctg/ctgdataset.cpp | 4 +--- frmts/dimap/dimapdataset.cpp | 4 +--- frmts/envisat/envisatdataset.cpp | 4 +--- frmts/fit/fitdataset.cpp | 4 +--- frmts/gff/gff_dataset.cpp | 4 +--- frmts/gif/biggifdataset.cpp | 4 +--- frmts/gif/gifdataset.cpp | 4 +--- frmts/grib/gribdataset.cpp | 4 +--- frmts/gxf/gxfdataset.cpp | 4 +--- frmts/hdf4/hdf4dataset.cpp | 4 +--- frmts/hdf5/bagdataset.cpp | 3 +-- frmts/hdf5/hdf5dataset.cpp | 4 +--- frmts/hdf5/hdf5imagedataset.cpp | 4 +--- frmts/hdf5/s102dataset.cpp | 3 +-- frmts/hdf5/s104dataset.cpp | 3 +-- frmts/hdf5/s111dataset.cpp | 3 +-- frmts/iris/irisdataset.cpp | 4 +--- frmts/jaxapalsar/jaxapalsardataset.cpp | 5 +---- frmts/jdem/jdemdataset.cpp | 4 +--- frmts/jpeg/jpgdataset.cpp | 4 +--- frmts/l1b/l1bdataset.cpp | 4 +--- frmts/map/mapdataset.cpp | 4 +--- frmts/msg/msgdataset.cpp | 4 +--- frmts/msgn/msgndataset.cpp | 4 +--- frmts/ngsgeoid/ngsgeoiddataset.cpp | 5 +---- frmts/nitf/ecrgtocdataset.cpp | 3 +-- frmts/nitf/rpftocdataset.cpp | 6 ++---- frmts/png/pngdataset.cpp | 4 +--- frmts/r/rdataset.cpp | 4 +--- frmts/raw/cpgdataset.cpp | 4 +--- frmts/raw/doq1dataset.cpp | 4 +--- frmts/raw/doq2dataset.cpp | 8 ++------ frmts/raw/eirdataset.cpp | 4 +--- frmts/raw/fastdataset.cpp | 4 +--- frmts/raw/gscdataset.cpp | 4 +--- frmts/raw/lcpdataset.cpp | 4 +--- frmts/raw/loslasdataset.cpp | 4 +--- frmts/raw/ndfdataset.cpp | 8 ++------ frmts/raw/nsidcbindataset.cpp | 5 +---- frmts/raw/snodasdataset.cpp | 4 +--- frmts/rcm/rcmdataset.cpp | 4 +--- frmts/rdb/rdbdataset.cpp | 4 +--- frmts/rik/rikdataset.cpp | 4 +--- frmts/rs2/rs2dataset.cpp | 4 +--- frmts/safe/safedataset.cpp | 4 +--- frmts/sdts/sdtsdataset.cpp | 4 +--- frmts/til/tildataset.cpp | 4 +--- frmts/tsx/tsxdataset.cpp | 4 +--- frmts/usgsdem/usgsdemdataset.cpp | 4 +--- frmts/wcs/wcsdataset.cpp | 4 +--- frmts/webp/webpdataset.cpp | 4 +--- frmts/wms/wmsdriver.cpp | 4 +--- frmts/xpm/xpmdataset.cpp | 4 +--- frmts/xyz/xyzdataset.cpp | 4 +--- frmts/zmap/zmapdataset.cpp | 4 +--- gcore/gdal_priv.h | 2 ++ gcore/gdaldataset.cpp | 17 +++++++++++++++++ ogr/ogrsf_frmts/cad/ogrcaddriver.cpp | 4 +--- ogr/ogrsf_frmts/miramon/ogrmiramondriver.cpp | 3 +-- 69 files changed, 89 insertions(+), 206 deletions(-) diff --git a/frmts/adrg/adrgdataset.cpp b/frmts/adrg/adrgdataset.cpp index dde59c560a9d..3300b15d0efc 100644 --- a/frmts/adrg/adrgdataset.cpp +++ b/frmts/adrg/adrgdataset.cpp @@ -1616,9 +1616,7 @@ GDALDataset *ADRGDataset::Open(GDALOpenInfo *poOpenInfo) { if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The ADRG driver does not support update access to " - "existing datasets."); + ReportUpdateNotSupportedByDriver("ADRG"); return nullptr; } diff --git a/frmts/adrg/srpdataset.cpp b/frmts/adrg/srpdataset.cpp index d0d4ad1300ba..c51daeb2f004 100644 --- a/frmts/adrg/srpdataset.cpp +++ b/frmts/adrg/srpdataset.cpp @@ -1615,9 +1615,7 @@ GDALDataset *SRPDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The SRP driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("SRP"); return nullptr; } diff --git a/frmts/aigrid/aigdataset.cpp b/frmts/aigrid/aigdataset.cpp index b5f5faae53c5..a09a237af3a5 100644 --- a/frmts/aigrid/aigdataset.cpp +++ b/frmts/aigrid/aigdataset.cpp @@ -636,9 +636,7 @@ GDALDataset *AIGDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { AIGClose(psInfo); - CPLError(CE_Failure, CPLE_NotSupported, - "The AIG driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("AIG"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/airsar/airsardataset.cpp b/frmts/airsar/airsardataset.cpp index 8043cf428638..b0e5451c849e 100644 --- a/frmts/airsar/airsardataset.cpp +++ b/frmts/airsar/airsardataset.cpp @@ -523,9 +523,7 @@ GDALDataset *AirSARDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The AIRSAR driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("AIRSAR"); CSLDestroy(papszMD); return nullptr; } diff --git a/frmts/blx/blxdataset.cpp b/frmts/blx/blxdataset.cpp index 9342391baa28..247cbaf2c59d 100644 --- a/frmts/blx/blxdataset.cpp +++ b/frmts/blx/blxdataset.cpp @@ -124,9 +124,7 @@ GDALDataset *BLXDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { delete poDS; - CPLError(CE_Failure, CPLE_NotSupported, - "The BLX driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("BLX"); return nullptr; } diff --git a/frmts/bsb/bsbdataset.cpp b/frmts/bsb/bsbdataset.cpp index a0afd3291be6..bb7f8b1cb7ba 100644 --- a/frmts/bsb/bsbdataset.cpp +++ b/frmts/bsb/bsbdataset.cpp @@ -818,9 +818,7 @@ GDALDataset *BSBDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The BSB driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("BSB"); return nullptr; } diff --git a/frmts/ceos/ceosdataset.cpp b/frmts/ceos/ceosdataset.cpp index 4720dd90b2c7..4b0d1507a44c 100644 --- a/frmts/ceos/ceosdataset.cpp +++ b/frmts/ceos/ceosdataset.cpp @@ -155,9 +155,7 @@ GDALDataset *CEOSDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { CEOSClose(psCEOS); - CPLError(CE_Failure, CPLE_NotSupported, - "The CEOS driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("CEOS"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/ceos2/sar_ceosdataset.cpp b/frmts/ceos2/sar_ceosdataset.cpp index dda64ac26480..304350e298fb 100644 --- a/frmts/ceos2/sar_ceosdataset.cpp +++ b/frmts/ceos2/sar_ceosdataset.cpp @@ -1791,10 +1791,7 @@ GDALDataset *SAR_CEOSDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError( - CE_Failure, CPLE_NotSupported, - "The SAR_CEOS driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("SAR_CEOS"); return nullptr; } diff --git a/frmts/coasp/coasp_dataset.cpp b/frmts/coasp/coasp_dataset.cpp index 65e916510a63..220a0cd60ab3 100644 --- a/frmts/coasp/coasp_dataset.cpp +++ b/frmts/coasp/coasp_dataset.cpp @@ -377,9 +377,7 @@ GDALDataset *COASPDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The COASP driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("COASP"); return nullptr; } diff --git a/frmts/cosar/cosar_dataset.cpp b/frmts/cosar/cosar_dataset.cpp index a136dbba39fd..f2e1e1ae726d 100644 --- a/frmts/cosar/cosar_dataset.cpp +++ b/frmts/cosar/cosar_dataset.cpp @@ -176,9 +176,7 @@ GDALDataset *COSARDataset::Open(GDALOpenInfo *pOpenInfo) /* -------------------------------------------------------------------- */ if (pOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The COSAR driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("COSAR"); return nullptr; } diff --git a/frmts/ctg/ctgdataset.cpp b/frmts/ctg/ctgdataset.cpp index 000ec386a5bb..a3f71fbc5ab2 100644 --- a/frmts/ctg/ctgdataset.cpp +++ b/frmts/ctg/ctgdataset.cpp @@ -415,9 +415,7 @@ GDALDataset *CTGDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The CTG driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("CTG"); return nullptr; } diff --git a/frmts/dimap/dimapdataset.cpp b/frmts/dimap/dimapdataset.cpp index 30ce22e5350e..fb023e62be0e 100644 --- a/frmts/dimap/dimapdataset.cpp +++ b/frmts/dimap/dimapdataset.cpp @@ -512,9 +512,7 @@ GDALDataset *DIMAPDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The DIMAP driver does not support update access to existing " - " datasets."); + ReportUpdateNotSupportedByDriver("DIMAP"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/envisat/envisatdataset.cpp b/frmts/envisat/envisatdataset.cpp index d0b866b18f82..d5146b4247c9 100644 --- a/frmts/envisat/envisatdataset.cpp +++ b/frmts/envisat/envisatdataset.cpp @@ -899,9 +899,7 @@ GDALDataset *EnvisatDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { EnvisatFile_Close(hEnvisatFile); - CPLError(CE_Failure, CPLE_NotSupported, - "The ENVISAT driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("ENVISAT"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/fit/fitdataset.cpp b/frmts/fit/fitdataset.cpp index 66281d1467d1..85d7187684e2 100644 --- a/frmts/fit/fitdataset.cpp +++ b/frmts/fit/fitdataset.cpp @@ -836,9 +836,7 @@ GDALDataset *FITDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The FIT driver does not support update access to existing" - " files.\n"); + ReportUpdateNotSupportedByDriver("FIT"); return nullptr; } diff --git a/frmts/gff/gff_dataset.cpp b/frmts/gff/gff_dataset.cpp index 2544a3e365e4..bea214ef5802 100644 --- a/frmts/gff/gff_dataset.cpp +++ b/frmts/gff/gff_dataset.cpp @@ -190,9 +190,7 @@ GDALDataset *GFFDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The GFF driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("GFF"); return nullptr; } diff --git a/frmts/gif/biggifdataset.cpp b/frmts/gif/biggifdataset.cpp index 20f2e936cf56..98305711e267 100644 --- a/frmts/gif/biggifdataset.cpp +++ b/frmts/gif/biggifdataset.cpp @@ -284,9 +284,7 @@ GDALDataset *BIGGIFDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The GIF driver does not support update access to existing" - " files.\n"); + ReportUpdateNotSupportedByDriver("GIF"); return nullptr; } diff --git a/frmts/gif/gifdataset.cpp b/frmts/gif/gifdataset.cpp index 95e66500354e..bfc954cd69f6 100644 --- a/frmts/gif/gifdataset.cpp +++ b/frmts/gif/gifdataset.cpp @@ -161,9 +161,7 @@ GDALDataset *GIFDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The GIF driver does not support update access to existing" - " files."); + ReportUpdateNotSupportedByDriver("GIF"); return nullptr; } diff --git a/frmts/grib/gribdataset.cpp b/frmts/grib/gribdataset.cpp index f99407267ae7..9092e6736c58 100644 --- a/frmts/grib/gribdataset.cpp +++ b/frmts/grib/gribdataset.cpp @@ -1485,9 +1485,7 @@ GDALDataset *GRIBDataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The GRIB driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("GRIB"); return nullptr; } diff --git a/frmts/gxf/gxfdataset.cpp b/frmts/gxf/gxfdataset.cpp index 67a8c18af5f2..c6f8747320d5 100644 --- a/frmts/gxf/gxfdataset.cpp +++ b/frmts/gxf/gxfdataset.cpp @@ -279,9 +279,7 @@ GDALDataset *GXFDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { GXFClose(l_hGXF); - CPLError(CE_Failure, CPLE_NotSupported, - "The GXF driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("GXF"); return nullptr; } diff --git a/frmts/hdf4/hdf4dataset.cpp b/frmts/hdf4/hdf4dataset.cpp index 623fc76081cf..cdccaaa4d7c8 100644 --- a/frmts/hdf4/hdf4dataset.cpp +++ b/frmts/hdf4/hdf4dataset.cpp @@ -1274,9 +1274,7 @@ GDALDataset *HDF4Dataset::Open(GDALOpenInfo *poOpenInfo) delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); - CPLError(CE_Failure, CPLE_NotSupported, - "The HDF4 driver does not support update access to " - "existing datasets."); + ReportUpdateNotSupportedByDriver(HDF4_DRIVER_NAME); return nullptr; } } diff --git a/frmts/hdf5/bagdataset.cpp b/frmts/hdf5/bagdataset.cpp index 4f60f6795010..e28a8a1032ea 100644 --- a/frmts/hdf5/bagdataset.cpp +++ b/frmts/hdf5/bagdataset.cpp @@ -2621,8 +2621,7 @@ GDALDataset *BAGDataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The BAG driver does not support update access."); + ReportUpdateNotSupportedByDriver("BAG"); return nullptr; } diff --git a/frmts/hdf5/hdf5dataset.cpp b/frmts/hdf5/hdf5dataset.cpp index 7371aebb5e06..0d83218cb6ad 100644 --- a/frmts/hdf5/hdf5dataset.cpp +++ b/frmts/hdf5/hdf5dataset.cpp @@ -565,9 +565,7 @@ GDALDataset *HDF5Dataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { delete poDS; - CPLError(CE_Failure, CPLE_NotSupported, - "The HDF5 driver does not support update access to " - "existing datasets."); + ReportUpdateNotSupportedByDriver("HDF5"); return nullptr; } } diff --git a/frmts/hdf5/hdf5imagedataset.cpp b/frmts/hdf5/hdf5imagedataset.cpp index 73d7a2e92bb7..d963ac21942a 100644 --- a/frmts/hdf5/hdf5imagedataset.cpp +++ b/frmts/hdf5/hdf5imagedataset.cpp @@ -971,9 +971,7 @@ GDALDataset *HDF5ImageDataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The HDF5ImageDataset driver does not support update access " - "to existing datasets."); + ReportUpdateNotSupportedByDriver("HDF5"); return nullptr; } diff --git a/frmts/hdf5/s102dataset.cpp b/frmts/hdf5/s102dataset.cpp index 12d10b998949..1926ea55dc0b 100644 --- a/frmts/hdf5/s102dataset.cpp +++ b/frmts/hdf5/s102dataset.cpp @@ -146,8 +146,7 @@ GDALDataset *S102Dataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The S102 driver does not support update access."); + ReportUpdateNotSupportedByDriver("S102"); return nullptr; } diff --git a/frmts/hdf5/s104dataset.cpp b/frmts/hdf5/s104dataset.cpp index 14b58c76a916..ce95103d3a53 100644 --- a/frmts/hdf5/s104dataset.cpp +++ b/frmts/hdf5/s104dataset.cpp @@ -97,8 +97,7 @@ GDALDataset *S104Dataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The S104 driver does not support update access."); + ReportUpdateNotSupportedByDriver("S104"); return nullptr; } diff --git a/frmts/hdf5/s111dataset.cpp b/frmts/hdf5/s111dataset.cpp index b21a5ec8720a..ca386edcc768 100644 --- a/frmts/hdf5/s111dataset.cpp +++ b/frmts/hdf5/s111dataset.cpp @@ -103,8 +103,7 @@ GDALDataset *S111Dataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The S111 driver does not support update access."); + ReportUpdateNotSupportedByDriver("S111"); return nullptr; } diff --git a/frmts/iris/irisdataset.cpp b/frmts/iris/irisdataset.cpp index b30c953d6e96..43f0c2fefb68 100644 --- a/frmts/iris/irisdataset.cpp +++ b/frmts/iris/irisdataset.cpp @@ -782,9 +782,7 @@ GDALDataset *IRISDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The IRIS driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("IRIS"); return nullptr; } diff --git a/frmts/jaxapalsar/jaxapalsardataset.cpp b/frmts/jaxapalsar/jaxapalsardataset.cpp index ed8371857e7e..746b22c703b5 100644 --- a/frmts/jaxapalsar/jaxapalsardataset.cpp +++ b/frmts/jaxapalsar/jaxapalsardataset.cpp @@ -567,10 +567,7 @@ GDALDataset *PALSARJaxaDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError( - CE_Failure, CPLE_NotSupported, - "The JAXAPALSAR driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("JAXAPALSAR"); return nullptr; } diff --git a/frmts/jdem/jdemdataset.cpp b/frmts/jdem/jdemdataset.cpp index a630e1ae103e..070cfffc9351 100644 --- a/frmts/jdem/jdemdataset.cpp +++ b/frmts/jdem/jdemdataset.cpp @@ -303,9 +303,7 @@ GDALDataset *JDEMDataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The JDEM driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("JDEM"); return nullptr; } diff --git a/frmts/jpeg/jpgdataset.cpp b/frmts/jpeg/jpgdataset.cpp index c49235ed0962..aac2f45e5cfa 100644 --- a/frmts/jpeg/jpgdataset.cpp +++ b/frmts/jpeg/jpgdataset.cpp @@ -2762,9 +2762,7 @@ GDALDataset *JPGDatasetCommon::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The JPEG driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("JPEG"); return nullptr; } diff --git a/frmts/l1b/l1bdataset.cpp b/frmts/l1b/l1bdataset.cpp index e956f5580e28..ab91ff5ab5dc 100644 --- a/frmts/l1b/l1bdataset.cpp +++ b/frmts/l1b/l1bdataset.cpp @@ -3330,9 +3330,7 @@ GDALDataset *L1BDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The L1B driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("L1B"); if (fp != nullptr) CPL_IGNORE_RET_VAL(VSIFCloseL(fp)); return nullptr; diff --git a/frmts/map/mapdataset.cpp b/frmts/map/mapdataset.cpp index 472ae7c31566..fdb14f1c7400 100644 --- a/frmts/map/mapdataset.cpp +++ b/frmts/map/mapdataset.cpp @@ -174,9 +174,7 @@ GDALDataset *MAPDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The MAP driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("MAP"); return nullptr; } diff --git a/frmts/msg/msgdataset.cpp b/frmts/msg/msgdataset.cpp index 43dde5ce0f8e..7608b1131a0c 100644 --- a/frmts/msg/msgdataset.cpp +++ b/frmts/msg/msgdataset.cpp @@ -305,9 +305,7 @@ GDALDataset *MSGDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { delete poDS; - CPLError(CE_Failure, CPLE_NotSupported, - "The MSG driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("MSG"); return nullptr; } diff --git a/frmts/msgn/msgndataset.cpp b/frmts/msgn/msgndataset.cpp index 16df86fbddb2..c7db88c45709 100644 --- a/frmts/msgn/msgndataset.cpp +++ b/frmts/msgn/msgndataset.cpp @@ -451,9 +451,7 @@ GDALDataset *MSGNDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The MSGN driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("MSGN"); return nullptr; } diff --git a/frmts/ngsgeoid/ngsgeoiddataset.cpp b/frmts/ngsgeoid/ngsgeoiddataset.cpp index 6d3d424bd742..c4f6af18c69e 100644 --- a/frmts/ngsgeoid/ngsgeoiddataset.cpp +++ b/frmts/ngsgeoid/ngsgeoiddataset.cpp @@ -313,10 +313,7 @@ GDALDataset *NGSGEOIDDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError( - CE_Failure, CPLE_NotSupported, - "The NGSGEOID driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("NGSGEOID"); return nullptr; } diff --git a/frmts/nitf/ecrgtocdataset.cpp b/frmts/nitf/ecrgtocdataset.cpp index 8e6b04a1f98d..bebdaea7d317 100644 --- a/frmts/nitf/ecrgtocdataset.cpp +++ b/frmts/nitf/ecrgtocdataset.cpp @@ -1036,8 +1036,7 @@ GDALDataset *ECRGTOCDataset::Open(GDALOpenInfo *poOpenInfo) if (poDS && poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "ECRGTOC driver does not support update mode"); + ReportUpdateNotSupportedByDriver("ECRGTOC"); delete poDS; return nullptr; } diff --git a/frmts/nitf/rpftocdataset.cpp b/frmts/nitf/rpftocdataset.cpp index e762bde31187..0026dd44d5e5 100644 --- a/frmts/nitf/rpftocdataset.cpp +++ b/frmts/nitf/rpftocdataset.cpp @@ -1286,8 +1286,7 @@ GDALDataset *RPFTOCDataset::Open(GDALOpenInfo *poOpenInfo) if (poDS && poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "RPFTOC driver does not support update mode"); + ReportUpdateNotSupportedByDriver("RPFTOC"); delete poDS; return nullptr; } @@ -1317,8 +1316,7 @@ GDALDataset *RPFTOCDataset::Open(GDALOpenInfo *poOpenInfo) if (poDS && poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "RPFTOC driver does not support update mode"); + ReportUpdateNotSupportedByDriver("RPFTOC"); delete poDS; return nullptr; } diff --git a/frmts/png/pngdataset.cpp b/frmts/png/pngdataset.cpp index cfe5981879c6..aa5ba4dfc1f9 100644 --- a/frmts/png/pngdataset.cpp +++ b/frmts/png/pngdataset.cpp @@ -1788,9 +1788,7 @@ GDALDataset *PNGDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The PNG driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("PNG"); return nullptr; } diff --git a/frmts/r/rdataset.cpp b/frmts/r/rdataset.cpp index 6879b7cdcf27..e8c09aa1e3a5 100644 --- a/frmts/r/rdataset.cpp +++ b/frmts/r/rdataset.cpp @@ -342,9 +342,7 @@ GDALDataset *RDataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The R driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("R"); return nullptr; } diff --git a/frmts/raw/cpgdataset.cpp b/frmts/raw/cpgdataset.cpp index 9e65d4334f3f..fec41e5c23f4 100644 --- a/frmts/raw/cpgdataset.cpp +++ b/frmts/raw/cpgdataset.cpp @@ -1141,9 +1141,7 @@ GDALDataset *CPGDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The CPG driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("CPG"); return nullptr; } diff --git a/frmts/raw/doq1dataset.cpp b/frmts/raw/doq1dataset.cpp index 44c9571d397a..ada5023f8814 100644 --- a/frmts/raw/doq1dataset.cpp +++ b/frmts/raw/doq1dataset.cpp @@ -244,9 +244,7 @@ GDALDataset *DOQ1Dataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The DOQ1 driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("DOQ1"); return nullptr; } diff --git a/frmts/raw/doq2dataset.cpp b/frmts/raw/doq2dataset.cpp index 007521e6a403..87fb6f927390 100644 --- a/frmts/raw/doq2dataset.cpp +++ b/frmts/raw/doq2dataset.cpp @@ -161,9 +161,7 @@ GDALDataset *DOQ2Dataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The DOQ2 driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("DOQ2"); return nullptr; } @@ -356,9 +354,7 @@ GDALDataset *DOQ2Dataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { CSLDestroy(papszMetadata); - CPLError(CE_Failure, CPLE_NotSupported, - "The DOQ2 driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("DOQ2"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/raw/eirdataset.cpp b/frmts/raw/eirdataset.cpp index 4494e2da41cf..1aec254da4cf 100644 --- a/frmts/raw/eirdataset.cpp +++ b/frmts/raw/eirdataset.cpp @@ -418,9 +418,7 @@ GDALDataset *EIRDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The EIR driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("EIR"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/raw/fastdataset.cpp b/frmts/raw/fastdataset.cpp index 2695a2e3c486..f242927371a8 100644 --- a/frmts/raw/fastdataset.cpp +++ b/frmts/raw/fastdataset.cpp @@ -1121,9 +1121,7 @@ GDALDataset *FASTDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The FAST driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("FAST"); return nullptr; } diff --git a/frmts/raw/gscdataset.cpp b/frmts/raw/gscdataset.cpp index 0fa1458eb566..21307f733441 100644 --- a/frmts/raw/gscdataset.cpp +++ b/frmts/raw/gscdataset.cpp @@ -143,9 +143,7 @@ GDALDataset *GSCDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The GSC driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("GSC"); return nullptr; } diff --git a/frmts/raw/lcpdataset.cpp b/frmts/raw/lcpdataset.cpp index bf2e282f9186..95ecc1bf7c0e 100644 --- a/frmts/raw/lcpdataset.cpp +++ b/frmts/raw/lcpdataset.cpp @@ -226,9 +226,7 @@ GDALDataset *LCPDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The LCP driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("LCP"); return nullptr; } /* -------------------------------------------------------------------- */ diff --git a/frmts/raw/loslasdataset.cpp b/frmts/raw/loslasdataset.cpp index eeae1d80abc8..073a59ed8895 100644 --- a/frmts/raw/loslasdataset.cpp +++ b/frmts/raw/loslasdataset.cpp @@ -180,9 +180,7 @@ GDALDataset *LOSLASDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The LOSLAS driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("LOSLAS"); return nullptr; } diff --git a/frmts/raw/ndfdataset.cpp b/frmts/raw/ndfdataset.cpp index b339ae89a8bb..d15818eab2c8 100644 --- a/frmts/raw/ndfdataset.cpp +++ b/frmts/raw/ndfdataset.cpp @@ -180,9 +180,7 @@ GDALDataset *NDFDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The NDF driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("NDF"); return nullptr; } /* -------------------------------------------------------------------- */ @@ -241,9 +239,7 @@ GDALDataset *NDFDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { CSLDestroy(papszHeader); - CPLError(CE_Failure, CPLE_NotSupported, - "The NDF driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("NDF"); return nullptr; } diff --git a/frmts/raw/nsidcbindataset.cpp b/frmts/raw/nsidcbindataset.cpp index 164a66625cc3..ff7b1d7c57ab 100644 --- a/frmts/raw/nsidcbindataset.cpp +++ b/frmts/raw/nsidcbindataset.cpp @@ -229,10 +229,7 @@ GDALDataset *NSIDCbinDataset::Open(GDALOpenInfo *poOpenInfo) // Confirm the requested access is supported. if (poOpenInfo->eAccess == GA_Update) { - CPLError( - CE_Failure, CPLE_NotSupported, - "The NSIDCbin driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("NSIDCbin"); return nullptr; } diff --git a/frmts/raw/snodasdataset.cpp b/frmts/raw/snodasdataset.cpp index 27e82bd0fc41..dc2c24489df9 100644 --- a/frmts/raw/snodasdataset.cpp +++ b/frmts/raw/snodasdataset.cpp @@ -250,9 +250,7 @@ GDALDataset *SNODASDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The SNODAS driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("SNODAS"); return nullptr; } diff --git a/frmts/rcm/rcmdataset.cpp b/frmts/rcm/rcmdataset.cpp index 0d0abc14b411..80be053ea880 100644 --- a/frmts/rcm/rcmdataset.cpp +++ b/frmts/rcm/rcmdataset.cpp @@ -1132,9 +1132,7 @@ GDALDataset *RCMDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "ERROR: The RCM driver does not support update " - "access to existing dataset."); + ReportUpdateNotSupportedByDriver("RCM"); return nullptr; } diff --git a/frmts/rdb/rdbdataset.cpp b/frmts/rdb/rdbdataset.cpp index d4c087404538..ce31ad8f5ace 100644 --- a/frmts/rdb/rdbdataset.cpp +++ b/frmts/rdb/rdbdataset.cpp @@ -586,9 +586,7 @@ GDALDataset *RDBDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The RDB driver does not support update access to existing " - "datasets."); + ReportUpdateNotSupportedByDriver("RDB"); return nullptr; } diff --git a/frmts/rik/rikdataset.cpp b/frmts/rik/rikdataset.cpp index fc65bd822ac7..247218972b28 100644 --- a/frmts/rik/rikdataset.cpp +++ b/frmts/rik/rikdataset.cpp @@ -1265,9 +1265,7 @@ GDALDataset *RIKDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { delete poDS; - CPLError(CE_Failure, CPLE_NotSupported, - "The RIK driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("RIK"); return nullptr; } diff --git a/frmts/rs2/rs2dataset.cpp b/frmts/rs2/rs2dataset.cpp index 3f3aaff395fd..ac2ef08c3105 100644 --- a/frmts/rs2/rs2dataset.cpp +++ b/frmts/rs2/rs2dataset.cpp @@ -729,9 +729,7 @@ GDALDataset *RS2Dataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { CPLDestroyXMLNode(psProduct); - CPLError(CE_Failure, CPLE_NotSupported, - "The RS2 driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("RS2"); return nullptr; } diff --git a/frmts/safe/safedataset.cpp b/frmts/safe/safedataset.cpp index ab46337b324d..a0c9ad98b1b0 100644 --- a/frmts/safe/safedataset.cpp +++ b/frmts/safe/safedataset.cpp @@ -1004,9 +1004,7 @@ GDALDataset *SAFEDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The SAFE driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("SAFE"); return nullptr; } diff --git a/frmts/sdts/sdtsdataset.cpp b/frmts/sdts/sdtsdataset.cpp index 29714be1a1f8..932904eb79aa 100644 --- a/frmts/sdts/sdtsdataset.cpp +++ b/frmts/sdts/sdtsdataset.cpp @@ -134,9 +134,7 @@ GDALDataset *SDTSDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { delete poTransfer; - CPLError(CE_Failure, CPLE_NotSupported, - "The SDTS driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("SDTS"); return nullptr; } diff --git a/frmts/til/tildataset.cpp b/frmts/til/tildataset.cpp index 8825d121d2b6..de13dfc58865 100644 --- a/frmts/til/tildataset.cpp +++ b/frmts/til/tildataset.cpp @@ -198,9 +198,7 @@ GDALDataset *TILDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The TIL driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("TIL"); return nullptr; } diff --git a/frmts/tsx/tsxdataset.cpp b/frmts/tsx/tsxdataset.cpp index d40b17b38737..4cecd79b39c7 100644 --- a/frmts/tsx/tsxdataset.cpp +++ b/frmts/tsx/tsxdataset.cpp @@ -455,9 +455,7 @@ GDALDataset *TSXDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The TSX driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("TSX"); return nullptr; } diff --git a/frmts/usgsdem/usgsdemdataset.cpp b/frmts/usgsdem/usgsdemdataset.cpp index ebc88a45f180..835854d0b56c 100644 --- a/frmts/usgsdem/usgsdemdataset.cpp +++ b/frmts/usgsdem/usgsdemdataset.cpp @@ -920,9 +920,7 @@ GDALDataset *USGSDEMDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { delete poDS; - CPLError(CE_Failure, CPLE_NotSupported, - "The USGSDEM driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("USGSDEM"); return nullptr; } diff --git a/frmts/wcs/wcsdataset.cpp b/frmts/wcs/wcsdataset.cpp index 86be887f42b0..215f79c4043f 100644 --- a/frmts/wcs/wcsdataset.cpp +++ b/frmts/wcs/wcsdataset.cpp @@ -1365,9 +1365,7 @@ GDALDataset *WCSDataset::Open(GDALOpenInfo *poOpenInfo) { CSLDestroy(papszModifiers); CPLDestroyXMLNode(service); - CPLError(CE_Failure, CPLE_NotSupported, - "The WCS driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("WCS"); return nullptr; } diff --git a/frmts/webp/webpdataset.cpp b/frmts/webp/webpdataset.cpp index 56516a8e812a..87464eb5ed78 100644 --- a/frmts/webp/webpdataset.cpp +++ b/frmts/webp/webpdataset.cpp @@ -547,9 +547,7 @@ GDALPamDataset *WEBPDataset::OpenPAM(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The WEBP driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("WEBP"); return nullptr; } diff --git a/frmts/wms/wmsdriver.cpp b/frmts/wms/wmsdriver.cpp index 2ac5e72f9fb3..71903120706f 100644 --- a/frmts/wms/wmsdriver.cpp +++ b/frmts/wms/wmsdriver.cpp @@ -902,9 +902,7 @@ GDALDataset *GDALWMSDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { CPLDestroyXMLNode(config); - CPLError(CE_Failure, CPLE_NotSupported, - "The WMS poDriver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("WMS"); return nullptr; } diff --git a/frmts/xpm/xpmdataset.cpp b/frmts/xpm/xpmdataset.cpp index 2623ce75eed1..c910532851f6 100644 --- a/frmts/xpm/xpmdataset.cpp +++ b/frmts/xpm/xpmdataset.cpp @@ -84,9 +84,7 @@ GDALDataset *XPMDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The XPM driver does not support update access to existing" - " files."); + ReportUpdateNotSupportedByDriver("XPM"); return nullptr; } diff --git a/frmts/xyz/xyzdataset.cpp b/frmts/xyz/xyzdataset.cpp index aaa64b03c7e3..c1e8ce96949c 100644 --- a/frmts/xyz/xyzdataset.cpp +++ b/frmts/xyz/xyzdataset.cpp @@ -1501,9 +1501,7 @@ GDALDataset *XYZDataset::Open(GDALOpenInfo *poOpenInfo) if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The XYZ driver does not support update access to existing" - " datasets.\n"); + ReportUpdateNotSupportedByDriver("XYZ"); VSIFCloseL(fp); return nullptr; } diff --git a/frmts/zmap/zmapdataset.cpp b/frmts/zmap/zmapdataset.cpp index 08523a19e121..816c58c05d10 100644 --- a/frmts/zmap/zmapdataset.cpp +++ b/frmts/zmap/zmapdataset.cpp @@ -291,9 +291,7 @@ GDALDataset *ZMapDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The ZMAP driver does not support update access to existing" - " datasets."); + ReportUpdateNotSupportedByDriver("ZMAP"); return nullptr; } diff --git a/gcore/gdal_priv.h b/gcore/gdal_priv.h index 4cf88355eacf..5d6c653ac131 100644 --- a/gcore/gdal_priv.h +++ b/gcore/gdal_priv.h @@ -946,6 +946,8 @@ class CPL_DLL GDALDataset : public GDALMajorObject // Only to be used by driver's GetOverviewCount() method. bool AreOverviewsEnabled() const; + + static void ReportUpdateNotSupportedByDriver(const char *pszDriverName); //! @endcond private: diff --git a/gcore/gdaldataset.cpp b/gcore/gdaldataset.cpp index 64e5ed828599..0288878dd067 100644 --- a/gcore/gdaldataset.cpp +++ b/gcore/gdaldataset.cpp @@ -10423,3 +10423,20 @@ CPLErr GDALDatasetGeolocationToPixelLine(GDALDatasetH hDS, double dfGeolocX, dfGeolocX, dfGeolocY, OGRSpatialReference::FromHandle(hSRS), pdfPixel, pdfLine, papszTransformerOptions); } + +/************************************************************************/ +/* ReportUpdateNotSupportedByDriver() */ +/************************************************************************/ + +//! @cond Doxygen_Suppress + +/* static */ +void GDALDataset::ReportUpdateNotSupportedByDriver(const char *pszDriverName) +{ + CPLError(CE_Failure, CPLE_NotSupported, + "The %s driver does not support update access to existing " + "datasets.", + pszDriverName); +} + +//! @endcond diff --git a/ogr/ogrsf_frmts/cad/ogrcaddriver.cpp b/ogr/ogrsf_frmts/cad/ogrcaddriver.cpp index dda528734b9c..3446ed3615c5 100644 --- a/ogr/ogrsf_frmts/cad/ogrcaddriver.cpp +++ b/ogr/ogrsf_frmts/cad/ogrcaddriver.cpp @@ -67,9 +67,7 @@ static GDALDataset *OGRCADDriverOpen(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ if (poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_NotSupported, - "The CAD driver does not support update access to existing" - " datasets.\n"); + GDALDataset::ReportUpdateNotSupportedByDriver("CAD"); delete pFileIO; return nullptr; } diff --git a/ogr/ogrsf_frmts/miramon/ogrmiramondriver.cpp b/ogr/ogrsf_frmts/miramon/ogrmiramondriver.cpp index ec3d05585f82..9ed9c38eff48 100644 --- a/ogr/ogrsf_frmts/miramon/ogrmiramondriver.cpp +++ b/ogr/ogrsf_frmts/miramon/ogrmiramondriver.cpp @@ -84,8 +84,7 @@ static GDALDataset *OGRMiraMonDriverOpen(GDALOpenInfo *poOpenInfo) if (poDS && poOpenInfo->eAccess == GA_Update) { - CPLError(CE_Failure, CPLE_OpenFailed, - "MiraMonVector driver does not support update."); + GDALDataset::ReportUpdateNotSupportedByDriver("MiraMonVector"); return nullptr; }