Skip to content

Commit

Permalink
Merge branch 'OSGeo:master' into i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
yoichigmf authored Jul 23, 2024
2 parents fd6a16e + 15866aa commit bd5c096
Show file tree
Hide file tree
Showing 32 changed files with 587 additions and 281 deletions.
3 changes: 3 additions & 0 deletions MIGRATION_GUIDE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ MIGRATION GUIDE FROM GDAL 3.9 to GDAL 3.10
corresponding optional (but recommended to be implemented to reliably detect
reading errors) callbacks "error" and "clear_err".

- Python bindings: Band.GetStatistics() and Band.ComputeStatistics() now
return a None value in case of error (when exceptions are not enabled)

MIGRATION GUIDE FROM GDAL 3.8 to GDAL 3.9
-----------------------------------------

Expand Down
12 changes: 6 additions & 6 deletions autotest/gcore/gdal_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_stats_dont_force():
gdal.Unlink("data/byte.tif.aux.xml")
ds = gdal.Open("data/byte.tif")
stats = ds.GetRasterBand(1).GetStatistics(0, 0)
assert stats == [0, 0, 0, -1], "did not get expected stats"
assert stats is None


###############################################################################
Expand Down Expand Up @@ -762,7 +762,7 @@ def test_stats_approx_stats_flag(dt=gdal.GDT_Byte, struct_frmt="B"):
approx_ok = 0
force = 0
stats = ds.GetRasterBand(1).GetStatistics(approx_ok, force)
assert stats == [0.0, 0.0, 0.0, -1.0], "did not get expected stats"
assert stats is None

approx_ok = 0
force = 1
Expand Down Expand Up @@ -824,15 +824,15 @@ def test_stats_clear():
filename = "/vsimem/out.tif"
gdal.Translate(filename, "data/byte.tif")
ds = gdal.Open(filename)
assert ds.GetRasterBand(1).GetStatistics(False, False) == [0, 0, 0, -1]
assert ds.GetRasterBand(1).ComputeStatistics(False) != [0, 0, 0, -1]
assert ds.GetRasterBand(1).GetStatistics(False, False) is None
assert ds.GetRasterBand(1).ComputeStatistics(False) is not None

ds = gdal.Open(filename)
assert ds.GetRasterBand(1).GetStatistics(False, False) != [0, 0, 0, -1]
assert ds.GetRasterBand(1).GetStatistics(False, False) is not None
ds.ClearStatistics()

ds = gdal.Open(filename)
assert ds.GetRasterBand(1).GetStatistics(False, False) == [0, 0, 0, -1]
assert ds.GetRasterBand(1).GetStatistics(False, False) is None

gdal.GetDriverByName("GTiff").Delete(filename)

Expand Down
2 changes: 1 addition & 1 deletion autotest/gcore/pam.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def test_pam_11():
# Check that we actually have no saved statistics
ds = gdal.Open("tmpdirreadonly/byte.tif")
stats = ds.GetRasterBand(1).GetStatistics(False, False)
assert stats[3] == -1, "did not expected to have stats at that point"
assert stats is None
ds = None

# This must be run as an external process so we can override GDAL_PAM_PROXY_DIR
Expand Down
2 changes: 1 addition & 1 deletion autotest/gcore/vrt_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -2341,7 +2341,7 @@ def test_vrt_read_compute_statistics_mosaic_optimization_src_with_nodata_all():

with gdal.quiet_errors():
vrt_stats = vrt_ds.GetRasterBand(1).ComputeStatistics(False)
assert vrt_stats == [0, 0, 0, 0]
assert vrt_stats is None
assert vrt_ds.GetRasterBand(1).GetMetadataItem("STATISTICS_MINIMUM") is None


Expand Down
2 changes: 1 addition & 1 deletion autotest/gdrivers/ecw.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ def test_ecw_41(tmp_path):
# Check that no statistics is already included in the file
assert ds.GetRasterBand(1).GetMinimum() is None
assert ds.GetRasterBand(1).GetMaximum() is None
assert ds.GetRasterBand(1).GetStatistics(1, 0) == [0.0, 0.0, 0.0, -1.0]
assert ds.GetRasterBand(1).GetStatistics(1, 0) is None
assert ds.GetRasterBand(1).GetDefaultHistogram(force=0) is None

# Now compute the stats
Expand Down
6 changes: 3 additions & 3 deletions autotest/gdrivers/ehdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,20 +379,20 @@ def test_ehdr_approx_stats_flag():
approx_ok = 1
force = 1
stats = ds.GetRasterBand(1).GetStatistics(approx_ok, force)
assert stats == [0.0, 0.0, 0.0, 0.0], "did not get expected stats"
assert stats == [0.0, 0.0, 0.0, 0.0]
md = ds.GetRasterBand(1).GetMetadata()
assert "STATISTICS_APPROXIMATE" in md, "did not get expected metadata"

approx_ok = 0
force = 0
stats = ds.GetRasterBand(1).GetStatistics(approx_ok, force)
assert stats == [0.0, 0.0, 0.0, -1.0], "did not get expected stats"
assert stats is None

ds = gdal.Open(tmpfile, gdal.GA_Update)
approx_ok = 0
force = 0
stats = ds.GetRasterBand(1).GetStatistics(approx_ok, force)
assert stats == [0.0, 0.0, 0.0, -1.0], "did not get expected stats"
assert stats is None

approx_ok = 0
force = 1
Expand Down
62 changes: 62 additions & 0 deletions autotest/gdrivers/gti.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import struct

import gdaltest
import ogrtest
import pytest

from osgeo import gdal, ogr
Expand Down Expand Up @@ -1057,6 +1058,20 @@ def test_gti_rgb_left_right(tmp_vsimem):
== "<LocationInfo><File>/vsimem/test_gti_rgb_left_right/left.tif</File></LocationInfo>"
)

if ogrtest.have_geos():
(flags, pct) = vrt_ds.GetRasterBand(1).GetDataCoverageStatus(
0, 0, vrt_ds.RasterXSize, vrt_ds.RasterYSize
)
assert flags == gdal.GDAL_DATA_COVERAGE_STATUS_DATA and pct == 100.0

(flags, pct) = vrt_ds.GetRasterBand(1).GetDataCoverageStatus(1, 2, 3, 4)
assert flags == gdal.GDAL_DATA_COVERAGE_STATUS_DATA and pct == 100.0

(flags, pct) = vrt_ds.GetRasterBand(1).GetDataCoverageStatus(
vrt_ds.RasterXSize // 2 - 1, 2, 2, 4
)
assert flags == gdal.GDAL_DATA_COVERAGE_STATUS_DATA and pct == 100.0


def test_gti_overlapping_sources(tmp_vsimem):

Expand All @@ -1082,6 +1097,12 @@ def test_gti_overlapping_sources(tmp_vsimem):
vrt_ds = gdal.Open(index_filename)
assert vrt_ds.GetRasterBand(1).Checksum() == 2

if ogrtest.have_geos():
(flags, pct) = vrt_ds.GetRasterBand(1).GetDataCoverageStatus(
0, 0, vrt_ds.RasterXSize, vrt_ds.RasterYSize
)
assert flags == gdal.GDAL_DATA_COVERAGE_STATUS_DATA and pct == 100.0

# Test unsupported sort_field_type = OFTBinary
index_filename = str(tmp_vsimem / "index.gti.gpkg")
sort_values = [None, None]
Expand Down Expand Up @@ -1319,6 +1340,41 @@ def test_gti_overlapping_sources(tmp_vsimem):
assert vrt_ds.GetRasterBand(1).Checksum() == 2, sort_values


def test_gti_gap_between_sources(tmp_vsimem):

filename1 = str(tmp_vsimem / "one.tif")
ds = gdal.GetDriverByName("GTiff").Create(filename1, 1, 1)
ds.SetGeoTransform([2, 1, 0, 49, 0, -1])
ds.GetRasterBand(1).Fill(1)
del ds

filename2 = str(tmp_vsimem / "two.tif")
ds = gdal.GetDriverByName("GTiff").Create(filename2, 1, 1)
ds.SetGeoTransform([4, 1, 0, 49, 0, -1])
ds.GetRasterBand(1).Fill(2)
del ds

index_filename = str(tmp_vsimem / "index.gti.gpkg")
index_ds, _ = create_basic_tileindex(
index_filename, [gdal.Open(filename1), gdal.Open(filename2)]
)
del index_ds

vrt_ds = gdal.Open(index_filename)
assert vrt_ds.GetRasterBand(1).Checksum() == 3

if ogrtest.have_geos():
(flags, pct) = vrt_ds.GetRasterBand(1).GetDataCoverageStatus(
0, 0, vrt_ds.RasterXSize, vrt_ds.RasterYSize
)
assert (
flags
== gdal.GDAL_DATA_COVERAGE_STATUS_DATA
| gdal.GDAL_DATA_COVERAGE_STATUS_EMPTY
and pct == pytest.approx(100.0 * 2 / 3)
)


def test_gti_no_source(tmp_vsimem):

index_filename = str(tmp_vsimem / "index.gti.gpkg")
Expand Down Expand Up @@ -1359,6 +1415,12 @@ def test_gti_no_source(tmp_vsimem):
is None
)

if ogrtest.have_geos():
(flags, pct) = vrt_ds.GetRasterBand(1).GetDataCoverageStatus(
0, 0, vrt_ds.RasterXSize, vrt_ds.RasterYSize
)
assert flags == gdal.GDAL_DATA_COVERAGE_STATUS_EMPTY and pct == 0.0


def test_gti_invalid_source(tmp_vsimem):

Expand Down
14 changes: 2 additions & 12 deletions autotest/gdrivers/netcdf_multidim.py
Original file line number Diff line number Diff line change
Expand Up @@ -3979,12 +3979,7 @@ def test():

view = ar.GetView("[0:10,...]")
classic_ds = view.AsClassicDataset(1, 0)
assert classic_ds.GetRasterBand(1).GetStatistics(False, False) == [
0.0,
0.0,
0.0,
-1.0,
]
assert classic_ds.GetRasterBand(1).GetStatistics(False, False) is None
classic_ds.GetRasterBand(1).ComputeStatistics(False)

view = ar.GetView("[10:20,...]")
Expand Down Expand Up @@ -4035,12 +4030,7 @@ def reopen():
)

classic_ds = ar.AsClassicDataset(1, 0)
assert classic_ds.GetRasterBand(1).GetStatistics(False, False) == [
0.0,
0.0,
0.0,
-1.0,
]
assert classic_ds.GetRasterBand(1).GetStatistics(False, False) is None

rg_subset = rg.SubsetDimensionFromSelection("/x=440750")

Expand Down
3 changes: 1 addition & 2 deletions autotest/gdrivers/nitf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1488,8 +1488,7 @@ def test_nitf_36():
ds.GetRasterBand(1).GetMinimum() is None
), "Did not expect to have minimum value at that point."

(_, _, mean, stddev) = ds.GetRasterBand(1).GetStatistics(False, False)
assert stddev < 0, "Did not expect to have statistics at that point."
assert ds.GetRasterBand(1).GetStatistics(False, False) is None

(exp_mean, exp_stddev) = (65.4208, 47.254550335)
(_, _, mean, stddev) = ds.GetRasterBand(1).GetStatistics(False, True)
Expand Down
2 changes: 1 addition & 1 deletion autotest/gdrivers/vrtprocesseddataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -1181,7 +1181,7 @@ def test_vrtprocesseddataset_serialize(tmp_vsimem):
with gdaltest.tempfile(vrt_filename, content):
ds = gdal.Open(vrt_filename)
np.testing.assert_equal(ds.GetRasterBand(1).ReadAsArray(), np.array([[11, 12]]))
assert ds.GetRasterBand(1).GetStatistics(False, False) == [0.0, 0.0, 0.0, -1.0]
assert ds.GetRasterBand(1).GetStatistics(False, False) is None
ds.GetRasterBand(1).ComputeStatistics(False)
ds.Close()

Expand Down
40 changes: 14 additions & 26 deletions autotest/ogr/ogr_geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -982,50 +982,38 @@ def test_ogr_geom_flattenTo2D_triangle():
###############################################################################


@gdaltest.enable_exceptions()
def test_ogr_geom_linestring_limits():

geom = ogr.CreateGeometryFromWkt("LINESTRING EMPTY")
assert geom.Length() == 0

gdal.ErrorReset()
with gdal.quiet_errors():
with pytest.raises(Exception):
geom.GetPoint(-1)
assert gdal.GetLastErrorType() != 0

gdal.ErrorReset()
with gdal.quiet_errors():
with pytest.raises(Exception):
geom.GetPoint(0)
assert gdal.GetLastErrorType() != 0

gdal.ErrorReset()
with gdal.quiet_errors():
with pytest.raises(Exception):
geom.GetPoint_2D(-1)
assert gdal.GetLastErrorType() != 0

gdal.ErrorReset()
with gdal.quiet_errors():
with pytest.raises(Exception):
geom.GetPoint_2D(0)
assert gdal.GetLastErrorType() != 0

gdal.ErrorReset()
with gdal.quiet_errors():
with pytest.raises(Exception):
geom.SetPoint(-1, 5, 6, 7)
assert gdal.GetLastErrorType() != 0

gdal.ErrorReset()
with gdal.quiet_errors():
with pytest.raises(Exception):
geom.SetPoint_2D(-1, 5, 6)
assert gdal.GetLastErrorType() != 0

gdal.ErrorReset()
with gdal.quiet_errors():
geom.SetPoint(2147000000, 5, 6, 7)
assert gdal.GetLastErrorType() != 0
with pytest.raises(Exception):
geom.SetPoint((1 << 31) - 2, 5, 6, 7)

gdal.ErrorReset()
with gdal.quiet_errors():
geom.SetPoint_2D(2147000000, 5, 6)
assert gdal.GetLastErrorType() != 0
with pytest.raises(Exception):
geom.SetPoint_2D((1 << 31) - 2, 5, 6)

with pytest.raises(Exception):
geom.SetPoint_2D((1 << 31) - 1, 5, 6)

geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0)")
assert geom.Length() == 0
Expand Down
42 changes: 42 additions & 0 deletions autotest/ogr/ogr_mem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,18 @@ def test_ogr_mem_write_arrow():
field_def = ogr.FieldDefn("field_stringlist", ogr.OFTStringList)
src_lyr.CreateField(field_def)

field_def = ogr.FieldDefn("field_json", ogr.OFTString)
field_def.SetSubType(ogr.OFSTJSON)
src_lyr.CreateField(field_def)

field_def = ogr.FieldDefn("field_uuid", ogr.OFTString)
field_def.SetSubType(ogr.OFSTUUID)
src_lyr.CreateField(field_def)

field_def = ogr.FieldDefn("field_with_width", ogr.OFTString)
field_def.SetWidth(10)
src_lyr.CreateField(field_def)

feat_def = src_lyr.GetLayerDefn()
src_feature = ogr.Feature(feat_def)
src_feature.SetField("field_bool", True)
Expand All @@ -1485,6 +1497,9 @@ def test_ogr_mem_write_arrow():
src_feature.field_float32list = [1.5, -1.5]
src_feature.field_reallist = [123.5, 567.0]
src_feature.field_stringlist = ["abc", "def"]
src_feature["field_json"] = '{"foo":"bar"}'
src_feature["field_uuid"] = "INVALID_UUID"
src_feature["field_with_width"] = "foo"
src_feature.SetGeometry(ogr.CreateGeometryFromWkt("POINT (1 2)"))

src_lyr.CreateFeature(src_feature)
Expand All @@ -1506,6 +1521,15 @@ def test_ogr_mem_write_arrow():
if schema.GetChild(i).GetName() != "wkb_geometry":
dst_lyr.CreateFieldFromArrowSchema(schema.GetChild(i))

idx = dst_lyr.GetLayerDefn().GetFieldIndex("field_json")
assert dst_lyr.GetLayerDefn().GetFieldDefn(idx).GetSubType() == ogr.OFSTJSON

idx = dst_lyr.GetLayerDefn().GetFieldIndex("field_uuid")
assert dst_lyr.GetLayerDefn().GetFieldDefn(idx).GetSubType() == ogr.OFSTUUID

idx = dst_lyr.GetLayerDefn().GetFieldIndex("field_with_width")
assert dst_lyr.GetLayerDefn().GetFieldDefn(idx).GetWidth() == 10

while True:
array = stream.GetNextRecordBatch()
if array is None:
Expand Down Expand Up @@ -2851,6 +2875,24 @@ def test_ogr_mem_write_pyarrow_invalid_dict_index(dict_values):
lyr.WritePyArrow(table)


###############################################################################


def test_ogr_mem_arrow_json():
pytest.importorskip("pyarrow")

ds = ogr.GetDriverByName("Memory").CreateDataSource("")
lyr = ds.CreateLayer("foo")
field_def = ogr.FieldDefn("field_json", ogr.OFTString)
field_def.SetSubType(ogr.OFSTJSON)
lyr.CreateField(field_def)

stream = lyr.GetArrowStreamAsPyArrow()
md = stream.schema["field_json"].metadata
assert b"ARROW:extension:name" in md
assert md[b"ARROW:extension:name"] == b"arrow.json"


###############################################################################
# Test Layer.GetDataset()

Expand Down
Loading

0 comments on commit bd5c096

Please sign in to comment.