From 37d0621cfb4a3a884eabca18e7c0bba28be48ea5 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 11 Feb 2025 11:46:40 +0100 Subject: [PATCH] [gdal_rasterize] Also accept doubles for -ts (#11830) But warn if it has a decimal part. Fixes #11829 --- apps/gdal_rasterize_lib.cpp | 20 ++++++++++++--- autotest/utilities/test_gdal_rasterize.py | 31 ++++++++++++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/apps/gdal_rasterize_lib.cpp b/apps/gdal_rasterize_lib.cpp index 315b0e567a11..a80b552c25de 100644 --- a/apps/gdal_rasterize_lib.cpp +++ b/apps/gdal_rasterize_lib.cpp @@ -263,10 +263,12 @@ GDALRasterizeOptionsGetParser(GDALRasterizeOptions *psOptions, _("Set output file resolution in target georeferenced units.")); // Store later + // Note: this is supposed to be int but for backward compatibility, we + // use double auto &arg = group.add_argument("-ts") .metavar(" ") .nargs(2) - .scan<'i', int>() + .scan<'g', double>() .help(_("Set output file size in pixels and lines.")); argParser->add_hidden_alias_for(arg, "-outsize"); @@ -1424,10 +1426,20 @@ GDALRasterizeOptionsNew(char **papszArgv, psOptions->bCreateOutput = true; } - if (auto oTs = argParser->present>("-ts")) + if (auto oTs = argParser->present>("-ts")) { - psOptions->nXSize = oTs.value()[0]; - psOptions->nYSize = oTs.value()[1]; + const int nXSize = static_cast(oTs.value()[0]); + const int nYSize = static_cast(oTs.value()[1]); + + // Warn the user if the conversion to int looses precision + if (nXSize != oTs.value()[0] || nYSize != oTs.value()[1]) + { + CPLError(CE_Warning, CPLE_AppDefined, + "-ts values parsed as %d %d.", nXSize, nYSize); + } + + psOptions->nXSize = nXSize; + psOptions->nYSize = nYSize; if (psOptions->nXSize <= 0 || psOptions->nYSize <= 0) { diff --git a/autotest/utilities/test_gdal_rasterize.py b/autotest/utilities/test_gdal_rasterize.py index 8a015a30ec6c..2f3fb1107eee 100755 --- a/autotest/utilities/test_gdal_rasterize.py +++ b/autotest/utilities/test_gdal_rasterize.py @@ -123,7 +123,6 @@ def test_gdal_rasterize_2(gdal_rasterize_path, tmp_path): output_tif = str(tmp_path / "rast2.tif") # Create a raster to rasterize into. - target_ds = gdal.GetDriverByName("GTiff").Create( output_tif, 12, 12, 3, gdal.GDT_Byte ) @@ -418,3 +417,33 @@ def test_gdal_rasterize_8(gdal_rasterize_path, tmp_path): assert cs == 21, "Did not rasterize line data properly" ds = None + + +############################################################################### +# Test that -ts also accepts double and warns if not integer + + +@pytest.mark.require_driver("CSV") +def test_gdal_rasterize_ts_1(tmp_path, gdal_rasterize_path): + + output_tif = str(tmp_path / "rast2.tif") + + # Create a raster to rasterize into. + target_ds = gdal.GetDriverByName("GTiff").Create( + output_tif, 12, 12, 3, gdal.GDT_Byte + ) + target_ds.SetGeoTransform((0, 1, 0, 12, 0, -1)) + + # Close TIF file + target_ds = None + + # Run the algorithm. + (_, err) = gdaltest.runexternal_out_and_err( + f"{gdal_rasterize_path} -at -burn 200 -ts 100.0 200.0 ../alg/data/cutline.csv {output_tif}" + ) + assert err is None or err == "", f"got error/warning {err}" + + (_, err) = gdaltest.runexternal_out_and_err( + f"{gdal_rasterize_path} -at -burn 200 -ts 100.4 200.6 ../alg/data/cutline.csv {output_tif}" + ) + assert "-ts values parsed as 100 200" in err