From 49c945003cc761ebfe694105ca99bbe20318f979 Mon Sep 17 00:00:00 2001 From: dsamaey Date: Thu, 10 Apr 2025 11:25:06 +0200 Subject: [PATCH 1/4] Issue #392 added support for "array_contains" in the OpenEOProcessScriptBuilder --- .../OpenEOProcessScriptBuilder.scala | 37 +++- .../TestOpenEOProcessScriptBuilder.java | 174 ++++++++++-------- 2 files changed, 132 insertions(+), 79 deletions(-) diff --git a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala index 4239c07db..35777c08c 100644 --- a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala +++ b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala @@ -3,7 +3,7 @@ package org.openeo.geotrellis import ai.catboost.CatBoostModel import ai.catboost.spark.CatBoostClassificationModel import geotrellis.raster.mapalgebra.local._ -import geotrellis.raster.{ArrayTile, BitCellType, ByteUserDefinedNoDataCellType, CellType, ConstantTile, Dimensions, DoubleConstantNoDataCellType, DoubleConstantTile, FloatConstantNoDataCellType, FloatConstantTile, IntConstantNoDataCellType, IntConstantTile, MultibandTile, MutableArrayTile, NODATA, ShortConstantNoDataCellType, ShortConstantTile, Tile, UByteCells, UByteConstantTile, UByteUserDefinedNoDataCellType, UShortCells, UShortUserDefinedNoDataCellType, isData, isNoData} +import geotrellis.raster.{ArrayTile, BitCellType, BitConstantTile, ByteUserDefinedNoDataCellType, CellType, ConstantTile, Dimensions, DoubleConstantNoDataCellType, DoubleConstantTile, FloatConstantNoDataCellType, FloatConstantTile, IntConstantNoDataCellType, IntConstantTile, MultibandTile, MutableArrayTile, NODATA, ShortConstantNoDataCellType, ShortConstantTile, Tile, UByteCells, UByteConstantTile, UByteUserDefinedNoDataCellType, UShortCells, UShortUserDefinedNoDataCellType, isData, isNoData} import org.apache.commons.math3.exception.NotANumberException import org.apache.commons.math3.stat.descriptive.rank.Percentile import org.apache.commons.math3.stat.descriptive.rank.Percentile.EstimationType @@ -21,11 +21,10 @@ import java.time.temporal.{ChronoUnit, TemporalAccessor} import java.time.{Duration, ZonedDateTime} import java.util import scala.Double.NaN -import scala.collection.JavaConversions.mapAsScalaMap +import scala.collection.JavaConverters.mapAsScalaMap import scala.collection.JavaConverters.collectionAsScalaIterableConverter import scala.collection.mutable.{ArrayBuffer, ListBuffer} import scala.collection.{immutable, mutable} -import scala.math.BigDecimal import scala.util.Try import scala.util.control.Breaks.{break, breakable} @@ -633,6 +632,37 @@ class OpenEOProcessScriptBuilder { contextStack.head.getOrElse(name, null).asInstanceOf[OpenEOProcess] } + private def arrayContains(arguments:java.util.Map[String,Object]) : OpenEOProcess = { + val value = getProcessArg("value") + val data = getProcessArg("data") + + val arrayContainsProcess = (context: Map[String, Any]) => (tiles: Seq[Tile]) => { + val value_input: Seq[Tile] = evaluateToTiles(value, context, tiles) + val data_input: Seq[Tile] = evaluateToTiles(data, context, tiles) + if (value_input.size != 1) { + throw new IllegalArgumentException("The value argument of the array_contains function should resolve to exactly one input.") + } + val the_value = value_input.head + val tile = MultibandTile(data_input) + + val mutableResult:MutableArrayTile = ArrayTile.empty(BitCellType,tile.cols,tile.rows) + for (column <- Range(0, tile.cols)) { + for (row <- Range(0, tile.rows)) { + breakable { + for (band <- tile.bands) { + if (band.get(column, row) == the_value.get(column, row)) { + mutableResult.set(column, row, 1) + break + } + } + } + } + } + Seq(mutableResult) + } + + arrayContainsProcess + } private def arrayFind(arguments:java.util.Map[String,Object]) : OpenEOProcess = { val storedArgs = contextStack.head @@ -1203,6 +1233,7 @@ class OpenEOProcessScriptBuilder { case "array_modify" => arrayModifyFunction(arguments) case "array_interpolate_linear" => applyListFunction("data", linearInterpolation, dataTypeMode = PRESERVE_DATATYPE_MODE) case "array_find" => arrayFind(arguments) + case "array_contains" => arrayContains(arguments) case "linear_scale_range" => linearScaleRangeFunction(arguments) case "quantiles" => quantilesFunction(arguments, ignoreNoData) case "array_concat" => arrayConcatFunction(arguments) diff --git a/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java b/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java index 8054e776e..f096d23fb 100644 --- a/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java +++ b/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java @@ -17,7 +17,6 @@ import scala.Function1; import scala.Int; import scala.Tuple2; -import scala.collection.JavaConversions; import scala.collection.JavaConverters; import scala.collection.Seq; @@ -32,7 +31,7 @@ private void testNdvi(OpenEOProcessScriptBuilder builder) { Function1, Seq> transformation = builder.generateFunction(); DoubleArrayTile tile1 = fillDoubleArrayTile(4, 2, 3, 10, 6, 3, 9, 15, 0, Double.NaN); DoubleArrayTile tile2 = fillDoubleArrayTile(4, 2, 0, 6, 10, 9, 7, 17, 0, Double.NaN); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1, tile2))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1, tile2))); assertEquals(1, result.length()); Tile ndvi = result.apply(0); assertDoubleTileEquals(fillDoubleArrayTile(4, 2, 1.0, 0.25, -0.25, -0.5, 0.125, -0.0625, Double.NaN, Double.NaN), ndvi); @@ -178,7 +177,7 @@ public void testAddConstant() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile1 = fillByteArrayTile(3, 3, 9, 10, 11, 12); ByteArrayTile tile2 = fillByteArrayTile(3, 3, 5, 6, 7, 8); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1, tile2))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1, tile2))); Tile res = result.apply(0); assertTileEquals(fillIntArrayTile(3, 3, 30, 30, 30, 30, 30, 30, 30, 30, 30), res); } @@ -192,7 +191,7 @@ public void testMultiBandMultiplyConstant() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile1 = fillByteArrayTile(3, 3, 9, -10, 11, 12); ByteArrayTile tile2 = fillByteArrayTile(3, 3, 5, 6, 7, 8); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1, tile2))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1, tile2))); assertTileEquals(fillShortArrayTile(3, 3, 90, -100, 110, 120, 0, 0, 0, 0, 0), result.apply(0)); assertTileEquals(fillShortArrayTile(3, 3, 50, 60, 70, 80, 0, 0, 0, 0, 0), result.apply(1)); @@ -227,7 +226,7 @@ public void testMultiBandMultiplyConstantFloat() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile1 = fillByteArrayTile(3, 3, 9, -10, 11, 12); ByteArrayTile tile2 = fillByteArrayTile(3, 3, 5, 6, 7, 8); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1, tile2))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1, tile2))); assertTileEquals(fillFloatArrayTile(3, 3, 90, -100, 110, 120, 0, 0, 0, 0, 0), result.apply(0)); assertTileEquals(fillFloatArrayTile(3, 3, 50, 60, 70, 80, 0, 0, 0, 0, 0), result.apply(1)); @@ -249,7 +248,7 @@ public void testMultiBandMultiply() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile1 = fillByteArrayTile(3, 3, 9, 10, 11, 12); ByteArrayTile tile2 = fillByteArrayTile(3, 3, 5, 6, 7, 8); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1, tile2))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1, tile2))); assertTileEquals(fillByteArrayTile(3, 3, 81, 100, 121, 144, 0, 0, 0, 0, 0), result.apply(0)); assertTileEquals(fillByteArrayTile(3, 3, 25, 36, 49, 64, 0, 0, 0, 0, 0), result.apply(1)); @@ -274,7 +273,7 @@ private void testLogicalComparisonWithConstant(String operator, int... expectedV assertEquals(BitCellType$.MODULE$, builder.getOutputCellType()); Tile tile = fillByteArrayTile(4, 3, 8, 9, 10, 11, 12); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile))); assertEquals(1, result.length()); Tile res = result.apply(0); assertTileEquals(fillBitArrayTile(4, 3, expectedValues), res); @@ -326,7 +325,7 @@ private void testLogicalComparisonXY(String operator, int... expectedValues) { Function1, Seq> transformation = builder.generateFunction(); Tile tile0 = fillByteArrayTile(3, 2, 8, 9, 10, 11, 12, 13); Tile tile1 = fillByteArrayTile(3, 2, 7, 9, 11, 9, 7, 5); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); assertEquals(1, result.length()); Tile res = result.apply(0); assertTileEquals(fillBitArrayTile(3, 2, expectedValues), res); @@ -453,7 +452,7 @@ public void testLogicalNotEqWithExpression() { Function1, Seq> transformation = builder.generateFunction(); Tile tile1 = fillByteArrayTile(4, 3, 8, 9, 10, 11, 12); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1))); Tile res = result.apply(0); assertTileEquals(fillBitArrayTile(4, 3, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1), res); } @@ -474,7 +473,7 @@ public void testLogicalNotEqWithX() { Function1, Seq> transformation = builder.generateFunction(); Tile tile1 = fillByteArrayTile(4, 3, 8, 9, 10, 11, 12); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1))); Tile res = result.apply(0); assertTileEquals(fillBitArrayTile(4, 3, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1), res); } @@ -518,7 +517,7 @@ private void testBetween(Object min, Object max, int[] expected, Object excludeM Function1, Seq> transformation = builder.generateFunction(); Tile tile1 = fillByteArrayTile(4, 3, 8, 9, 10, 11, 12); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1))); Tile res = result.apply(0); assertTileEquals(fillBitArrayTile(4, 3, expected), res); } @@ -534,7 +533,7 @@ private void testLogicalOperatorWithExpressionsArray(String operator, int... exp BitArrayTile x = fillBitArrayTile(4, 4, 0, 0, 1, 1); BitArrayTile y = fillBitArrayTile(4, 4, 0, 1, 0, 1); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(x, y))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(x, y))); assertEquals(1, result.length()); Tile z = result.apply(0); assertEquals("bool", z.cellType().toString()); @@ -570,7 +569,7 @@ private void testLogicalOperatorWithXY(String operator, int... expectedValues) { BitArrayTile x = fillBitArrayTile(4, 4, 0, 0, 1, 1); BitArrayTile y = fillBitArrayTile(4, 4, 0, 1, 0, 1); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(x, y))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(x, y))); assertEquals(1, result.length()); Tile z = result.apply(0); assertEquals("bool", z.cellType().toString()); @@ -604,7 +603,7 @@ private void testMathXY(String operator, Number... expectedValues) { Function1, Seq> transformation = builder.generateFunction(); Tile tile0 = fillIntArrayTile(3, 2, 3, 4, 5, 6, 7, 8); Tile tile1 = fillIntArrayTile(3, 2, 1, 2, 4, 8, 16, 20); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); assertEquals(1, result.length()); Tile res = result.apply(0); @@ -616,7 +615,7 @@ private void testMathXY(String operator, Number... expectedValues) { } - Tile doubleResult = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0.convert(CellType.fromName("float64")), tile1.convert(CellType.fromName("float64"))))).apply(0); + Tile doubleResult = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0.convert(CellType.fromName("float64")), tile1.convert(CellType.fromName("float64"))))).apply(0); assertTileEquals(expectedTile.convert(CellType.fromName("float64")), doubleResult); } @@ -647,7 +646,7 @@ public void testMathWithBitCells(String operator, int... expectedValues) { Function1, Seq> transformation = builder.generateFunction(); Tile tile0 = fillBitArrayTile(3, 2, 0,1,1,0); Tile tile1 = fillBitArrayTile(3, 2, 1,1,0,0); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); assertEquals(1, result.length()); Tile res = result.apply(0); ArrayTile expectedTile = fillByteArrayTile(3, 2, expectedValues).convert(new ByteUserDefinedNoDataCellType(((Integer)127).byteValue())); @@ -686,7 +685,7 @@ public void testNormalizedDifferenceXY() { Function1, Seq> transformation = builder.generateFunction(); DoubleArrayTile tile1 = fillDoubleArrayTile(4, 2, 3, 10, 6, 3, 9, 15, 0, Double.NaN); DoubleArrayTile tile2 = fillDoubleArrayTile(4, 2, 0, 6, 10, 9, 7, 17, 0, Double.NaN); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1, tile2))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1, tile2))); assertEquals(1, result.length()); Tile ndvi = result.apply(0); assertDoubleTileEquals(fillDoubleArrayTile(4, 2, 1.0, 0.25, -0.25, -0.5, 0.125, -0.0625, Double.NaN, Double.NaN), ndvi); @@ -702,7 +701,7 @@ private void testMathData(String operator, Number... expectedValues) { Function1, Seq> transformation = builder.generateFunction(); Tile tile0 = fillIntArrayTile(3, 2, 3, 4, 5, 6, 7, 8); Tile tile1 = fillIntArrayTile(3, 2, 1, 2, 4, 8, 16, 20); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); assertEquals(1, result.length()); Tile res = result.apply(0); assertTileEquals(fillIntArrayTile(3, 2, expectedValues), res); @@ -781,7 +780,7 @@ public void testIf() { ByteArrayTile value = ByteConstantNoDataArrayTile.fill((byte) 1, 4, 4); value.set(0, 0, 0); value.set(1, 0, 0); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, value))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, value))); Tile res = result.apply(0); tile0.set(0,0,nodataVal); tile0.set(1,0,nodataVal); @@ -820,7 +819,7 @@ public void testIfWithReject() { tile0.setDouble(1, 0, 5.5); tile0.setDouble(1, 1, 5.5); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0))); Tile res = result.apply(0); tile0.setDouble(2,0,1.5); tile0.setDouble(1,0,1.5); @@ -861,7 +860,7 @@ public void testIfWithRejectCube() { tile0.setDouble(1, 0, 5.5); tile0.setDouble(1, 1, 5.5); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0,tile0))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0,tile0))); FloatArrayTile expected = FloatArrayTile.fill( 1.5f, 4, 4); expected.setDouble(2,0,Float.NaN); expected.setDouble(1,0,5.5); @@ -890,12 +889,12 @@ public void testFirstWithNoData() { ByteArrayTile tile_timestep1 = ByteConstantNoDataArrayTile.fill((byte)5, 4, 4); // Then selecting all first pixels from a list of one timestep just returns us that tile. - Seq single_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy()))); + Seq single_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy()))); assertTileEquals(tile_timestep0, single_input.apply(0)); // When a second timestep is added that has actual values, the Nodata from the first tile will still be selected. // Because ignore_nodata is set to false. - Seq multiple_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); + Seq multiple_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); assertEquals(Int.MinValue(), multiple_input.apply(0).get(0,0)); // Including the one non-NoData value in timestep 0. assertEquals(3, multiple_input.apply(0).get(2,2)); @@ -926,11 +925,11 @@ public void testFirstIgnoreNodata() { ByteArrayTile tile_timestep1 = ByteConstantNoDataArrayTile.fill((byte)5, 4, 4); // Then selecting all first pixels from a list of one timestep just returns us that tile, even if it has NoData values. - Seq single_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy()))); + Seq single_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy()))); assertTileEquals(tile_timestep0, single_input.apply(0)); // When a second timestep is added that has actual values, those will be selected as first instead of the NoData values. - Seq multiple_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); + Seq multiple_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); assertEquals(5, multiple_input.apply(0).get(0,0)); // Except for the one non-NoData value in timestep 0. assertEquals(3, multiple_input.apply(0).get(2,2)); @@ -966,12 +965,12 @@ public void testLastWithNoData() { tile_timestep1.set(2,2,3); // Then selecting all last pixels from a list of one timestep just returns us that tile. - Seq single_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep1.mutable().copy()))); + Seq single_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep1.mutable().copy()))); assertTileEquals(tile_timestep1, single_input.apply(0)); // When a second timestep is prepended that has actual values, the Nodata from the last tile will be selected. // Because ignore_nodata is set to false. - Seq multiple_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); + Seq multiple_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); assertEquals(Int.MinValue(), multiple_input.apply(0).get(0,0)); // Including the one non-NoData value in timestep 1. assertEquals(3, multiple_input.apply(0).get(2,2)); @@ -1002,11 +1001,11 @@ public void testLastIgnoreNodata() { tile_timestep1.set(2,2,3); // Then selecting all last pixels from a list of one timestep just returns us that tile. - Seq single_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep1.mutable().copy()))); + Seq single_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep1.mutable().copy()))); assertTileEquals(tile_timestep1, single_input.apply(0)); // When a second timestep is prepended that has actual values, those will be selected as last instead of the NoData values. - Seq multiple_input = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); + Seq multiple_input = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile_timestep0.mutable().copy(), tile_timestep1.mutable().copy()))); assertEquals(5, multiple_input.apply(0).get(0,0)); // Except for the one non-NoData value in timestep 1. assertEquals(3, multiple_input.apply(0).get(2,2)); @@ -1031,7 +1030,7 @@ public void testInt() { private void testUnary( String processName, String argName, double... expectedValues) { OpenEOProcessScriptBuilder builder = buildUnaryProcess(processName, argName); Function1, Seq> transformation = builder.generateFunction(); - Seq result1 = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(fillFloatArrayTile(3, 3, 0, 3.5, -0.4, -3.5, Double.NaN)))); + Seq result1 = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(fillFloatArrayTile(3, 3, 0, 3.5, -0.4, -3.5, Double.NaN)))); assertTileEquals(fillFloatArrayTile(3, 3, expectedValues), result1.head()); } @@ -1052,7 +1051,7 @@ private void testUnary( String processName, String argName, int... expectedValue OpenEOProcessScriptBuilder builder = buildUnaryProcess(processName, argName); Function1, Seq> transformation = builder.generateFunction(); - Seq result1 = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(fillFloatArrayTile(3, 3, 0, 3.5, -0.4, -3.5, Double.NaN)))); + Seq result1 = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(fillFloatArrayTile(3, 3, 0, 3.5, -0.4, -3.5, Double.NaN)))); assertTileEquals(fillShortArrayTile(3, 3, expectedValues).convert(IntConstantNoDataCellType$.MODULE$), result1.head()); @@ -1073,7 +1072,7 @@ public void testIsNoDataAndIsNan() { tile0.setDouble(0,0, 5.0); tile0.setDouble(2,1, 4.0); tile0.setDouble(2,2, 17.0); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile0))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile0))); Tile res = result.apply(0); int expected_values[] = {0, 1, 1, 1, 1, 0, 1, 1, 0}; @@ -1085,7 +1084,7 @@ public void testIsNoDataAndIsNan() { isNanBuilder.argumentStart("x"); isNanBuilder.argumentEnd(); isNanBuilder.expressionEnd("is_nan", dummyMap("x")); - Seq result2 = isNanBuilder.generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile0))); + Seq result2 = isNanBuilder.generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile0))); assertTileEquals(fillBitArrayTile(3, 3, expected_values), result2.head()); } @@ -1111,7 +1110,7 @@ public void testArrayElement() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); Tile res = result.apply(0); assertTileEquals(tile1, res); assertEquals(ByteConstantNoDataCellType$.MODULE$,res.cellType()); @@ -1137,7 +1136,7 @@ public void testArrayElementByLabel() { assertEquals(ByteConstantNoDataCellType$.MODULE$,builder.getOutputCellType()); ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); Tile res = result.apply(0); assertTileEquals(tile1, res); } @@ -1171,7 +1170,7 @@ public void testArrayFind() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); ArrayTile expectedResult = ShortConstantNoDataArrayTile.fill((short) 1, 4, 4); assertTileEquals(expectedResult, result.head()); @@ -1207,7 +1206,7 @@ public void testArrayFindReverse() { ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1,tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1,tile1))); ByteArrayTile expectedResult = ByteConstantNoDataArrayTile.fill((byte) 2, 4, 4); assertTileEquals(expectedResult.convert(ShortConstantNoDataCellType$.MODULE$), result.head()); @@ -1232,10 +1231,33 @@ public void testArrayFindNoMatch() { ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Tile emptyResult = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))).head(); + Tile emptyResult = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))).head(); assertTrue(emptyResult.isNoDataTile()); } + @DisplayName("Test array_contains process") + @Test + public void testArrayContains() { + OpenEOProcessScriptBuilder builder = new OpenEOProcessScriptBuilder(); + Map arguments = Collections.emptyMap(); + + builder.expressionStart("array_contains", arguments); + builder.argumentStart("data"); + builder.argumentEnd(); + builder.constantArgument("value",0); + builder.expressionEnd("array_contains",arguments); + + Function1, Seq> transformation = builder.generateFunction(); + ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fromBytes(new byte[]{0,10,10,5,0,5,10,5,0,5,10,5,0,5,10,5}, 4, 4); + ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fromBytes(new byte[]{0,10,5,0,5,10,5,0,5,10,5,0,5,10,5,0}, 4, 4); + ByteArrayTile tile2 = ByteConstantNoDataArrayTile.fromBytes(new byte[]{5,10,5,0,5,10,5,0,5,10,5,0,5,10,5,0}, 4, 4); + ByteArrayTile tile3 = ByteConstantNoDataArrayTile.fromBytes(new byte[]{0,5,10,0,5,10,5,0,5,10,5,0,5,10,5,0}, 4, 4); + + Tile result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1, tile2, tile3))).head(); + BitArrayTile expectedResult = BitArrayTile.fromBytes(new byte[]{(byte)153, (byte)153}, 4, 4); + assertTileEquals(expectedResult, result); + } + @DisplayName("Test array_modify process: insert") @Test public void testArrayModifyInsert() { @@ -1257,7 +1279,7 @@ public void testArrayModifyInsert() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); assertEquals(3,result.size()); Tile res = result.apply(0); assertTileEquals(tile0, res); @@ -1340,7 +1362,7 @@ public void testArrayConcat() { ByteArrayTile t3 = ByteConstantNoDataArrayTile.fill((byte) 3, 4, 4); ByteArrayTile t4 = ByteConstantNoDataArrayTile.fill((byte) 4, 4, 4); ByteArrayTile t5 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(t0, t1, t2, t3, t4, t5))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(t0, t1, t2, t3, t4, t5))); assertEquals(5, result.size()); assertTileEquals(t4, result.apply(0)); assertTileEquals(t2, result.apply(1)); @@ -1376,7 +1398,7 @@ public void testArrayCreate(String type) { case "int16": theConstant = (byte)10; break; case "float32": theConstant = 1.005; break; - }; + } OpenEOProcessScriptBuilder builder = new OpenEOProcessScriptBuilder(); builder.defaultDataParameterName_$eq("data"); @@ -1421,7 +1443,7 @@ public void testArrayCreate(String type) { assertEquals(constantType,builder.getOutputCellType()); Tile t0 = ByteConstantNoDataArrayTile.fill((byte) 0, 4, 4).convert(constantType); Tile t1 = ByteConstantNoDataArrayTile.fill((byte) 1, 4, 4).convert(constantType); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(t0, t1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(t0, t1))); assertEquals(6, result.size()); assertTileEquals(t1, result.apply(0)); assertTileEquals(t0, result.apply(1)); @@ -1440,7 +1462,7 @@ public void testArrayInterpolateLinear() { ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile nodataTile = ByteConstantNoDataArrayTile.empty(4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile,nodataTile,tile0, nodataTile,tile1, nodataTile,nodataTile,tile0,nodataTile).stream().map(byteArrayTile -> byteArrayTile.copy()).collect(Collectors.toList()))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile,nodataTile,tile0, nodataTile,tile1, nodataTile,nodataTile,tile0,nodataTile).stream().map(byteArrayTile -> byteArrayTile.copy()).collect(Collectors.toList()))); assertEquals(9,result.size()); assertTrue(result.apply(0).isNoDataTile()); assertTrue(result.apply(1).isNoDataTile()); @@ -1466,7 +1488,7 @@ public void testLinearScaleRange() { Tile tile3 = FloatConstantNoDataArrayTile.fill(1.9f, 4, 4); Tile nodataTile = new ByteConstantTile((byte)123, 4, 4, ByteUserDefinedNoDataCellType.apply((byte)123)); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile,tile0,tile1,tile2,tile3))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile,tile0,tile1,tile2,tile3))); assertTrue(result.apply(0).isNoDataTile()); @@ -1491,7 +1513,7 @@ public void testLinearScaleRangeToShort() { Tile tile3 = FloatConstantNoDataArrayTile.fill(19f, 4, 4); Tile nodataTile = ByteConstantNoDataArrayTile.empty(4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile,tile0,tile1,tile2,tile3))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile,tile0,tile1,tile2,tile3))); assertTrue(result.apply(0).isNoDataTile()); assertEquals(UShortUserDefinedNoDataCellType.apply((short)65535),result.apply(1).cellType()); @@ -1514,18 +1536,18 @@ public void testMedian() { Tile tile3 = ByteConstantNoDataArrayTile.fill((byte)19, 4, 4); Tile nodataTile = ByteConstantNoDataArrayTile.empty(4, 4); - Seq result = createMedian(null,tile0.cellType()).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile.mutable().copy(),tile1.mutable().copy(),nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); + Seq result = createMedian(null,tile0.cellType()).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile.mutable().copy(),tile1.mutable().copy(),nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); assertEquals(ByteConstantNoDataCellType.withDefaultNoData(),result.apply(0).cellType()); assertEquals(3,result.apply(0).get(0,0)); - Seq result_nodata = createMedian(false,tile0.cellType()).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1.mutable().copy(),tile1.mutable().copy(),tile1,tile2,nodataTile,tile3,tile0))); + Seq result_nodata = createMedian(false,tile0.cellType()).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1.mutable().copy(),tile1.mutable().copy(),tile1,tile2,nodataTile,tile3,tile0))); assertTrue(result_nodata.apply(0).isNoDataTile()); - Seq single_input = createMedian(true,tile0.cellType()).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile2.mutable().copy()))); + Seq single_input = createMedian(true,tile0.cellType()).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile2.mutable().copy()))); assertEquals(-10,single_input.apply(0).get(0,0)); - Seq even_input = createMedian(true,tile0.cellType()).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile2.mutable().copy(),tile1))); + Seq even_input = createMedian(true,tile0.cellType()).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile2.mutable().copy(),tile1))); assertEquals(-3.0,even_input.apply(0).get(0,0)); } @@ -1539,18 +1561,18 @@ public void testStandardDeviation() { Tile nodataTile = FloatConstantNoDataArrayTile.empty(4, 4); FloatConstantNoDataCellType$ ct = FloatConstantNoDataCellType$.MODULE$; - Seq result = createStandardDeviation(null, ct).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile.mutable().copy(),tile1.mutable().copy(),nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); + Seq result = createStandardDeviation(null, ct).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile.mutable().copy(),tile1.mutable().copy(),nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); assertEquals(FloatConstantNoDataArrayTile.empty(0, 0).cellType(), result.apply(0).cellType()); assertEquals(9.261029243469238,result.apply(0).getDouble(0,0)); - Seq result_nodata = createStandardDeviation(false,ct).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1.mutable().copy(),tile1.mutable().copy(),tile1,tile2,nodataTile,tile3,tile0))); + Seq result_nodata = createStandardDeviation(false,ct).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1.mutable().copy(),tile1.mutable().copy(),tile1,tile2,nodataTile,tile3,tile0))); assertTrue(result_nodata.apply(0).isNoDataTile()); - Seq input1 = createStandardDeviation(true,ct).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile2.mutable().copy(), tile3))); + Seq input1 = createStandardDeviation(true,ct).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile2.mutable().copy(), tile3))); assertEquals(20.50609588623047, input1.apply(0).getDouble(0,0)); - Seq input2 = createStandardDeviation(true,ct).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile2.mutable().copy(),tile1, nodataTile))); + Seq input2 = createStandardDeviation(true,ct).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile2.mutable().copy(),tile1, nodataTile))); assertEquals(9.192388534545898, input2.apply(0).getDouble(0,0)); } @@ -1564,21 +1586,21 @@ public void testQuantiles() { Tile tile3 = ByteConstantNoDataArrayTile.fill((byte)19, 4, 4); Tile nodataTile = ByteConstantNoDataArrayTile.empty(4, 4); - Seq result = createQuantiles(null,2).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile.mutable().copy(),tile1.mutable().copy(),nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); + Seq result = createQuantiles(null,2).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile.mutable().copy(),tile1.mutable().copy(),nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); assertEquals(ByteConstantNoDataCellType.withDefaultNoData(),result.apply(0).cellType()); assertEquals(3,result.apply(0).get(0,0)); - //Seq result_nodata = createQuantiles(false,2).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile1.mutable().copy(),tile1.mutable().copy(),tile1,tile2,nodataTile,tile3,tile0))); + //Seq result_nodata = createQuantiles(false,2).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile1.mutable().copy(),tile1.mutable().copy(),tile1,tile2,nodataTile,tile3,tile0))); //assertTrue(result_nodata.apply(0).isNoDataTile()); - Seq single_input = createQuantiles(true,2).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile2))); + Seq single_input = createQuantiles(true,2).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile2))); assertEquals(-10,single_input.apply(0).get(0,0)); - Seq even_input = createQuantiles(true,2).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile2,tile1))); + Seq even_input = createQuantiles(true,2).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile2,tile1))); assertEquals(-3.0,even_input.apply(0).get(0,0)); - Seq quartiles = createQuantiles(null,4).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile,tile1,nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); + Seq quartiles = createQuantiles(null,4).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile,tile1,nodataTile,tile1,tile1,tile2,nodataTile,tile3,tile0))); Object[] elements = JavaConverters.seqAsJavaListConverter(quartiles).asJava().stream().map(v1 -> v1.get(0, 0)).toArray(); //nd,3,nd,3,3,-10,nd,19,nd // -10,1 ,3 3 3 19 nd nd nd nd @@ -1597,8 +1619,8 @@ public void testQuantilesOnFloats() { List tiles = Arrays.stream(values).mapToObj(d -> FloatConstantNoDataArrayTile.fill((float)d, 4, 4).mutable()).collect(Collectors.toList()); - Seq result = createQuantiles(null,10).generateFunction().apply(JavaConversions.asScalaBuffer(tiles)); - Collection javaCollection = JavaConversions.asJavaCollection(result); + Seq result = createQuantiles(null,10).generateFunction().apply(JavaConverters.asScalaBuffer(tiles)); + Collection javaCollection = JavaConverters.asJavaCollection(result); double[] quantiles = javaCollection.stream().mapToDouble(t -> t.getDouble(0, 0)).toArray(); double[] expected = {0.01131441444158554, 0.014035594649612904, 0.015291771851480007, 0.015623917803168297, 0.01615156978368759, 0.016581697389483452, 0.01708749309182167, 0.018107332289218903, 0.022564664483070374}; @@ -1620,8 +1642,8 @@ public void testClip() { Tile tile3 = FloatConstantNoDataArrayTile.fill(3.5f, 4, 4); Tile nodataTile = FloatConstantNoDataArrayTile.empty(4, 4); - Seq result1 = transformation1.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); - Seq result2 = transformation2.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); + Seq result1 = transformation1.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); + Seq result2 = transformation2.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); assertTrue(result1.apply(0).isNoDataTile()); assertEquals(1, result1.apply(1).getDouble(0,0)); @@ -1652,19 +1674,19 @@ public void testCount() { Tile tile2 = FloatConstantNoDataArrayTile.fill(4, 4, 4); Tile tile3 = FloatConstantNoDataArrayTile.fill(Float.NaN, 4, 4); - Seq result1 = createCount(false).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); + Seq result1 = createCount(false).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); assertEquals(3, result1.apply(0).get(0, 0)); - Seq result2 = createCount(true).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); + Seq result2 = createCount(true).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); assertEquals(4, result2.apply(0).get(0, 0)); - Seq result3 = createCount("gt", 2.0, false).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); + Seq result3 = createCount("gt", 2.0, false).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); assertEquals(2, result3.apply(0).get(0, 0)); - Seq result4 = createCount("eq", 3.0, true).generateFunction().apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); + Seq result4 = createCount("eq", 3.0, true).generateFunction().apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0.mutable().copy(), tile1.mutable().copy(), tile2.mutable().copy(), tile3.mutable().copy()))); assertEquals(3, result4.apply(0).get(0, 0)); } @@ -1718,7 +1740,7 @@ private Seq predictWithDefaultRandomForestClassifier(scala.collection.muta List> contextTuples = javaContext.entrySet().stream() .map(e -> Tuple2.apply(e.getKey(), e.getValue())) .collect(Collectors.toList()); - scala.collection.immutable.Map scalaContext = scala.collection.immutable.Map$.MODULE$.apply(JavaConversions.asScalaBuffer(contextTuples).toSeq()); + scala.collection.immutable.Map scalaContext = scala.collection.immutable.Map$.MODULE$.apply(JavaConverters.asScalaBuffer(contextTuples).toSeq()); Seq result = builder .generateFunction(scalaContext) @@ -1743,7 +1765,7 @@ public void testPredictRandomForest() { tile2.setDouble(col, row, (random.nextDouble() * 10)); } } - scala.collection.mutable.Buffer tiles = JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1, tile2)); + scala.collection.mutable.Buffer tiles = JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1, tile2)); Seq result = predictWithDefaultRandomForestClassifier(tiles, random); assertEquals(FloatCellType.withDefaultNoData(),result.apply(0).cellType()); assertEquals(8, result.apply(0).get(0,0)); @@ -1767,14 +1789,14 @@ public void testPredictRandomForestWithWrongArguments() { tile1.setDouble(col, row, (random.nextDouble() * 10)); } } - scala.collection.mutable.Buffer tiles = JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1)); + scala.collection.mutable.Buffer tiles = JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1)); assertThrows(IllegalArgumentException.class, () -> predictWithDefaultRandomForestClassifier(tiles, random)); // NoData cells. FloatArrayTile emptyTile0 = FloatArrayTile.empty(4,4); FloatArrayTile emptyTile1 = FloatArrayTile.empty(4,4); FloatArrayTile emptyTile2 = FloatArrayTile.empty(4,4); - scala.collection.mutable.Buffer emptyTiles = JavaConversions.asScalaBuffer(Arrays.asList(emptyTile0, emptyTile1, emptyTile2)); + scala.collection.mutable.Buffer emptyTiles = JavaConverters.asScalaBuffer(Arrays.asList(emptyTile0, emptyTile1, emptyTile2)); Seq result = predictWithDefaultRandomForestClassifier(emptyTiles, random); double noDataValue = emptyTile0.get(0,0); assertEquals(noDataValue, result.apply(0).get(0,0)); @@ -1804,7 +1826,7 @@ public void testInspect() { Function1, Seq> transformation = builder.generateFunction(); ByteArrayTile tile0 = ByteConstantNoDataArrayTile.fill((byte) 10, 4, 4); ByteArrayTile tile1 = ByteConstantNoDataArrayTile.fill((byte) 5, 4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(tile0, tile1))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1))); Tile res = result.apply(0); assertTileEquals(tile0, res); } @@ -1958,7 +1980,7 @@ public void testArrayApply() { Tile tile3 = FloatConstantNoDataArrayTile.fill(1.9f, 4, 4); Tile nodataTile = ByteConstantNoDataArrayTile.empty(4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); assertTrue(result.apply(0).isNoDataTile()); @@ -1975,14 +1997,14 @@ public void testArrayApply() { @DisplayName("Test array_apply with date difference process") public void testArrayApplyDateDifference(boolean fixedDate) { OpenEOProcessScriptBuilder builder = createArrayApplyDateDifference(fixedDate); - Function1, Seq> transformation = builder.generateFunction(Collections.singletonMap("array_labels",JavaConversions.asScalaBuffer(Arrays.asList("2022-01-04T04:00:00Z","2022-01-05T00:00:00Z","2016-02-29T00:00:00Z","2019-06-15T00:00:00Z","2030-12-31T00:00:00Z")))); + Function1, Seq> transformation = builder.generateFunction(Collections.singletonMap("array_labels",JavaConverters.asScalaBuffer(Arrays.asList("2022-01-04T04:00:00Z","2022-01-05T00:00:00Z","2016-02-29T00:00:00Z","2019-06-15T00:00:00Z","2030-12-31T00:00:00Z")))); Tile tile0 = FloatConstantNoDataArrayTile.fill(1, 4, 4); Tile tile1 = FloatConstantNoDataArrayTile.fill(3, 4, 4); Tile tile2 = FloatConstantNoDataArrayTile.fill(-1, 4, 4); Tile tile3 = FloatConstantNoDataArrayTile.fill(1.9f, 4, 4); Tile nodataTile = ByteConstantNoDataArrayTile.empty(4, 4); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); if (fixedDate) { assertEquals(-2.16666, result.apply(0).getDouble(0, 0),0.001); @@ -2113,14 +2135,14 @@ public void testBAP() { builder.argumentEnd(); builder.expressionEnd("array_apply", Collections.EMPTY_MAP); - Function1, Seq> transformation = builder.generateFunction(Collections.singletonMap("array_labels",JavaConversions.asScalaBuffer(Arrays.asList("2022-01-04T04:00:00Z","2022-01-05T00:00:00Z","2022-01-14T00:00:00Z","2022-01-16T00:00:00Z","2022-01-21T00:00:00Z")))); + Function1, Seq> transformation = builder.generateFunction(Collections.singletonMap("array_labels",JavaConverters.asScalaBuffer(Arrays.asList("2022-01-04T04:00:00Z","2022-01-05T00:00:00Z","2022-01-14T00:00:00Z","2022-01-16T00:00:00Z","2022-01-21T00:00:00Z")))); Tile tile0 = FloatConstantNoDataArrayTile.fill(5, 1, 1); Tile tile1 = FloatConstantNoDataArrayTile.fill(3, 1, 1); Tile tile2 = FloatConstantNoDataArrayTile.fill(1, 1, 1); Tile tile3 = FloatConstantNoDataArrayTile.fill(1.9f, 1, 1); Tile nodataTile = ByteConstantNoDataArrayTile.empty(1, 1); - Seq result = transformation.apply(JavaConversions.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); + Seq result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(nodataTile, tile0, tile1, tile2, tile3))); BitConstantTile trueTile = new BitConstantTile(true, 1, 1); assertTileEquals(trueTile,result.apply(0)); assertTileEquals(trueTile,result.apply(1)); From 3a67b6ccbafd96b866c604620afd74fd5f3209a5 Mon Sep 17 00:00:00 2001 From: dsamaey Date: Thu, 10 Apr 2025 13:50:11 +0200 Subject: [PATCH 2/4] Issue #392 fixed compilation issue --- .../OpenEOProcessScriptBuilder.scala | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala index 35777c08c..730e13e5e 100644 --- a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala +++ b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala @@ -3,7 +3,7 @@ package org.openeo.geotrellis import ai.catboost.CatBoostModel import ai.catboost.spark.CatBoostClassificationModel import geotrellis.raster.mapalgebra.local._ -import geotrellis.raster.{ArrayTile, BitCellType, BitConstantTile, ByteUserDefinedNoDataCellType, CellType, ConstantTile, Dimensions, DoubleConstantNoDataCellType, DoubleConstantTile, FloatConstantNoDataCellType, FloatConstantTile, IntConstantNoDataCellType, IntConstantTile, MultibandTile, MutableArrayTile, NODATA, ShortConstantNoDataCellType, ShortConstantTile, Tile, UByteCells, UByteConstantTile, UByteUserDefinedNoDataCellType, UShortCells, UShortUserDefinedNoDataCellType, isData, isNoData} +import geotrellis.raster.{ArrayTile, BitCellType, ByteUserDefinedNoDataCellType, CellType, ConstantTile, Dimensions, DoubleConstantNoDataCellType, DoubleConstantTile, FloatConstantNoDataCellType, FloatConstantTile, IntConstantNoDataCellType, IntConstantTile, MultibandTile, MutableArrayTile, NODATA, ShortConstantNoDataCellType, ShortConstantTile, Tile, UByteCells, UByteConstantTile, UByteUserDefinedNoDataCellType, UShortCells, UShortUserDefinedNoDataCellType, isData, isNoData} import org.apache.commons.math3.exception.NotANumberException import org.apache.commons.math3.stat.descriptive.rank.Percentile import org.apache.commons.math3.stat.descriptive.rank.Percentile.EstimationType @@ -21,10 +21,11 @@ import java.time.temporal.{ChronoUnit, TemporalAccessor} import java.time.{Duration, ZonedDateTime} import java.util import scala.Double.NaN -import scala.collection.JavaConverters.mapAsScalaMap +import scala.collection.JavaConversions.mapAsScalaMap import scala.collection.JavaConverters.collectionAsScalaIterableConverter import scala.collection.mutable.{ArrayBuffer, ListBuffer} import scala.collection.{immutable, mutable} +import scala.math.BigDecimal import scala.util.Try import scala.util.control.Breaks.{break, breakable} @@ -637,20 +638,20 @@ class OpenEOProcessScriptBuilder { val data = getProcessArg("data") val arrayContainsProcess = (context: Map[String, Any]) => (tiles: Seq[Tile]) => { - val value_input: Seq[Tile] = evaluateToTiles(value, context, tiles) - val data_input: Seq[Tile] = evaluateToTiles(data, context, tiles) - if (value_input.size != 1) { - throw new IllegalArgumentException("The value argument of the array_contains function should resolve to exactly one input.") + val valueInput: Seq[Tile] = evaluateToTiles(value, context, tiles) + val dataInput: Seq[Tile] = evaluateToTiles(data, context, tiles) + if (valueInput.size != 1) { + throw new IllegalArgumentException(f"The value argument of the array_contains function should resolve to exactly one input, got ${valueInput.size}.") } - val the_value = value_input.head - val tile = MultibandTile(data_input) + val theValue = valueInput.head + val tile = MultibandTile(dataInput) val mutableResult:MutableArrayTile = ArrayTile.empty(BitCellType,tile.cols,tile.rows) for (column <- Range(0, tile.cols)) { for (row <- Range(0, tile.rows)) { breakable { for (band <- tile.bands) { - if (band.get(column, row) == the_value.get(column, row)) { + if (band.get(column, row) == theValue.get(column, row)) { mutableResult.set(column, row, 1) break } From 86b99e2f2e6afb99c0a398a5686315af80ffa2a1 Mon Sep 17 00:00:00 2001 From: dsamaey Date: Wed, 23 Apr 2025 11:53:50 +0200 Subject: [PATCH 3/4] Issue #392 array_contains support (PR remarks) --- .../OpenEOProcessScriptBuilder.scala | 7 ++-- .../TestOpenEOProcessScriptBuilder.java | 2 ++ .../OpenEOProcessGraphBuilderTest.scala | 35 +++++++++++++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala index 730e13e5e..e97846106 100644 --- a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala +++ b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala @@ -25,7 +25,6 @@ import scala.collection.JavaConversions.mapAsScalaMap import scala.collection.JavaConverters.collectionAsScalaIterableConverter import scala.collection.mutable.{ArrayBuffer, ListBuffer} import scala.collection.{immutable, mutable} -import scala.math.BigDecimal import scala.util.Try import scala.util.control.Breaks.{break, breakable} @@ -647,8 +646,8 @@ class OpenEOProcessScriptBuilder { val tile = MultibandTile(dataInput) val mutableResult:MutableArrayTile = ArrayTile.empty(BitCellType,tile.cols,tile.rows) - for (column <- Range(0, tile.cols)) { - for (row <- Range(0, tile.rows)) { + cfor(0)(_ < tile.rows, _ + 1) { row => + cfor(0)(_ < tile.cols, _ + 1) { column => breakable { for (band <- tile.bands) { if (band.get(column, row) == theValue.get(column, row)) { @@ -1252,7 +1251,7 @@ class OpenEOProcessScriptBuilder { if(operator != "linear_scale_range") { //TODO: generalize to other operations that result in a specific datatype? - if(Array("gt","lt","lte","gte","eq","neq","between","any","and","all","or", "is_nodata", "is_nan").contains(operator)) { + if(Array("gt","lt","lte","gte","eq","neq","between","any","and","all","or", "is_nodata", "is_nan", "array_contains").contains(operator)) { resultingDataType = BitCellType } } diff --git a/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java b/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java index f096d23fb..38b7c020e 100644 --- a/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java +++ b/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java @@ -1253,6 +1253,8 @@ public void testArrayContains() { ByteArrayTile tile2 = ByteConstantNoDataArrayTile.fromBytes(new byte[]{5,10,5,0,5,10,5,0,5,10,5,0,5,10,5,0}, 4, 4); ByteArrayTile tile3 = ByteConstantNoDataArrayTile.fromBytes(new byte[]{0,5,10,0,5,10,5,0,5,10,5,0,5,10,5,0}, 4, 4); + assertEquals(BitCellType$.MODULE$, builder.resultingDataType()); + Tile result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1, tile2, tile3))).head(); BitArrayTile expectedResult = BitArrayTile.fromBytes(new byte[]{(byte)153, (byte)153}, 4, 4); assertTileEquals(expectedResult, result); diff --git a/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala index 9878371bd..712165f45 100644 --- a/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala +++ b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import geotrellis.raster.{ByteArrayTile, ByteConstantNoDataCellType, ShortArrayTile, Tile} import org.junit.jupiter.api.Assertions.{assertEquals, assertNotNull} +import java.nio.charset.Charset import java.util import scala.collection.mutable.ArrayBuffer @@ -102,19 +103,47 @@ class OpenEOProcessGraphBuilderTest { assert(result) } + @Test + def testArrayFind(): Unit = { + val graphPath = IOUtils.toString(getClass.getResource("/org/openeo/geotrellis/testArrayFindProcessGraph.json"), Charset.defaultCharset()) + val visitor = (new GeotrellisTileProcessGraphVisitor).create() + val graph = new ObjectMapper().readValue(graphPath,classOf[util.Map[String,Object]]) + println(graph) + visitor._acceptDict(graph) + // val processes = visitor.processes + // assert(processes.size==4) + // for (process <- processes) { + // print(process) + // } + } + + + @Test + def testArrayContains(): Unit = { + val graphPath = IOUtils.toString(getClass.getResource("/org/openeo/geotrellis/testArrayContainsProcessGraph.json"), Charset.defaultCharset()) + val visitor = (new GeotrellisTileProcessGraphVisitor).create() + val graph = new ObjectMapper().readValue(graphPath,classOf[util.Map[String,Object]]) + println(graph) + visitor.acceptProcessGraph(graph) +// val processes = visitor.processes +// assert(processes.size==4) +// for (process <- processes) { +// print(process) +// } + } @Test def testAcceptDict(): Unit ={ - val graphPath = IOUtils.toString(getClass.getResource("/org/openeo/geotrellis/ProcessGraphBuilderGraph.json")) + val graphPath = IOUtils.toString(getClass.getResource("/org/openeo/geotrellis/ProcessGraphBuilderGraph.json"), Charset.defaultCharset()) val visitor = (new GeotrellisTileProcessGraphVisitor).create() val graph = new ObjectMapper().readValue(graphPath,classOf[util.Map[String,Object]]) visitor._acceptDict(graph) val processes = visitor.processes assert(processes.size==4) - for (process <- processes) + for (process <- processes) { print(process) - + } assert(true) } From 8f87ed64b1ed4c06ac4ce6e3e9d148521dec7449 Mon Sep 17 00:00:00 2001 From: dsamaey Date: Thu, 24 Apr 2025 14:18:50 +0200 Subject: [PATCH 4/4] Issue #392 array_contains support (fixed tests) --- .../OpenEOProcessScriptBuilder.scala | 1 - .../scala/org/openeo/geotrellis/package.scala | 1 - .../TestOpenEOProcessScriptBuilder.java | 1 + .../testArrayContainsProcessGraph.json | 12 +++++ .../geotrellis/testArrayFindProcessGraph.json | 12 +++++ .../OpenEOProcessGraphBuilderTest.scala | 45 ++++++++----------- .../openeo/geotrellis/testutil/package.scala | 26 +++++++++++ 7 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayContainsProcessGraph.json create mode 100644 openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayFindProcessGraph.json create mode 100644 openeo-geotrellis/src/test/scala/org/openeo/geotrellis/testutil/package.scala diff --git a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala index e97846106..5dd20f375 100644 --- a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala +++ b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/OpenEOProcessScriptBuilder.scala @@ -672,7 +672,6 @@ class OpenEOProcessScriptBuilder { val reverse = (arguments.getOrDefault("reverse",Boolean.box(false).asInstanceOf[Object]) == Boolean.box(true) || arguments.getOrDefault("reverse",None) == "true" ) resultingDataType = ShortConstantNoDataCellType - val arrayfindProcess = (context: Map[String, Any]) => (tiles: Seq[Tile]) => { val value_input: Seq[Tile] = evaluateToTiles(value, context, tiles) val data_input: Seq[Tile] = evaluateToTiles(data, context, tiles) diff --git a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/package.scala b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/package.scala index 54df9245d..fea4d01eb 100644 --- a/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/package.scala +++ b/openeo-geotrellis/src/main/scala/org/openeo/geotrellis/package.scala @@ -27,7 +27,6 @@ import java.time.temporal.ChronoUnit import java.time.{Duration, Instant} import java.util.concurrent.ConcurrentHashMap import scala.compat.java8.FunctionConverters._ -import scala.reflect.io.Directory package object geotrellis { diff --git a/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java b/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java index 38b7c020e..38271be59 100644 --- a/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java +++ b/openeo-geotrellis/src/test/java/org/openeo/geotrellis/TestOpenEOProcessScriptBuilder.java @@ -1257,6 +1257,7 @@ public void testArrayContains() { Tile result = transformation.apply(JavaConverters.asScalaBuffer(Arrays.asList(tile0, tile1, tile2, tile3))).head(); BitArrayTile expectedResult = BitArrayTile.fromBytes(new byte[]{(byte)153, (byte)153}, 4, 4); + System.out.println(transformation); assertTileEquals(expectedResult, result); } diff --git a/openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayContainsProcessGraph.json b/openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayContainsProcessGraph.json new file mode 100644 index 000000000..5880deb90 --- /dev/null +++ b/openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayContainsProcessGraph.json @@ -0,0 +1,12 @@ +{ + "contains": { + "process_id": "array_contains", + "arguments": { + "data": { + "from_parameter": "data" + }, + "value": 5 + }, + "result": true + } +} \ No newline at end of file diff --git a/openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayFindProcessGraph.json b/openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayFindProcessGraph.json new file mode 100644 index 000000000..872565711 --- /dev/null +++ b/openeo-geotrellis/src/test/resources/org/openeo/geotrellis/testArrayFindProcessGraph.json @@ -0,0 +1,12 @@ +{ + "find": { + "process_id": "array_find", + "arguments": { + "data": { + "from_parameter": "data" + }, + "value": 5 + }, + "result": true + } +} \ No newline at end of file diff --git a/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala index 712165f45..4194f6885 100644 --- a/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala +++ b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/OpenEOProcessGraphBuilderTest.scala @@ -3,11 +3,14 @@ package org.openeo.geotrellis import org.apache.commons.io.IOUtils import org.junit.Test import com.fasterxml.jackson.databind.ObjectMapper -import geotrellis.raster.{ByteArrayTile, ByteConstantNoDataCellType, ShortArrayTile, Tile} -import org.junit.jupiter.api.Assertions.{assertEquals, assertNotNull} +import geotrellis.raster.{BitArrayTile, ByteArrayFiller, ByteArrayTile, ByteConstantNoDataArrayTile, ByteConstantNoDataCellType, ShortArrayTile, ShortConstantNoDataCellType, ShortConstantNoDataCellType$, Tile} +import org.junit.jupiter.api.Assertions.{assertArrayEquals, assertEquals, assertNotNull} +import java.net.URL import java.nio.charset.Charset import java.util +import java.util.Arrays +import scala.collection.JavaConverters import scala.collection.mutable.ArrayBuffer class OpenEOProcessGraphBuilderTest { @@ -69,11 +72,10 @@ class OpenEOProcessGraphBuilderTest { } def assertTileEquals(expected: Tile, actual: Tile):Unit = { - assertEquals(1,1) assertEquals(expected.cols, actual.cols) assertEquals(expected.rows, actual.rows) assertEquals(expected.cellType, actual.cellType) - assert(expected.toArray sameElements actual.toArray) + assertArrayEquals(expected.toArray, actual.toArray) } def fillShortArrayTile(cols: Int, rows: Int, values: Int *)= { @@ -105,31 +107,22 @@ class OpenEOProcessGraphBuilderTest { @Test def testArrayFind(): Unit = { - val graphPath = IOUtils.toString(getClass.getResource("/org/openeo/geotrellis/testArrayFindProcessGraph.json"), Charset.defaultCharset()) - val visitor = (new GeotrellisTileProcessGraphVisitor).create() - val graph = new ObjectMapper().readValue(graphPath,classOf[util.Map[String,Object]]) - println(graph) - visitor._acceptDict(graph) - // val processes = visitor.processes - // assert(processes.size==4) - // for (process <- processes) { - // print(process) - // } + val transformation = org.openeo.geotrellis.testutil.fromUrl(getClass.getResource("/org/openeo/geotrellis/testArrayFindProcessGraph.json")) + val tile0 = ByteArrayTile.fill(10.toByte, 4, 4) + val tile1 = ByteArrayTile.fill(5.toByte, 4, 4) + val result = transformation.apply(JavaConverters.asScalaBuffer(util.Arrays.asList(tile0, tile1))) + val expectedResult = ByteArrayTile.fill(1.toByte, 4, 4) + assertTileEquals(expectedResult.convert(ShortConstantNoDataCellType), result.head) } - @Test def testArrayContains(): Unit = { - val graphPath = IOUtils.toString(getClass.getResource("/org/openeo/geotrellis/testArrayContainsProcessGraph.json"), Charset.defaultCharset()) - val visitor = (new GeotrellisTileProcessGraphVisitor).create() - val graph = new ObjectMapper().readValue(graphPath,classOf[util.Map[String,Object]]) - println(graph) - visitor.acceptProcessGraph(graph) -// val processes = visitor.processes -// assert(processes.size==4) -// for (process <- processes) { -// print(process) -// } + val transformation = org.openeo.geotrellis.testutil.fromUrl(getClass.getResource("/org/openeo/geotrellis/testArrayContainsProcessGraph.json")) + val tile0 = ByteArrayTile.fill(10.toByte, 4, 4) + val tile1 = ByteArrayTile.fill(5.toByte, 4, 4) + val result = transformation.apply(JavaConverters.asScalaBuffer(util.Arrays.asList(tile0, tile1))) + val expectedResult = new BitArrayTile(Array.ofDim[Byte](((4 * 4) + 7) / 8).fill(255.toByte), 4, 4) // BitArrayTile.fill(1, 4, 4) seems bugged + assertTileEquals(expectedResult, result.head) } @@ -148,4 +141,4 @@ class OpenEOProcessGraphBuilderTest { assert(true) } -} +} \ No newline at end of file diff --git a/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/testutil/package.scala b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/testutil/package.scala new file mode 100644 index 000000000..e9270efcf --- /dev/null +++ b/openeo-geotrellis/src/test/scala/org/openeo/geotrellis/testutil/package.scala @@ -0,0 +1,26 @@ +package org.openeo.geotrellis + +import _root_.geotrellis.raster._ +import com.fasterxml.jackson.databind.ObjectMapper +import org.apache.commons.io.IOUtils + +import java.net.URL +import java.nio.charset.Charset +import java.util + + +package object testutil { + + def fromUrl(url: URL): Seq[Tile] => Seq[Tile] = { + val graphPath = IOUtils.toString(url, Charset.defaultCharset()) + fromString(graphPath) + } + + def fromString(graphPath: String): Seq[Tile] => Seq[Tile] = { + val visitor = (new GeotrellisTileProcessGraphVisitor).create() + val graph = new ObjectMapper().readValue(graphPath, classOf[util.Map[String, Object]]) + visitor.acceptProcessGraph(graph) + val transformation = visitor.builder.generateFunction() + transformation + } +}