+ * 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_AsBinary", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL) +public class STAsBinary implements SimpleFunction { + + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; + + @Output + org.apache.arrow.vector.holders.NullableVarBinaryHolder wkbOutput; + + @Inject + org.apache.arrow.memory.ArrowBuf buffer; + + 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); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + buffer = buffer.reallocIfNeeded(bytes.length); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, wkbOutput); + } else { + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(wkbOutput); + } + } +} diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STAsEWKB.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STAsEWKB.java new file mode 100644 index 0000000..cdb41f2 --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STAsEWKB.java @@ -0,0 +1,55 @@ +/** + * 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_AsEWKB", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL) +public class STAsEWKB implements SimpleFunction { + + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; + + @Output + org.apache.arrow.vector.holders.NullableVarBinaryHolder ewkbOutput; + + @Inject + org.apache.arrow.memory.ArrowBuf buffer; + + 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); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); + buffer = buffer.reallocIfNeeded(bytes.length); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, ewkbOutput); + } else { + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(ewkbOutput); + } + } +} diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STAzimuth.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STAzimuth.java index 8328a3d..437b7df 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STAzimuth.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STAzimuth.java @@ -25,21 +25,26 @@ @FunctionTemplate( name = "ST_Azimuth", scope = FunctionTemplate.FunctionScope.SIMPLE, - nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) + nulls = FunctionTemplate.NullHandling.INTERNAL) public class STAzimuth implements SimpleFunction { @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput1; @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput2; @Output - org.apache.arrow.vector.holders.Float8Holder output; + org.apache.arrow.vector.holders.NullableFloat8Holder output; public void setup() { } public void eval() { - org.locationtech.jts.geom.Point p1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toPoint(binaryInput1); - org.locationtech.jts.geom.Point p2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toPoint(binaryInput2); - output.value = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toAzimuthRadians(p1, p2); + if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.areHoldersSet(binaryInput1, binaryInput2)) { + org.locationtech.jts.geom.Point p1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toPoint(binaryInput1); + org.locationtech.jts.geom.Point p2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toPoint(binaryInput2); + double radians = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toAzimuthRadians(p1, p2); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setDoubleValue(output, radians); + } else { + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(output); + } } } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STBuffer.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STBuffer.java index ef88db9..c8a1374 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STBuffer.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STBuffer.java @@ -23,14 +23,13 @@ import com.dremio.exec.expr.annotations.Param; import org.apache.arrow.memory.ArrowBuf; - - import javax.inject.Inject; @FunctionTemplate( name = "ST_Buffer", scope = FunctionTemplate.FunctionScope.SIMPLE, - nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) + nulls = FunctionTemplate.NullHandling.INTERNAL, + costCategory = FunctionTemplate.FunctionCostCategory.MEDIUM) public class STBuffer implements SimpleFunction { @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; @@ -48,10 +47,14 @@ public void setup() { } public void eval() { - org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); - org.locationtech.jts.geom.Geometry buffered = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.buffer(geom, radiusInput.value, null); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(buffered); - buffer = buffer.reallocIfNeeded(bytes.length); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); + 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); + org.locationtech.jts.geom.Geometry buffered = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.buffer(geom, radiusInput.value, null); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(buffered); + 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); + } } } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STBufferParameters.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STBufferParameters.java index 337e175..07682a5 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STBufferParameters.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STBufferParameters.java @@ -28,7 +28,8 @@ @FunctionTemplate( name = "ST_Buffer", scope = FunctionTemplate.FunctionScope.SIMPLE, - nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) + nulls = FunctionTemplate.NullHandling.INTERNAL, + costCategory = FunctionTemplate.FunctionCostCategory.MEDIUM) public class STBufferParameters implements SimpleFunction { @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; @@ -49,11 +50,15 @@ public void setup() { } public void eval() { - org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); - java.lang.String parameters = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toUTF8String(parametersInput); - org.locationtech.jts.geom.Geometry buffered = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.buffer(geom, radiusInput.value, parameters); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(buffered); - buffer = buffer.reallocIfNeeded(bytes.length); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); + 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); + java.lang.String parameters = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toUTF8String(parametersInput); + org.locationtech.jts.geom.Geometry buffered = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.buffer(geom, radiusInput.value, parameters); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(buffered); + 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); + } } } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STCentroid.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STCentroid.java index 9988781..9f18376 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STCentroid.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STCentroid.java @@ -48,7 +48,7 @@ public void eval() { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); org.locationtech.jts.algorithm.Centroid centroid = new org.locationtech.jts.algorithm.Centroid(geom); org.locationtech.jts.geom.Point point = factory.createPoint(centroid.getCentroid()); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(point); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(point); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STCollect.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STCollect.java index 2793a69..403e0ff 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STCollect.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STCollect.java @@ -49,7 +49,7 @@ public void eval() { org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1); org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2); org.locationtech.jts.geom.GeometryCollection collection = org.sheinbergon.dremio.udf.gis.util.GeometryCollections.collect(geom1, geom2); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(collection); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(collection); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STCollectAggregate.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STCollectAggregate.java index bca4566..e0d044e 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STCollectAggregate.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STCollectAggregate.java @@ -52,30 +52,30 @@ public void setup() { value = new org.apache.arrow.vector.holders.NullableVarBinaryHolder(); indicator = new org.apache.arrow.vector.holders.NullableBitHolder(); org.locationtech.jts.geom.GeometryCollection collection = org.sheinbergon.dremio.udf.gis.util.GeometryCollections.empty(); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(collection); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(collection); valueBuffer = valueBuffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, valueBuffer, value); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(value); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValueFalse(indicator); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(indicator, false); } @Override public void add() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(input)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(input); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); final int required = value.end + bytes.length + Integer.BYTES; valueBuffer = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.enlargeBufferIfNeeded(valueBuffer, required); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.append(bytes, valueBuffer, value); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValueTrue(indicator); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(indicator, true); } } @Override public void output() { - if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isValueTrue(indicator)) { + if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.getBooleanValue(indicator)) { org.locationtech.jts.geom.GeometryCollection collection = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometryCollection(value); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(collection); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(collection); outputBuffer = outputBuffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, outputBuffer, output); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(output); @@ -87,10 +87,10 @@ public void output() { @Override public void reset() { org.locationtech.jts.geom.GeometryCollection collection = org.sheinbergon.dremio.udf.gis.util.GeometryCollections.empty(); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(collection); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(collection); valueBuffer = valueBuffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, valueBuffer, value); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(value); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValueFalse(indicator); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(indicator, false); } } \ No newline at end of file diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STConcaveHull.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STConcaveHull.java new file mode 100644 index 0000000..32ee70a --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STConcaveHull.java @@ -0,0 +1,64 @@ +/** + * 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_ConcaveHull", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL) +public class STConcaveHull implements SimpleFunction { + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; + + @Param(constant = true) + org.apache.arrow.vector.holders.Float8Holder percentageConvexInput; + + @Param(constant = true) + org.apache.arrow.vector.holders.BitHolder allowHolesInput; + + @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)) { + org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); + org.locationtech.jts.algorithm.hull.ConcaveHull concaveHull = new org.locationtech.jts.algorithm.hull.ConcaveHull(geom); + concaveHull.setHolesAllowed(org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.getBooleanValue(allowHolesInput)); + concaveHull.setMaximumEdgeLengthRatio(percentageConvexInput.value); + org.locationtech.jts.geom.Geometry hull = concaveHull.getHull(); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(hull); + 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); + } + } +} diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STConcaveHullNoHolesAllowed.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STConcaveHullNoHolesAllowed.java new file mode 100644 index 0000000..8ca5075 --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STConcaveHullNoHolesAllowed.java @@ -0,0 +1,60 @@ +/** + * 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_ConcaveHull", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL) +public class STConcaveHullNoHolesAllowed implements SimpleFunction { + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; + + @Param(constant = true) + org.apache.arrow.vector.holders.Float8Holder percentageConvexInput; + + @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)) { + org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); + org.locationtech.jts.algorithm.hull.ConcaveHull concaveHull = new org.locationtech.jts.algorithm.hull.ConcaveHull(geom); + concaveHull.setMaximumEdgeLengthRatio(percentageConvexInput.value); + org.locationtech.jts.geom.Geometry hull = concaveHull.getHull(); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(hull); + 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); + } + } +} diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STConvexHull.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STConvexHull.java index 2295538..d1775d6 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STConvexHull.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STConvexHull.java @@ -46,7 +46,7 @@ public void eval() { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); org.locationtech.jts.algorithm.ConvexHull convexHull = new org.locationtech.jts.algorithm.ConvexHull(geom); org.locationtech.jts.geom.Geometry hull = convexHull.getConvexHull(); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(hull); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(hull); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STDifference.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STDifference.java index 537f8ff..39c1748 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STDifference.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STDifference.java @@ -50,7 +50,7 @@ public void eval() { org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1); org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2); org.locationtech.jts.geom.Geometry difference = geom1.difference(geom2); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(difference); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(difference); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STDistance.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STDistance.java index 03dd93f..98cb6e2 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STDistance.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STDistance.java @@ -25,7 +25,7 @@ @FunctionTemplate( name = "ST_Distance", scope = FunctionTemplate.FunctionScope.SIMPLE, - nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) + nulls = FunctionTemplate.NullHandling.INTERNAL) public class STDistance implements SimpleFunction { @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput1; @@ -34,14 +34,19 @@ public class STDistance implements SimpleFunction { org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput2; @Output - org.apache.arrow.vector.holders.Float8Holder output; + org.apache.arrow.vector.holders.NullableFloat8Holder output; public void setup() { } public void eval() { - org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1); - org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2); - output.value = geom1.distance(geom2); + if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.areHoldersSet(binaryInput1, binaryInput2)) { + org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1); + org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2); + double radians = geom1.distance(geom2); + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setDoubleValue(output, radians); + } else { + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(output); + } } } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STEnvelope.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STEnvelope.java index 546f926..e466c2c 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STEnvelope.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STEnvelope.java @@ -45,7 +45,7 @@ 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); org.locationtech.jts.geom.Geometry envelope = geom.getEnvelope(); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(envelope); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(envelope); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKB.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKB.java new file mode 100644 index 0000000..8f3b1a3 --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKB.java @@ -0,0 +1,55 @@ +/** + * 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_GeomFromEWKB", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL) +public class STGeomFromEWKB implements SimpleFunction { + + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder ewkbInput; + + @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(ewkbInput)) { + org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(ewkbInput); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); + 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/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKT.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKT.java index 21923fa..5e9345d 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKT.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromEWKT.java @@ -45,7 +45,7 @@ public void setup() { public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(ewktInput)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometryFromEWKT(ewktInput); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromText.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromText.java index 0e1c006..53a9702 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromText.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromText.java @@ -45,7 +45,7 @@ public void setup() { public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(wktInput)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(wktInput); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromTextSrid.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromTextSrid.java index 4bf1f4d..7da5ad0 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromTextSrid.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromTextSrid.java @@ -49,7 +49,7 @@ public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(wktInput)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(wktInput); geom.setSRID(sridInput.value); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKB.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKB.java index 8a9426c..e88b22e 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKB.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKB.java @@ -45,7 +45,7 @@ public void setup() { public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(wkbInput)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(wkbInput); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKBSrid.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKBSrid.java index 6089249..a758c08 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKBSrid.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeomFromWKBSrid.java @@ -49,7 +49,7 @@ public void eval() { if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isHolderSet(wkbInput)) { org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(wkbInput); geom.setSRID(sridInput.value); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(geom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(geom); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeometryN.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeometryN.java index 3351396..436bd94 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STGeometryN.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STGeometryN.java @@ -51,7 +51,7 @@ public void eval() { if (0 <= index && index < size) { org.locationtech.jts.geom.Geometry nthGeom = geom.getGeometryN(index); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(binaryOutput); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(nthGeom); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(nthGeom); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } else { diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STIntersection.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STIntersection.java index c517d16..438e589 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STIntersection.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STIntersection.java @@ -49,7 +49,7 @@ public void eval() { org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1); org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2); org.locationtech.jts.geom.Geometry intersection = geom1.intersection(geom2); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(intersection); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(intersection); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput); } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STIsClosed.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsClosed.java index d281e79..b7b110b 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STIsClosed.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsClosed.java @@ -40,7 +40,7 @@ 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 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isClosed(geom); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValue(output, result); + 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/STIsCollection.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsCollection.java index 53faf53..ca3379c 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STIsCollection.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsCollection.java @@ -40,7 +40,7 @@ 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 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isACollection(geom); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValue(output, result); + 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/STIsEmpty.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsEmpty.java index a14c7d1..02c6cdb 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STIsEmpty.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsEmpty.java @@ -40,7 +40,7 @@ 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.isEmpty(); - org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValue(output, result); + 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/STIsSimple.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsSimple.java new file mode 100644 index 0000000..34b6c71 --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STIsSimple.java @@ -0,0 +1,48 @@ +/** + * 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; + +@FunctionTemplate( + name = "ST_IsSimple", + scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.INTERNAL) +public class STIsSimple implements SimpleFunction { + @Param + org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; + + @Output + org.apache.arrow.vector.holders.NullableBitHolder output; + + 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(); + 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/STLength.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STLength.java index ca54d18..59d4b71 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STLength.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STLength.java @@ -25,23 +25,27 @@ @FunctionTemplate( name = "ST_Length", scope = FunctionTemplate.FunctionScope.SIMPLE, - nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) + nulls = FunctionTemplate.NullHandling.INTERNAL, + costCategory = FunctionTemplate.FunctionCostCategory.MEDIUM) public class STLength implements SimpleFunction { @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; @Output - org.apache.arrow.vector.holders.Float8Holder output; + org.apache.arrow.vector.holders.NullableFloat8Holder output; public void setup() { } public void eval() { - org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); - if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isLinear(geom)) { - output.value = geom.getLength(); + 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); + double length = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isLinear(geom) + ? geom.getLength() + : 0.0; + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setDoubleValue(output, length); } else { - output.value = 0.0; + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(output); } } } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STPerimeter.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STPerimeter.java index d4d1992..5d1b726 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STPerimeter.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STPerimeter.java @@ -25,23 +25,25 @@ @FunctionTemplate( name = "ST_Perimeter", scope = FunctionTemplate.FunctionScope.SIMPLE, - nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) + nulls = FunctionTemplate.NullHandling.INTERNAL, + costCategory = FunctionTemplate.FunctionCostCategory.MEDIUM) public class STPerimeter implements SimpleFunction { @Param org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput; @Output - org.apache.arrow.vector.holders.Float8Holder output; + org.apache.arrow.vector.holders.NullableFloat8Holder output; public void setup() { } public void eval() { - org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput); - if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isAreal(geom)) { - output.value = geom.getLength(); + 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); + double perimeter = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isAreal(geom) ? geom.getLength() : 0.0; + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setDoubleValue(output, perimeter); } else { - output.value = 0.0; + org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderNotSet(output); } } } diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STPoint.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STPointSrid.java similarity index 97% rename from src/main/java/org/sheinbergon/dremio/udf/gis/STPoint.java rename to src/main/java/org/sheinbergon/dremio/udf/gis/STPointSrid.java index b674de5..647ed68 100644 --- a/src/main/java/org/sheinbergon/dremio/udf/gis/STPoint.java +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STPointSrid.java @@ -31,7 +31,7 @@ name = "ST_Point", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STPoint implements SimpleFunction { +public class STPointSrid implements SimpleFunction { @Param org.apache.arrow.vector.holders.Float8Holder longitudeInput; @@ -58,7 +58,7 @@ public void eval() { org.locationtech.jts.geom.PrecisionModel precisionModel = new org.locationtech.jts.geom.PrecisionModel(); org.locationtech.jts.geom.GeometryFactory factory = new org.locationtech.jts.geom.GeometryFactory(precisionModel, srid()); org.locationtech.jts.geom.Point point = factory.createPoint(coordinate); - byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(point); + byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(point); buffer = buffer.reallocIfNeeded(bytes.length); org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, 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 new file mode 100644 index 0000000..63700f5 --- /dev/null +++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STSimplify.java @@ -0,0 +1,60 @@ +/** + * 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 org.apache.arrow.memory.ArrowBuf;
+
+import javax.inject.Inject;
+
+@FunctionTemplate(
+ name = "ST_Simplify",
+ scope = FunctionTemplate.FunctionScope.SIMPLE,
+ nulls = FunctionTemplate.NullHandling.INTERNAL,
+ costCategory = FunctionTemplate.FunctionCostCategory.COMPLEX)
+public class STSimplify implements SimpleFunction {
+ @Param
+ org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryInput;
+
+ @Param(constant = true)
+ org.apache.arrow.vector.holders.Float8Holder toleranceInput;
+
+ @Output
+ org.apache.arrow.vector.holders.NullableVarBinaryHolder binaryOutput;
+
+ @Inject
+ ArrowBuf buffer;
+
+ 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);
+ org.locationtech.jts.geom.Geometry simplified = org.locationtech.jts.simplify.DouglasPeuckerSimplifier.simplify(geom, toleranceInput.value);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(simplified);
+ 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);
+ }
+ }
+}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STSymDifference.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STSymDifference.java
index b6005ec..0d2a6a8 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/STSymDifference.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STSymDifference.java
@@ -48,7 +48,7 @@ public void eval() {
org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1);
org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2);
org.locationtech.jts.geom.Geometry difference = geom1.symDifference(geom2);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(difference);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(difference);
buffer = buffer.reallocIfNeeded(bytes.length);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput);
}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformFromProj4ToSrid.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformFromProj4ToSrid.java
index b6ff5de..41ca963 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformFromProj4ToSrid.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformFromProj4ToSrid.java
@@ -27,7 +27,8 @@
@FunctionTemplate(
name = "ST_Transform",
scope = FunctionTemplate.FunctionScope.SIMPLE,
- nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
+ nulls = FunctionTemplate.NullHandling.NULL_IF_NULL,
+ costCategory = FunctionTemplate.FunctionCostCategory.COMPLEX)
public class STTransformFromProj4ToSrid implements SimpleFunction {
@Param
@@ -54,7 +55,7 @@ public void eval() {
String source = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toUTF8String(sourceProj4ParametersInput);
org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput);
org.locationtech.jts.geom.Geometry result = org.sheinbergon.dremio.udf.gis.util.GeometryTransformation.transform(geom, source, target);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(result);
+ 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);
}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToProj4.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToProj4.java
index 1633264..2579b76 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToProj4.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToProj4.java
@@ -27,7 +27,8 @@
@FunctionTemplate(
name = "ST_Transform",
scope = FunctionTemplate.FunctionScope.SIMPLE,
- nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
+ nulls = FunctionTemplate.NullHandling.NULL_IF_NULL,
+ costCategory = FunctionTemplate.FunctionCostCategory.COMPLEX)
public class STTransformToProj4 implements SimpleFunction {
@Param
@@ -50,7 +51,7 @@ public void eval() {
java.lang.String target = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toUTF8String(targetProj4ParametersInput);
org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput);
org.locationtech.jts.geom.Geometry result = org.sheinbergon.dremio.udf.gis.util.GeometryTransformation.transform(geom, target);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(result);
+ 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);
}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToSrid.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToSrid.java
index 64219bf..7612d57 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToSrid.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STTransformToSrid.java
@@ -27,7 +27,8 @@
@FunctionTemplate(
name = "ST_Transform",
scope = FunctionTemplate.FunctionScope.SIMPLE,
- nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
+ nulls = FunctionTemplate.NullHandling.NULL_IF_NULL,
+ costCategory = FunctionTemplate.FunctionCostCategory.COMPLEX)
public class STTransformToSrid implements SimpleFunction {
@Param
@@ -50,7 +51,7 @@ public void eval() {
int target = targetSridInput.value;
org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput);
org.locationtech.jts.geom.Geometry result = org.sheinbergon.dremio.udf.gis.util.GeometryTransformation.transform(geom, target);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(result);
+ 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);
}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STUnion.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STUnion.java
index d09b318..8b70ab3 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/STUnion.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STUnion.java
@@ -50,7 +50,7 @@ public void eval() {
org.locationtech.jts.geom.Geometry geom1 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput1);
org.locationtech.jts.geom.Geometry geom2 = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(binaryInput2);
org.locationtech.jts.geom.Geometry union = geom1.union(geom2);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(union);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(union);
buffer = buffer.reallocIfNeeded(bytes.length);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, buffer, binaryOutput);
}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/STUnionAggregate.java b/src/main/java/org/sheinbergon/dremio/udf/gis/STUnionAggregate.java
index f498cf9..1f034e3 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/STUnionAggregate.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/STUnionAggregate.java
@@ -52,11 +52,11 @@ public void setup() {
value = new org.apache.arrow.vector.holders.NullableVarBinaryHolder();
indicator = new org.apache.arrow.vector.holders.NullableBitHolder();
org.locationtech.jts.geom.Geometry empty = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.emptyGeometry();
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(empty);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(empty);
valueBuffer = valueBuffer.reallocIfNeeded(bytes.length);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, valueBuffer, value);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(value);
- org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValueFalse(indicator);
+ org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(indicator, false);
}
@Override
@@ -65,18 +65,18 @@ public void add() {
org.locationtech.jts.geom.Geometry geom = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(input);
org.locationtech.jts.geom.Geometry accumulated = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(value);
org.locationtech.jts.geom.Geometry union = accumulated.union(geom);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(union);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(union);
valueBuffer = valueBuffer.reallocIfNeeded(bytes.length);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, valueBuffer, value);
- org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValueTrue(indicator);
+ org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(indicator, true);
}
}
@Override
public void output() {
- if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.isValueTrue(indicator)) {
+ if (org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.getBooleanValue(indicator)) {
org.locationtech.jts.geom.Geometry union = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toGeometry(value);
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(union);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(union);
outputBuffer = outputBuffer.reallocIfNeeded(bytes.length);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, outputBuffer, output);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(output);
@@ -88,10 +88,10 @@ public void output() {
@Override
public void reset() {
org.locationtech.jts.geom.Geometry empty = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.emptyGeometry();
- byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toBinary(empty);
+ byte[] bytes = org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.toEWKB(empty);
valueBuffer = valueBuffer.reallocIfNeeded(bytes.length);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.populate(bytes, valueBuffer, value);
org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.markHolderSet(value);
- org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setValueFalse(indicator);
+ org.sheinbergon.dremio.udf.gis.util.GeometryHelpers.setBooleanValue(indicator, false);
}
}
\ No newline at end of file
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryHelpers.java b/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryHelpers.java
index 7766149..44de0ef 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryHelpers.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryHelpers.java
@@ -35,6 +35,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Set;
@@ -52,7 +53,6 @@ public final class GeometryHelpers {
private static final int GEOMETRY_DIMENSIONS = 2;
private static final double AZIMUTH_NORTH_RADIANS = Angle.toRadians(90.0);
- private static final String EWKT_TEMPLATE = "SRID=%d;%s";
private static final Pattern EWKT_REGEX_PATTERN = Pattern.compile("^\\s*SRID\\s*=\\s*(\\d+)\\s*;\\s*(.+)\\s*$");
private GeometryHelpers() {
@@ -77,11 +77,24 @@ public static String toUTF8String(final @Nonnull NullableVarCharHolder holder) {
holder.buffer);
}
+ public static byte[] toEWKB(final @Nonnull Geometry geometry) {
+ int order = nativeWkbByteOrder();
+ WKBWriter writer = new WKBWriter(GEOMETRY_DIMENSIONS, order, true);
+ return writer.write(geometry);
+ }
+
public static byte[] toBinary(final @Nonnull Geometry geometry) {
- WKBWriter writer = new WKBWriter(GEOMETRY_DIMENSIONS, true);
+ int order = nativeWkbByteOrder();
+ WKBWriter writer = new WKBWriter(GEOMETRY_DIMENSIONS, order, false);
return writer.write(geometry);
}
+ private static int nativeWkbByteOrder() {
+ return ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
+ ? ByteOrderValues.BIG_ENDIAN
+ : ByteOrderValues.LITTLE_ENDIAN;
+ }
+
public static byte[] toText(
final @Nonnull Geometry geometry) {
WKTWriter writer = new WKTWriter(GEOMETRY_DIMENSIONS);
@@ -92,7 +105,13 @@ public static byte[] toEWKT(
final @Nonnull Geometry geometry) {
final WKTWriter writer = new WKTWriter(GEOMETRY_DIMENSIONS);
final String wkt = writer.write(geometry);
- return String.format(EWKT_TEMPLATE, geometry.getSRID(), wkt).getBytes(StandardCharsets.UTF_8);
+ String result;
+ if (geometry.getSRID() > 0) {
+ result = String.format("SRID=%d;%s", geometry.getSRID(), wkt);
+ } else {
+ result = wkt;
+ }
+ return result.getBytes(StandardCharsets.UTF_8);
}
public static byte[] toGeoJson(final @Nonnull Geometry geometry) {
@@ -275,6 +294,17 @@ public static boolean isLinear(
return geometry != null && LINEAR_TYPES.contains(geometry.getGeometryType());
}
+ public static boolean areHoldersSet(final @Nonnull ValueHolder... holders) {
+ boolean result = false;
+ for (ValueHolder holder : holders) {
+ result = isHolderSet(holder);
+ if (!result) {
+ break;
+ }
+ }
+ return result;
+ }
+
public static boolean isHolderSet(final @Nonnull ValueHolder holder) {
if (holder instanceof NullableIntHolder) {
return ((NullableIntHolder) holder).isSet == BIT_TRUE;
@@ -314,6 +344,8 @@ public static void markHolderNotSet(final @Nonnull ValueHolder holder) {
((NullableVarCharHolder) holder).isSet = BIT_FALSE;
} else if (holder instanceof NullableVarBinaryHolder) {
((NullableVarBinaryHolder) holder).isSet = BIT_FALSE;
+ } else if (holder instanceof NullableFloat8Holder) {
+ ((NullableFloat8Holder) holder).isSet = BIT_FALSE;
} else {
throw new IllegalArgumentException(
String.format("Unsupported value holder type - %s",
@@ -321,7 +353,7 @@ public static void markHolderNotSet(final @Nonnull ValueHolder holder) {
}
}
- public static boolean isValueTrue(final @Nonnull ValueHolder holder) {
+ public static boolean getBooleanValue(final @Nonnull ValueHolder holder) {
if (holder instanceof BitHolder) {
return ((BitHolder) holder).value == BIT_TRUE;
} else if (holder instanceof NullableBitHolder) {
@@ -338,24 +370,7 @@ public static boolean isValueTrue(final @Nonnull ValueHolder holder) {
}
}
- public static boolean isValueFalse(final @Nonnull ValueHolder holder) {
- if (holder instanceof BitHolder) {
- return ((BitHolder) holder).value == BIT_FALSE;
- } else if (holder instanceof NullableBitHolder) {
- NullableBitHolder nullable = (NullableBitHolder) holder;
- if (nullable.isSet == BIT_TRUE) {
- return ((NullableBitHolder) holder).value == BIT_FALSE;
- } else {
- throw new IllegalStateException("Cannot verify state of a not-set nullable bit holder");
- }
- } else {
- throw new IllegalArgumentException(
- String.format("Unsupported value holder type - %s",
- holder.getClass().getName()));
- }
- }
-
- public static void setValue(final @Nonnull ValueHolder holder, final boolean value) {
+ public static void setBooleanValue(final @Nonnull ValueHolder holder, final boolean value) {
int bitValue = value ? BIT_TRUE : BIT_FALSE;
if (holder instanceof BitHolder) {
((BitHolder) holder).value = bitValue;
@@ -370,26 +385,12 @@ public static void setValue(final @Nonnull ValueHolder holder, final boolean val
}
}
- public static void setValueFalse(final @Nonnull ValueHolder holder) {
- if (holder instanceof BitHolder) {
- ((BitHolder) holder).value = BIT_FALSE;
- } else if (holder instanceof NullableBitHolder) {
- NullableBitHolder nullable = (NullableBitHolder) holder;
- nullable.value = BIT_FALSE;
- nullable.isSet = BIT_TRUE;
- } else {
- throw new IllegalArgumentException(
- String.format("Unsupported value holder type - %s",
- holder.getClass().getName()));
- }
- }
-
- public static void setValueTrue(final @Nonnull ValueHolder holder) {
- if (holder instanceof BitHolder) {
- ((BitHolder) holder).value = BIT_TRUE;
- } else if (holder instanceof NullableBitHolder) {
- NullableBitHolder nullable = (NullableBitHolder) holder;
- nullable.value = BIT_TRUE;
+ public static void setDoubleValue(final @Nonnull ValueHolder holder, final double value) {
+ if (holder instanceof Float8Holder) {
+ ((Float8Holder) holder).value = value;
+ } else if (holder instanceof NullableFloat8Holder) {
+ NullableFloat8Holder nullable = (NullableFloat8Holder) holder;
+ nullable.value = value;
nullable.isSet = BIT_TRUE;
} else {
throw new IllegalArgumentException(
diff --git a/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STAngle2LinesTests.kt b/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STAngle2LinesTests.kt
index 5ae0a60..c4b5629 100644
--- a/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STAngle2LinesTests.kt
+++ b/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STAngle2LinesTests.kt
@@ -1,6 +1,6 @@
package org.sheinbergon.dremio.udf.gis
-import org.apache.arrow.vector.holders.Float8Holder
+import org.apache.arrow.vector.holders.NullableFloat8Holder
import org.apache.arrow.vector.holders.NullableVarBinaryHolder
import org.sheinbergon.dremio.udf.gis.spec.GeometryMeasurementFunSpec
@@ -13,15 +13,22 @@ internal class STAngle2LinesTests : GeometryMeasurementFunSpec.Binary