diff --git a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/geotiff/package.scala b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/geotiff/package.scala index 98ac2c12a..d74598252 100644 --- a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/geotiff/package.scala +++ b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/geotiff/package.scala @@ -922,4 +922,24 @@ package object geotiff { result.collect() print("test done") } + + // TODO: favor dedicated XML type over String? + def embedGdalMetadata(gdalMetadataXml: String, geotiffPath: Path): Unit = { + import scala.sys.process._ + import java.nio.charset._ + + val outputBuffer = new StringBuilder + val processLogger = ProcessLogger(line => outputBuffer appendAll line) + + val tempFile = Files.createTempFile("GDALMetadata_", ".xml.tmp") + try { + Files.write(tempFile, s"$gdalMetadataXml\n".getBytes(StandardCharsets.US_ASCII)) + + val args = Seq("tiffset", "-sf", "42112", tempFile.toString, geotiffPath.toString) + val exitCode = args ! processLogger + if (exitCode != 0) { + throw new Exception(s"${args mkString " "} failed; output: $outputBuffer") + } + } finally Files.delete(tempFile) + } } diff --git a/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/geotiff/PackageTest.scala b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/geotiff/PackageTest.scala new file mode 100644 index 000000000..f659bb4bb --- /dev/null +++ b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/geotiff/PackageTest.scala @@ -0,0 +1,40 @@ +package org.openeo.geotrellis.geotiff + +import geotrellis.raster.io.geotiff.MultibandGeoTiff +import org.junit.jupiter.api.Assertions.{assertEquals, assertThrows, assertTrue} +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir + +import java.nio.file.{Files, Path, Paths} + +class PackageTest { + + @Test + def testEmbedGdalMetadata(@TempDir tempDir: Path): Unit = { + val geotiffCopy = tempDir.resolve("copy.tif") + Files.copy(getClass.getResourceAsStream("/org/openeo/geotrellis/cgls_ndvi300.tif"), geotiffCopy) + + assertTrue(processingSoftware(geotiffCopy).isEmpty) + + val gdalMetadataXml = + + 0.45.0a1 + CO + + + embedGdalMetadata(gdalMetadataXml.toString(), geotiffCopy) + + assertEquals(Some("0.45.0a1"), processingSoftware(geotiffCopy)) + } + + @Test + def testEmbedGdalMetadataFails(): Unit = { + val e = assertThrows(classOf[Exception], () => + embedGdalMetadata(gdalMetadataXml = "", geotiffPath = Paths.get("doesnotexist.tif"))) + + assertTrue(e.getMessage contains "doesnotexist.tif: No such file or directory") + } + + private def processingSoftware(geotiff: Path): Option[String] = + MultibandGeoTiff(geotiff.toString).tags.headTags.get("PROCESSING_SOFTWARE") +}