Skip to content

Commit

Permalink
Merge pull request #9105 from rouault/S102_QualityOfSurvey_nodata
Browse files Browse the repository at this point in the history
S102: read NoData value for QualityOfSurvey from /Group_F/QualityOfSurvey
rouault authored Jan 31, 2024
2 parents e85546b + 1e18888 commit c118d79
Showing 4 changed files with 73 additions and 1 deletion.
22 changes: 21 additions & 1 deletion autotest/gdrivers/data/s102/generate_test.py
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ def generate(filename, version, with_QualityOfSurvey=False):
BathymetryCoverage_01.attrs["numPointsLongitudinal"] = np.uint32(values.shape[1])
BathymetryCoverage_01.attrs["numPointsLatitudinal"] = np.uint32(values.shape[0])

f.create_group("Group_F")
group_f = f.create_group("Group_F")

f.attrs["issueDate"] = "2023-12-31"
f.attrs["geographicIdentifier"] = "Somewhere"
@@ -137,6 +137,26 @@ def generate(filename, version, with_QualityOfSurvey=False):
)
featureAttributeTable[...] = data

GroupFQualityOfSurvey_struct_type = np.dtype(
[
("code", "S16"),
("name", "S16"),
("uom.name", "S16"),
("fillValue", "S16"),
("datatype", "S16"),
("lower", "S16"),
("upper", "S16"),
("closure", "S16"),
]
)
GroupFQualityOfSurvey = group_f.create_dataset(
"QualityOfSurvey", (1,), dtype=GroupFQualityOfSurvey_struct_type
)
GroupFQualityOfSurvey[...] = np.array(
[("id", "", "", "0", "H5T_INTEGER", "1", "", "geSemiInterval")],
dtype=GroupFQualityOfSurvey_struct_type,
)


generate("test_s102_v2.1", "INT.IHO.S-102.2.1")
generate("test_s102_v2.2", "INT.IHO.S-102.2.2")
Binary file modified autotest/gdrivers/data/s102/test_s102_v2.2_with_QualityOfSurvey.h5
Binary file not shown.
1 change: 1 addition & 0 deletions autotest/gdrivers/s102.py
Original file line number Diff line number Diff line change
@@ -233,6 +233,7 @@ def test_s102_QualityOfSurvey():
assert ds.GetGeoTransform() == pytest.approx((1.8, 0.4, 0.0, 48.75, 0.0, -0.5))
band = ds.GetRasterBand(1)
assert band.DataType == gdal.GDT_UInt32
assert band.GetNoDataValue() == 0
assert struct.unpack("I" * 6, band.ReadRaster()) == (1000000, 3, 2, 0, 1, 2)

rat = band.GetDefaultRAT()
51 changes: 51 additions & 0 deletions frmts/hdf5/hdf5multidim.cpp
Original file line number Diff line number Diff line change
@@ -1052,6 +1052,57 @@ HDF5Array::HDF5Array(const std::string &osParentName, const std::string &osName,
memcpy(m_abyNoData.data(), afNoData, m_abyNoData.size());
}

// Special case for S102 QualityOfSurvey nodata value that is typically at 0
if (GetFullName() ==
"/QualityOfSurvey/QualityOfSurvey.01/Group_001/values" &&
m_dt.GetClass() == GEDTC_NUMERIC &&
m_dt.GetNumericDataType() == GDT_UInt32)
{
if (auto poRootGroup = HDF5Array::GetRootGroup())
{
if (const auto poGroupF = poRootGroup->OpenGroup("Group_F"))
{
const auto poGroupFArray =
poGroupF->OpenMDArray("QualityOfSurvey");
if (poGroupFArray &&
poGroupFArray->GetDataType().GetClass() == GEDTC_COMPOUND &&
poGroupFArray->GetDataType().GetComponents().size() == 8 &&
poGroupFArray->GetDataType()
.GetComponents()[0]
->GetName() == "code" &&
poGroupFArray->GetDataType()
.GetComponents()[3]
->GetName() == "fillValue" &&
poGroupFArray->GetDimensionCount() == 1 &&
poGroupFArray->GetDimensions()[0]->GetSize() == 1)
{
auto poFillValue =
poGroupFArray->GetView("[\"fillValue\"]");
if (poFillValue)
{
char *pszVal0 = nullptr;
const GUInt64 anArrayStartIdx0[] = {0};
const size_t anCount[] = {1};
const GInt64 anArrayStep[] = {0};
const GPtrDiff_t anBufferStride[] = {0};
poFillValue->Read(anArrayStartIdx0, anCount,
anArrayStep, anBufferStride,
GDALExtendedDataType::CreateString(),
&pszVal0);
if (pszVal0)
{
const uint32_t nNoData = atoi(pszVal0);
m_abyNoData.resize(m_dt.GetSize());
memcpy(m_abyNoData.data(), &nNoData,
m_abyNoData.size());
}
CPLFree(pszVal0);
}
}
}
}
}

// Special case for S104 nodata value that is typically -9999
if (STARTS_WITH(GetFullName().c_str(), "/WaterLevel/WaterLevel.01/") &&
GetFullName().find("/values") != std::string::npos &&

0 comments on commit c118d79

Please sign in to comment.