Skip to content

Commit 192b64d

Browse files
committed
work on supporting writing to geotiff
1 parent d96967e commit 192b64d

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

test/core/store/fs/impl/test_geotiff.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ def test_read_geotiff(self):
147147

148148
class DatasetGeoTiffFsDataAccessorTest(unittest.TestCase):
149149
"""
150-
A Test class to test opening a GeoTIFF as multilevel dataset or
150+
A Test class to test opening and writing a GeoTIFF as multilevel dataset or
151151
as normal dataset
152152
"""
153153

154-
def test_ml_to_dataset(self):
154+
def test_open_ml_to_dataset(self):
155155
fs, cog_path = GeoTIFFMultiLevelDatasetTest.get_params("sample-cog.tif")
156156
data_accessor = DatasetGeoTiffFsDataAccessor()
157157
self.assertIsInstance(data_accessor, DatasetGeoTiffFsDataAccessor)
@@ -164,7 +164,7 @@ def test_ml_to_dataset(self):
164164
data_accessor.get_open_data_params_schema(cog_path), JsonSchema
165165
)
166166

167-
def test_dataset(self):
167+
def test_open_dataset(self):
168168
fs, tiff_path = GeoTIFFMultiLevelDatasetTest.get_params("sample-geotiff.tif")
169169
data_accessor = DatasetGeoTiffFsDataAccessor()
170170
self.assertIsInstance(data_accessor, DatasetGeoTiffFsDataAccessor)
@@ -178,6 +178,24 @@ def test_dataset(self):
178178
)
179179
self.assertIsInstance(dataset, xarray.Dataset)
180180

181+
def test_write_dataset(self):
182+
from xcube.core.new import new_cube
183+
fs, _ = GeoTIFFMultiLevelDatasetTest.get_params("sample-geotiff.tif")
184+
ds = new_cube(variables=dict(xxx=1, yyy=2))
185+
data_accessor = DatasetGeoTiffFsDataAccessor()
186+
tiff_path = "geotiff_write_test.tif"
187+
data_accessor.write_data(
188+
ds, tiff_path, fs=fs
189+
)
190+
dataset = data_accessor.open_data(
191+
data_id=tiff_path,
192+
fs=fs,
193+
root=None,
194+
tile_size=[256, 256],
195+
overview_level=None,
196+
)
197+
self.assertIsNotNone(dataset)
198+
181199

182200
class ObjectStorageMultiLevelDatasetTest(S3Test):
183201
"""

xcube/core/store/fs/impl/dataset.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import zarr
1414
from rasterio.session import AWSSession
1515

16+
from xcube.core.gridmapping import GridMapping
1617
# Note, we need the following reference to register the
1718
# xarray property accessor
1819
# noinspection PyUnresolvedReferences
@@ -413,7 +414,33 @@ def get_write_data_params_schema(self) -> JsonObjectSchema:
413414
def write_data(
414415
self, data: xr.Dataset, data_id: str, replace=False, **write_params
415416
) -> str:
416-
raise NotImplementedError("Writing of GeoTIFF not yet supported")
417+
assert_instance(data, xr.Dataset, name="data")
418+
assert_instance(data_id, str, name="data_id")
419+
fs, root, write_params = self.load_fs(write_params)
420+
421+
gm = GridMapping.from_dataset(data)
422+
423+
try:
424+
with fs.open(data_id, "wb") as fobj:
425+
with rasterio.open(
426+
fobj,
427+
"w",
428+
driver="GTiff",
429+
height=gm.height,
430+
width=gm.height,
431+
count=len(data.data_vars) * len(data.time),
432+
dtype=data[list(data.data_vars.keys())[0]].dtype,
433+
crs=data.rio.crs,
434+
transform=data.rio.transform(),
435+
) as dst:
436+
band_index = 1
437+
for var in data.data_vars:
438+
for time in data.time.values:
439+
dst.write(data[var].sel(time=time).values, band_index)
440+
band_index += 1
441+
except ValueError as e:
442+
raise DataStoreError(f"Failed to write dataset {data_id!r}: {e}") from e
443+
return data_id
417444

418445
@classmethod
419446
def _sanitize_dataset_attrs(cls, dataset):

0 commit comments

Comments
 (0)