diff --git a/pom.xml b/pom.xml index 9f4c81d..cbc27cf 100644 --- a/pom.xml +++ b/pom.xml @@ -15,14 +15,14 @@ 4.13.2 5.10.1 1.10.1 - 1.9.21 + 1.9.24 5.7.2 2.9 - 1.23.4 + 1.23.5 0.7.0 12.0.1 - 0.12.0-SNAPSHOT + 0.12.2-SNAPSHOT dremio-udf-gis GIS UDF extensions for Dremio https://github.com/sheinbergon/dremio-udf-gis diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STIsSimple.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsSimple.java index 34b6c71..678907b 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STIsSimple.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsSimple.java @@ -39,7 +39,7 @@ public void setup() { public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(binaryInput)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); - boolean result = geom.isSimple(); + boolean result = org.locationtech.jts.operation.valid.IsSimpleOp.isSimple(geom); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(output, result); } else { org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(output); diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplify.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplify.java index 6a85a03..b05af9b 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplify.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplify.java @@ -21,7 +21,6 @@ import com.dremio.exec.expr.annotations.FunctionTemplate; import com.dremio.exec.expr.annotations.Output; import com.dremio.exec.expr.annotations.Param; -import org.apache.arrow.memory.ArrowBuf; import javax.inject.Inject; @@ -31,25 +30,29 @@ nulls = FunctionTemplate.NullHandling.INTERNAL, costCategory = FunctionTemplate.FunctionCostCategory.COMPLEX) public class STSimplify implements SimpleFunction { + @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; - @Param(constant = true) + @Param org.apache.arrow.vector.holders.Float8Holder toleranceInput; @Output org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryOutput; @Inject - ArrowBuf buffer; + org.apache.arrow.memory.ArrowBuf buffer; public void setup() { } public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(binaryInput)) { + double tolerance = toleranceInput.value; org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); - org.locationtech.jts.geom.Geometry simplified = org.locationtech.jts.simplify.DouglasPeuckerSimplifier.simplify(geom, toleranceInput.value); + org.locationtech.jts.simplify.DouglasPeuckerSimplifier simplifier = new org.locationtech.jts.simplify.DouglasPeuckerSimplifier(geom); + simplifier.setDistanceTolerance(tolerance); + org.locationtech.jts.geom.Geometry simplified = simplifier.getResultGeometry(); simplified.setSRID(geom.getSRID()); byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(simplified); buffer = buffer.reallocIfNeeded(bytes.length); @@ -58,4 +61,4 @@ public void eval() { org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(binaryOutput); } } -} +} \ No newline at end of file diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplifyPreserveTopology.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplifyPreserveTopology.java new file mode 100644 index 0000000..3730cb1 --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplifyPreserveTopology.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sheinbergon.dremio.udf.gis; + +import com.dremio.exec.expr.SimpleFunction; +import com.dremio.exec.expr.annotations.FunctionTemplate; +import com.dremio.exec.expr.annotations.Output; +import com.dremio.exec.expr.annotations.Param; + +import javax.inject.Inject; + +@FunctionTemplate( + name = "ST_SimplifyPreserveTopology", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL, + costCategory = FunctionTemplate.FunctionCostCategory.COMPLEX) +public class STSimplifyPreserveTopology implements SimpleFunction { + + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; + + @Param + org.apache.arrow.vector.holders.Float8Holder toleranceInput; + + @Output + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryOutput; + + @Inject + org.apache.arrow.memory.ArrowBuf buffer; + + public void setup() { + } + + public void eval() { + if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(binaryInput)) { + double tolerance = toleranceInput.value; + org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); + org.locationtech.jts.simplify.TopologyPreservingSimplifier simplifier = new org.locationtech.jts.simplify.TopologyPreservingSimplifier(geom); + simplifier.setDistanceTolerance(tolerance); + org.locationtech.jts.geom.Geometry result = simplifier.getResultGeometry(); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(result); + buffer = buffer.reallocIfNeeded(bytes.length); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); + } else { + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(binaryOutput); + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STSimplifyPreserveTopologyTests.kt b/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STSimplifyPreserveTopologyTests.kt new file mode 100644 index 0000000..b2675d1 --- /dev/null +++ b/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STSimplifyPreserveTopologyTests.kt @@ -0,0 +1,51 @@ +package org.sheinbergon.dremio.udf.gis + +import org.apache.arrow.vector.holders.Float8Holder +import org.apache.arrow.vector.holders.NullableVarBinaryHolder +import org.sheinbergon.dremio.udf.gis.spec.GeometryProcessingFunSpec +import org.sheinbergon.dremio.udf.gis.util.allocateBuffer +import org.sheinbergon.dremio.udf.gis.util.reset + +internal class STSimplifyPreserveTopologyTests : GeometryProcessingFunSpec() { + + init { + + beforeEach { + function.toleranceInput.reset() + } + + testGeometryProcessing( + name = "Calling ST_SimplifyPreserveTopology on a MULTILINESTRING with a tolerance of 40.0", + wkt = """ + MULTILINESTRING ( + (20 180, 20 150, 50 150, 50 100, 110 150, 150 140, 170 120), + (20 10, 80 30, 90 120), + (90 120, 130 130), + (130 130, 130 70, 160 40, 180 60, 180 90, 140 80), + (50 40, 70 40, 80 70, 70 60, 60 60, 50 50, 50 40) + )""".trimIndent(), + expected = """ + MULTILINESTRING( + (20 180,50 100,110 150,170 120), + (20 10,90 120), + (90 120,130 130), + (130 130,130 70,160 40,180 90,140 80), + (50 40,70 40,80 70,60 60,50 40) + )""".trimIndent() + ) { function.toleranceInput.value = 40.0 } + + testNullGeometryProcessing( + "Calling ST_SimplifyPreserveTopology on a NULL input" + ) + } + + override val function = STSimplifyPreserveTopology().apply { + binaryInput = NullableVarBinaryHolder() + toleranceInput = Float8Holder() + binaryOutput = NullableVarBinaryHolder() + buffer = allocateBuffer() + } + + override val STSimplifyPreserveTopology.wkbInput: NullableVarBinaryHolder get() = function.binaryInput + override val STSimplifyPreserveTopology.wkbOutput: NullableVarBinaryHolder get() = function.binaryOutput +}