From 4a4eac4338efc925c993e6ff89effab7a26fe9a2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 25 Aug 2024 16:51:21 +0200 Subject: [PATCH] SRTMHGT: add support for creating 7201x7201 files Fixes #10627 --- autotest/gdrivers/srtmhgt.py | 3 +++ doc/source/drivers/raster/srtmhgt.rst | 3 +++ frmts/srtmhgt/srtmhgtdataset.cpp | 38 ++++++++++++++++++--------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/autotest/gdrivers/srtmhgt.py b/autotest/gdrivers/srtmhgt.py index 76acf525a138..9ad1191de8a1 100755 --- a/autotest/gdrivers/srtmhgt.py +++ b/autotest/gdrivers/srtmhgt.py @@ -227,3 +227,6 @@ def test_srtmhgt_all_supported_sizes(tmp_vsimem, width, height, nb_bytes): if nb_bytes == 2 else gdal.GDT_Float32 ) + + out_filename = str(tmp_vsimem / "create" / "n00e000.hgt") + gdal.GetDriverByName("SRTMHGT").CreateCopy(out_filename, ds) diff --git a/doc/source/drivers/raster/srtmhgt.rst b/doc/source/drivers/raster/srtmhgt.rst index 54077188a3d3..38fcacda8a36 100644 --- a/doc/source/drivers/raster/srtmhgt.rst +++ b/doc/source/drivers/raster/srtmhgt.rst @@ -21,6 +21,9 @@ The driver does support creating new files, but the input data must be exactly formatted as a SRTM-3 or SRTM-1 cell. That is the size, and bounds must be appropriate for a cell. +Starting with GDAL 3.10, the driver also supports reading and writing 0.5 +degree resolution SRTM HGT files. + See Also: - `SRTM diff --git a/frmts/srtmhgt/srtmhgtdataset.cpp b/frmts/srtmhgt/srtmhgtdataset.cpp index ff8c8d863ff4..d1f35966257b 100644 --- a/frmts/srtmhgt/srtmhgtdataset.cpp +++ b/frmts/srtmhgt/srtmhgtdataset.cpp @@ -57,6 +57,8 @@ class SRTMHGTDataset final : public GDALPamDataset GByte *pabyBuffer = nullptr; OGRSpatialReference m_oSRS{}; + static GDALPamDataset *OpenPAM(GDALOpenInfo *); + public: SRTMHGTDataset(); virtual ~SRTMHGTDataset(); @@ -360,6 +362,15 @@ int SRTMHGTDataset::Identify(GDALOpenInfo *poOpenInfo) /************************************************************************/ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) +{ + return OpenPAM(poOpenInfo); +} + +/************************************************************************/ +/* OpenPAM() */ +/************************************************************************/ + +GDALPamDataset *SRTMHGTDataset::OpenPAM(GDALOpenInfo *poOpenInfo) { if (!Identify(poOpenInfo)) return nullptr; @@ -374,7 +385,7 @@ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) osFilename += CPLString(fileName).substr(0, 7); osFilename += ".hgt"; GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess); - GDALDataset *poDS = Open(&oOpenInfo); + auto poDS = OpenPAM(&oOpenInfo); if (poDS != nullptr) { // override description with the main one @@ -392,7 +403,7 @@ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) osFilename += CPLString(fileName).substr(0, 7); osFilename += ".raw"; GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess); - GDALDataset *poDS = Open(&oOpenInfo); + auto poDS = OpenPAM(&oOpenInfo); if (poDS != nullptr) { // override description with the main one @@ -427,7 +438,7 @@ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ - SRTMHGTDataset *poDS = new SRTMHGTDataset(); + auto poDS = std::make_unique(); poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; @@ -435,7 +446,6 @@ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) VSIStatBufL fileStat; if (VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0) { - delete poDS; return nullptr; } @@ -498,7 +508,7 @@ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ /* Create band information object. */ /* -------------------------------------------------------------------- */ - SRTMHGTRasterBand *tmpBand = new SRTMHGTRasterBand(poDS, 1, eDT); + SRTMHGTRasterBand *tmpBand = new SRTMHGTRasterBand(poDS.get(), 1, eDT); poDS->SetBand(1, tmpBand); /* -------------------------------------------------------------------- */ @@ -510,9 +520,9 @@ GDALDataset *SRTMHGTDataset::Open(GDALOpenInfo *poOpenInfo) /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ - poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); + poDS->oOvManager.Initialize(poDS.get(), poOpenInfo->pszFilename); - return poDS; + return poDS.release(); } /************************************************************************/ @@ -597,12 +607,14 @@ GDALDataset *SRTMHGTDataset::CreateCopy(const char *pszFilename, const int nYSize = poSrcDS->GetRasterYSize(); if (!((nXSize == 1201 && nYSize == 1201) || + (nXSize == 1801 && nYSize == 3601) || + (nXSize == 3601 && nYSize == 3601) || (nXSize == 3601 && nYSize == 3601) || - (nXSize == 1801 && nYSize == 3601))) + (nXSize == 7201 && nYSize == 7201))) { - CPLError( - CE_Failure, CPLE_AppDefined, - "Image dimensions should be 1201x1201, 3601x3601 or 1801x3601."); + CPLError(CE_Failure, CPLE_AppDefined, + "Image dimensions should be 1201x1201, 1801x3601, 3601x3601 " + "or 7201x7201."); return nullptr; } @@ -691,8 +703,8 @@ GDALDataset *SRTMHGTDataset::CreateCopy(const char *pszFilename, /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ - GDALPamDataset *poDS = - reinterpret_cast(GDALOpen(pszFilename, GA_ReadOnly)); + GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); + auto poDS = OpenPAM(&oOpenInfo); if (poDS) poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT);