This is an automated email from the ASF dual-hosted git repository. parthc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/drill.git
commit eded745d4647a15716fa570a69b660385d0f0ee7 Author: potocki <[email protected]> AuthorDate: Mon Nov 16 14:05:18 2015 +0100 DRILL-4091: Adding support for additional gis operations in gis contrib module This closes #1201 --- contrib/gis/pom.xml | 6 +- contrib/gis/sample-data/CA-cities-with-nulls.csv | 3 + contrib/gis/sample-data/polygons.tsv | 5 + .../com/esri/core/geometry/VertexGeomAccessor.java | 25 +++ .../gis/{STGeomFromTextSrid.java => STBuffer.java} | 33 +-- .../gis/{STGeomFromText.java => STContains.java} | 36 ++-- .../gis/{STGeomFromText.java => STCrosses.java} | 35 ++-- .../{STGeomFromTextSrid.java => STDifference.java} | 36 ++-- .../gis/{STGeomFromText.java => STDisjoint.java} | 35 ++-- .../gis/{STGeomFromText.java => STDistance.java} | 36 ++-- .../{STGeomFromTextSrid.java => STEnvelope.java} | 39 ++-- .../gis/{STGeomFromText.java => STEquals.java} | 35 ++-- .../exec/expr/fn/impl/gis/STGeomFromText.java | 4 +- .../exec/expr/fn/impl/gis/STGeomFromTextSrid.java | 2 +- .../gis/{STGeomFromText.java => STIntersects.java} | 36 ++-- .../gis/{STGeomFromText.java => STOverlaps.java} | 35 ++-- .../drill/exec/expr/fn/impl/gis/STRelate.java | 73 +++++++ .../gis/{STGeomFromText.java => STTouches.java} | 35 ++-- .../drill/exec/expr/fn/impl/gis/STTransform.java | 114 +++++++++++ .../gis/{STGeomFromTextSrid.java => STUnion.java} | 35 ++-- .../exec/expr/fn/impl/gis/STUnionAggregate.java | 115 +++++++++++ .../impl/gis/{STGeomFromText.java => STXFunc.java} | 30 +-- .../impl/gis/{STGeomFromText.java => STXMax.java} | 39 ++-- .../impl/gis/{STGeomFromText.java => STXMin.java} | 39 ++-- .../impl/gis/{STGeomFromText.java => STYFunc.java} | 30 +-- .../impl/gis/{STGeomFromText.java => STYMax.java} | 39 ++-- .../impl/gis/{STGeomFromText.java => STYMin.java} | 39 ++-- .../expr/fn/impl/gis/TestGeometryFunctions.java | 228 ++++++++++++++++++++- 28 files changed, 903 insertions(+), 314 deletions(-) diff --git a/contrib/gis/pom.xml b/contrib/gis/pom.xml index 30a0924..96f694a 100644 --- a/contrib/gis/pom.xml +++ b/contrib/gis/pom.xml @@ -45,7 +45,11 @@ <artifactId>esri-geometry-api</artifactId> <version>2.0.0</version> </dependency> - + <dependency> + <groupId>org.osgeo</groupId> + <artifactId>proj4j</artifactId> + <version>0.1.0</version> + </dependency> <!-- Test dependencies --> <dependency> <groupId>org.apache.drill.exec</groupId> diff --git a/contrib/gis/sample-data/CA-cities-with-nulls.csv b/contrib/gis/sample-data/CA-cities-with-nulls.csv new file mode 100644 index 0000000..dcd67ec --- /dev/null +++ b/contrib/gis/sample-data/CA-cities-with-nulls.csv @@ -0,0 +1,3 @@ +US,6,"Acampo", +US,6,"Agnew",POINT(-121.9591252 37.3946626) +US,6,"Agua Caliente",POINT(-122.4880366 38.3240804) \ No newline at end of file diff --git a/contrib/gis/sample-data/polygons.tsv b/contrib/gis/sample-data/polygons.tsv new file mode 100644 index 0000000..f70c922 --- /dev/null +++ b/contrib/gis/sample-data/polygons.tsv @@ -0,0 +1,5 @@ +1 POLYGON((0 0, 0 1, 1 1, 1 0, 0 0)) +1 POLYGON((0 0, 0 -1, 1 -1, 1 0, 0 0)) +2 POLYGON((10 10, 10 11, 11 11, 11 10, 10 10)) +2 POLYGON((10 10, 10 9, 11 9, 11 10, 10 10)) +2 diff --git a/contrib/gis/src/main/java/com/esri/core/geometry/VertexGeomAccessor.java b/contrib/gis/src/main/java/com/esri/core/geometry/VertexGeomAccessor.java new file mode 100644 index 0000000..c95b798 --- /dev/null +++ b/contrib/gis/src/main/java/com/esri/core/geometry/VertexGeomAccessor.java @@ -0,0 +1,25 @@ +/* + * 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 com.esri.core.geometry; + +public class VertexGeomAccessor { + public static MultiVertexGeometry getVertexGeometry(Geometry geom){ + return (MultiVertexGeometry) geom._getImpl(); + } +} diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STBuffer.java similarity index 63% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STBuffer.java index 055eb94..a1d3af4 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STBuffer.java @@ -23,20 +23,23 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableIntHolder; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* +* Returns a geometry that represents all points whose distance from this Geometry +* is less than or equal to radius +*/ +@FunctionTemplate(name = "st_buffer", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromTextSrid implements DrillSimpleFunc { +public class STBuffer implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Param - NullableIntHolder sridParam; + Float8Holder bufferRadiusParam; @Output VarBinaryHolder out; @@ -48,21 +51,19 @@ public class STGeomFromTextSrid implements DrillSimpleFunc { } public void eval() { - int srid = sridParam.value; - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); + double bufferRadius = bufferRadiusParam.value; - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - geom.setSpatialReference(com.esri.core.geometry.SpatialReference.create(srid)); + com.esri.core.geometry.ogc.OGCGeometry bufferedGeom = geom1.buffer(bufferRadius); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + java.nio.ByteBuffer bufferedGeomBytes = bufferedGeom.asBinary(); - int outputSize = pointBytes.remaining(); + int outputSize = bufferedGeomBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; - buffer.setBytes(0, pointBytes); - } + buffer.setBytes(0, bufferedGeomBytes); + } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STContains.java similarity index 59% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STContains.java index 3a613e1..5204ce6 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STContains.java @@ -23,19 +23,26 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + Returns true if and only if no points of B lie in the exterior of A, + and at least one point of the interior of B lies in the interior of A. +*/ +@FunctionTemplate(name = "st_contains", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STContains implements DrillSimpleFunc { + @Param + VarBinaryHolder geom1Param; + @Param - NullableVarCharHolder input; + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +51,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int contains = geom1.contains(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = contains; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STCrosses.java similarity index 61% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STCrosses.java index 3a613e1..95d7aca 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STCrosses.java @@ -23,19 +23,25 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns TRUE if the supplied geometries have some, but not all, interior points in common + */ +@FunctionTemplate(name = "st_crosses", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STCrosses implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; + + @Param + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +50,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int crosses = geom1.crosses(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = crosses; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDifference.java similarity index 59% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDifference.java index 055eb94..4906880 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDifference.java @@ -23,20 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableIntHolder; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Given geometries A and B, this function returns a geometry that represents + * the part of geometry A that does not intersect with geometry B + */ +@FunctionTemplate(name = "st_difference", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromTextSrid implements DrillSimpleFunc { +public class STDifference implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Param - NullableIntHolder sridParam; + VarBinaryHolder geom2Param; @Output VarBinaryHolder out; @@ -48,21 +50,21 @@ public class STGeomFromTextSrid implements DrillSimpleFunc { } public void eval() { - int srid = sridParam.value; - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry diffGeom = geom1.difference(geom2); - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - geom.setSpatialReference(com.esri.core.geometry.SpatialReference.create(srid)); + java.nio.ByteBuffer bufferedGeomBytes = diffGeom.asBinary(); - java.nio.ByteBuffer pointBytes = geom.asBinary(); - - int outputSize = pointBytes.remaining(); + int outputSize = bufferedGeomBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; - buffer.setBytes(0, pointBytes); - } + buffer.setBytes(0, bufferedGeomBytes); + } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDisjoint.java similarity index 61% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDisjoint.java index 3a613e1..8a34241 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDisjoint.java @@ -23,19 +23,25 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns TRUE if two Geometries do not "spatially intersect" - if they do not share any space + */ +@FunctionTemplate(name = "st_disjoint", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STDisjoint implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; + + @Param + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +50,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int isDisjoint = geom1.disjoint(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = isDisjoint; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDistance.java similarity index 58% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDistance.java index 3a613e1..9415f39 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STDistance.java @@ -23,19 +23,26 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * For geometry type Returns the 2D Cartesian distance between two geometries in projected units (based on spatial ref). + * For geography type defaults to return minimum geodesic distance between two geographies in meters + */ +@FunctionTemplate(name = "st_distance", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STDistance implements DrillSimpleFunc { + @Param + VarBinaryHolder geom1Param; + @Param - NullableVarCharHolder input; + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +51,14 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - java.nio.ByteBuffer pointBytes = geom.asBinary(); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = geom1.distance(geom2); } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STEnvelope.java similarity index 60% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STEnvelope.java index 055eb94..8286224 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STEnvelope.java @@ -23,20 +23,19 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableIntHolder; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns a geometry representing the double precision (float8) bounding box of the supplied geometry. + * The polygon is defined by the corner points of the bounding box ((MINX, MINY), (MINX, MAXY), (MAXX, MAXY), (MAXX, MINY), (MINX, MINY)) + */ +@FunctionTemplate(name = "st_envelope", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromTextSrid implements DrillSimpleFunc { - @Param - NullableVarCharHolder input; - +public class STEnvelope implements DrillSimpleFunc { @Param - NullableIntHolder sridParam; + VarBinaryHolder geom1Param; @Output VarBinaryHolder out; @@ -48,21 +47,23 @@ public class STGeomFromTextSrid implements DrillSimpleFunc { } public void eval() { - int srid = sridParam.value; - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); + com.esri.core.geometry.ogc.OGCGeometry geom1; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - geom.setSpatialReference(com.esri.core.geometry.SpatialReference.create(srid)); + com.esri.core.geometry.ogc.OGCGeometry envelopeGeom; + if (geom1.geometryType().equals("Point")) { + envelopeGeom = geom1; + } else { + envelopeGeom = geom1.envelope(); + } - java.nio.ByteBuffer pointBytes = geom.asBinary(); + java.nio.ByteBuffer envelopeGeomBytes = envelopeGeom.asBinary(); - int outputSize = pointBytes.remaining(); + int outputSize = envelopeGeomBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; - buffer.setBytes(0, pointBytes); - } + buffer.setBytes(0, envelopeGeomBytes); + } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STEquals.java similarity index 61% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STEquals.java index 3a613e1..b5e22d6 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STEquals.java @@ -23,19 +23,25 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns true if the given geometries represent the same geometry. Directionality is ignored + */ +@FunctionTemplate(name = "st_equals", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STEquals implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; + + @Param + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +50,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int equals = geom1.equals(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = equals; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java index 3a613e1..042046e 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java @@ -45,12 +45,10 @@ public class STGeomFromText implements DrillSimpleFunc { public void eval() { String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); + input.buffer); com.esri.core.geometry.ogc.OGCGeometry geom; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - java.nio.ByteBuffer pointBytes = geom.asBinary(); int outputSize = pointBytes.remaining(); diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java index 055eb94..9a7432e 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java @@ -64,5 +64,5 @@ public class STGeomFromTextSrid implements DrillSimpleFunc { out.start = 0; out.end = outputSize; buffer.setBytes(0, pointBytes); - } + } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STIntersects.java similarity index 59% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STIntersects.java index 3a613e1..9e152c5 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STIntersects.java @@ -23,19 +23,25 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns TRUE if the Geometries/Geography "spatially intersect in 2D" - (share any portion of space) and FALSE if they don't (they are Disjoint) + */ +@FunctionTemplate(name = "st_intersects", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STIntersects implements DrillSimpleFunc { + @Param + VarBinaryHolder geom1Param; + @Param - NullableVarCharHolder input; + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +50,15 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int intersects = geom1.intersects(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = intersects; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STOverlaps.java similarity index 60% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STOverlaps.java index 3a613e1..7ae770d 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STOverlaps.java @@ -23,19 +23,25 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns TRUE if the Geometries share space, are of the same dimension, but are not completely contained by each other + */ +@FunctionTemplate(name = "st_overlaps", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STOverlaps implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; + + @Param + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +50,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int overlaps = geom1.overlaps(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = overlaps; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STRelate.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STRelate.java new file mode 100644 index 0000000..9a1c64b --- /dev/null +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STRelate.java @@ -0,0 +1,73 @@ +/* + * 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.apache.drill.exec.expr.fn.impl.gis; + +import javax.inject.Inject; + +import org.apache.drill.exec.expr.DrillSimpleFunc; +import org.apache.drill.exec.expr.annotations.FunctionTemplate; +import org.apache.drill.exec.expr.annotations.Output; +import org.apache.drill.exec.expr.annotations.Param; +import org.apache.drill.exec.expr.holders.BitHolder; +import org.apache.drill.exec.expr.holders.VarBinaryHolder; +import org.apache.drill.exec.expr.holders.VarCharHolder; + +import io.netty.buffer.DrillBuf; + +/* + * Returns true if this Geometry is spatially related to anotherGeometry, by testing for intersections between + * the Interior, Boundary and Exterior of the two geometries as specified by the values in the intersectionMatrixPattern. + * If no intersectionMatrixPattern is passed in, then returns the maximum intersectionMatrixPattern that relates the 2 geometries + */ +@FunctionTemplate(name = "st_relate", scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) +public class STRelate implements DrillSimpleFunc { + @Param + VarBinaryHolder geom1Param; + + @Param + VarBinaryHolder geom2Param; + + @Param + VarCharHolder matrixParam; + + @Output + BitHolder out; + + @Inject + DrillBuf buffer; + + public void setup() { + } + + public void eval() { + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; + String matrix = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(matrixParam.start, + matrixParam.end, matrixParam.buffer); + + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); + + int relates = geom1.relate(geom2, matrix) ? 1 : 0; + + out.value = relates; + } +} diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STTouches.java similarity index 61% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STTouches.java index 3a613e1..79ad0c7 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STTouches.java @@ -23,19 +23,25 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns TRUE if the geometries have at least one point in common, but their interiors do not intersect + */ +@FunctionTemplate(name = "st_touches", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STTouches implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; + + @Param + VarBinaryHolder geom2Param; @Output - VarBinaryHolder out; + BitHolder out; @Inject DrillBuf buffer; @@ -44,19 +50,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - java.nio.ByteBuffer pointBytes = geom.asBinary(); + int touches = geom1.touches(geom2) ? 1 : 0; - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + out.value = touches; } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STTransform.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STTransform.java new file mode 100644 index 0000000..c2788c1 --- /dev/null +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STTransform.java @@ -0,0 +1,114 @@ +/* + * 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.apache.drill.exec.expr.fn.impl.gis; + +import javax.inject.Inject; + +import org.apache.drill.exec.expr.DrillSimpleFunc; +import org.apache.drill.exec.expr.annotations.FunctionTemplate; +import org.apache.drill.exec.expr.annotations.Output; +import org.apache.drill.exec.expr.annotations.Param; +import org.apache.drill.exec.expr.annotations.Workspace; +import org.apache.drill.exec.expr.holders.NullableIntHolder; +import org.apache.drill.exec.expr.holders.VarBinaryHolder; +import org.osgeo.proj4j.CRSFactory; +import org.osgeo.proj4j.CoordinateTransform; + +import io.netty.buffer.DrillBuf; + +/* + * Return a new geometry with its coordinates transformed to a different spatial reference + */ +@FunctionTemplate(name = "st_transform", scope = FunctionTemplate.FunctionScope.SIMPLE, + nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) +public class STTransform implements DrillSimpleFunc { + @Param + VarBinaryHolder geom1Param; + + @Param + NullableIntHolder sridSrcParam; + + @Param + NullableIntHolder sridTgtParam; + + @Workspace + CoordinateTransform transform; + + @Workspace + CRSFactory crsFactory; + + @Workspace + int sridTgt; + + @Output + VarBinaryHolder out; + + @Inject + DrillBuf buffer; + + public void setup() { + int sridSrc = sridSrcParam.value; + sridTgt = sridTgtParam.value; + + org.osgeo.proj4j.CoordinateReferenceSystem srcCrs = + new org.osgeo.proj4j.CRSFactory().createFromName("EPSG:" + sridSrc); + + org.osgeo.proj4j.CoordinateReferenceSystem tgtCrs = + new org.osgeo.proj4j.CRSFactory().createFromName("EPSG:" + sridTgt); + + transform = new org.osgeo.proj4j.BasicCoordinateTransform(srcCrs, tgtCrs); + } + + public void eval() { + com.esri.core.geometry.ogc.OGCGeometry geomSrc = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + + //int code = Integer.parseInt(transform.getTargetCRS().getName().substring(5, 9));//now sridTgt + org.osgeo.proj4j.ProjCoordinate result = new org.osgeo.proj4j.ProjCoordinate(); + com.esri.core.geometry.SpatialReference sr = com.esri.core.geometry.SpatialReference.create(sridTgt); + java.nio.ByteBuffer geomBytes = null; + + if (geomSrc != null && geomSrc.geometryType().equals("Point")) { + com.esri.core.geometry.ogc.OGCPoint pointGeom = (com.esri.core.geometry.ogc.OGCPoint) geomSrc; + result = transform.transform(new org.osgeo.proj4j.ProjCoordinate(pointGeom.X(), pointGeom.Y()), result); + + geomBytes = new com.esri.core.geometry.ogc.OGCPoint( + new com.esri.core.geometry.Point(result.x, result.y), sr).asBinary(); + } else { + com.esri.core.geometry.Geometry esriGeom = geomSrc.getEsriGeometry(); + com.esri.core.geometry.MultiVertexGeometry vertexGeom = + com.esri.core.geometry.VertexGeomAccessor.getVertexGeometry(esriGeom); + for (int i = 0; i < vertexGeom.getPointCount(); i++) { + com.esri.core.geometry.Point point = vertexGeom.getPoint(i); + result = transform.transform(new org.osgeo.proj4j.ProjCoordinate(point.getX(), point.getY()), result); + point.setXY(result.x, result.y); + vertexGeom.setPoint(i, point); + } + + com.esri.core.geometry.ogc.OGCGeometry tGeom = + com.esri.core.geometry.ogc.OGCGeometry.createFromEsriGeometry(esriGeom, sr); + geomBytes = tGeom.asBinary(); + } + + int outputSize = geomBytes.remaining(); + buffer = out.buffer = buffer.reallocIfNeeded(outputSize); + out.start = 0; + out.end = outputSize; + buffer.setBytes(0, geomBytes); + } +} diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STUnion.java similarity index 61% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STUnion.java index 055eb94..907c6da 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromTextSrid.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STUnion.java @@ -23,20 +23,21 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableIntHolder; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns a geometry that represents the point set union of the Geometries + */ +@FunctionTemplate(name = "st_union", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromTextSrid implements DrillSimpleFunc { +public class STUnion implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Param - NullableIntHolder sridParam; + VarBinaryHolder geom2Param; @Output VarBinaryHolder out; @@ -48,21 +49,21 @@ public class STGeomFromTextSrid implements DrillSimpleFunc { } public void eval() { - int srid = sridParam.value; - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); + com.esri.core.geometry.ogc.OGCGeometry geom1; + com.esri.core.geometry.ogc.OGCGeometry geom2; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + geom2 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); - com.esri.core.geometry.ogc.OGCGeometry geom; + com.esri.core.geometry.ogc.OGCGeometry unionGeom = geom1.union(geom2); - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - geom.setSpatialReference(com.esri.core.geometry.SpatialReference.create(srid)); + java.nio.ByteBuffer bufferedGeomBytes = unionGeom.asBinary(); - java.nio.ByteBuffer pointBytes = geom.asBinary(); - - int outputSize = pointBytes.remaining(); + int outputSize = bufferedGeomBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; - buffer.setBytes(0, pointBytes); - } + buffer.setBytes(0, bufferedGeomBytes); + } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STUnionAggregate.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STUnionAggregate.java new file mode 100644 index 0000000..bcb7615 --- /dev/null +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STUnionAggregate.java @@ -0,0 +1,115 @@ +/* + * 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.apache.drill.exec.expr.fn.impl.gis; + +import javax.inject.Inject; + +import org.apache.drill.exec.expr.DrillAggFunc; +import org.apache.drill.exec.expr.annotations.FunctionTemplate; +import org.apache.drill.exec.expr.annotations.Output; +import org.apache.drill.exec.expr.annotations.Param; +import org.apache.drill.exec.expr.annotations.Workspace; +import org.apache.drill.exec.expr.holders.BigIntHolder; +import org.apache.drill.exec.expr.holders.IntHolder; +import org.apache.drill.exec.expr.holders.NullableVarBinaryHolder; +import org.apache.drill.exec.expr.holders.ObjectHolder; +import org.apache.drill.exec.expr.holders.UInt1Holder; + +import io.netty.buffer.DrillBuf; + +/* + * Returns a geometry that represents the point set union of the Geometries + */ +@FunctionTemplate(name = "st_unionaggregate", scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) +public class STUnionAggregate implements DrillAggFunc { + @Param NullableVarBinaryHolder in; + @Workspace ObjectHolder value; + @Workspace UInt1Holder init; + @Workspace BigIntHolder nonNullCount; + @Workspace IntHolder srid; + @Inject DrillBuf buf; + @Output NullableVarBinaryHolder out; + + public void setup() { + init = new UInt1Holder(); + nonNullCount = new BigIntHolder(); + nonNullCount.value = 0; + init.value = 0; + value = new ObjectHolder(); + value.obj = new java.util.ArrayList<com.esri.core.geometry.Geometry>(); + } + + @Override + public void add() { + sout: { + if (in.isSet == 0) { + // processing nullable input and the value is null, so don't do anything... + break sout; + } + nonNullCount.value = 1; + java.util.ArrayList<com.esri.core.geometry.Geometry> tmp = (java.util.ArrayList<com.esri.core.geometry.Geometry>) value.obj; + + com.esri.core.geometry.ogc.OGCGeometry geom; + geom = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(in.buffer.nioBuffer(in.start, in.end - in.start)); + + tmp.add(geom.getEsriGeometry()); + + if(init.value == 0) { + init.value = 1; + srid.value = geom.SRID(); + } + } // end of sout block + } + + @Override + public void output() { + if (nonNullCount.value > 0) { + out.isSet = 1; + + java.util.ArrayList<com.esri.core.geometry.Geometry> tmp = (java.util.ArrayList<com.esri.core.geometry.Geometry>) value.obj; + + com.esri.core.geometry.SpatialReference spatialRef = null; + if (srid.value != 0){ + spatialRef = com.esri.core.geometry.SpatialReference.create(4326); + } + com.esri.core.geometry.Geometry[] geomArr = + (com.esri.core.geometry.Geometry[]) tmp.toArray( new com.esri.core.geometry.Geometry[0] ); + com.esri.core.geometry.Geometry geom = com.esri.core.geometry.GeometryEngine.union(geomArr, spatialRef); + + com.esri.core.geometry.ogc.OGCGeometry unionGeom = com.esri.core.geometry.ogc.OGCGeometry.createFromEsriGeometry(geom, spatialRef); + java.nio.ByteBuffer unionGeomBytes = unionGeom.asBinary(); + + int outputSize = unionGeomBytes.remaining(); + buf = out.buffer = buf.reallocIfNeeded(outputSize); + out.start = 0; + out.end = outputSize; + buf.setBytes(0, unionGeomBytes); + } else { + out.isSet = 0; + } + } + + @Override + public void reset() { + value = new ObjectHolder(); + value.obj = new java.util.ArrayList<com.esri.core.geometry.Geometry>(); + init.value = 0; + nonNullCount.value = 0; + } +} diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXFunc.java similarity index 66% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXFunc.java index 3a613e1..8986bbc 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXFunc.java @@ -23,19 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Return the X coordinate of the point, or NaN if not available + */ +@FunctionTemplate(name = "st_x", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STXFunc implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geomParam; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +47,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); com.esri.core.geometry.ogc.OGCGeometry geom; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - - java.nio.ByteBuffer pointBytes = geom.asBinary(); + geom = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geomParam.buffer.nioBuffer(geomParam.start, geomParam.end - geomParam.start)); - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + if (geom != null && geom.geometryType().equals("Point")) { + out.value = ((com.esri.core.geometry.ogc.OGCPoint) geom).X(); + } else { + out.value = Double.NaN; + } } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXMax.java similarity index 60% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXMax.java index 3a613e1..ee8afa0 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXMax.java @@ -23,19 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns X maxima of a bounding box 2d or 3d or a geometry + */ +@FunctionTemplate(name = "st_xmax", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STXMax implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +47,17 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - - java.nio.ByteBuffer pointBytes = geom.asBinary(); - - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + com.esri.core.geometry.ogc.OGCGeometry geom1; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + + com.esri.core.geometry.ogc.OGCGeometry envelopeGeom; + if (geom1.geometryType().equals("Point")) { + out.value = ((com.esri.core.geometry.ogc.OGCPoint) geom1).X(); + } else { + com.esri.core.geometry.Envelope envelope = new com.esri.core.geometry.Envelope(); + geom1.getEsriGeometry().queryEnvelope(envelope); + out.value = envelope.getXMax(); + } } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXMin.java similarity index 60% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXMin.java index 3a613e1..d527e6e 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STXMin.java @@ -23,19 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns X minima of a bounding box 2d or 3d or a geometry + */ +@FunctionTemplate(name = "st_xmin", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STXMin implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +47,17 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - - java.nio.ByteBuffer pointBytes = geom.asBinary(); - - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + com.esri.core.geometry.ogc.OGCGeometry geom1; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + + com.esri.core.geometry.ogc.OGCGeometry envelopeGeom; + if (geom1.geometryType().equals("Point")) { + out.value = ((com.esri.core.geometry.ogc.OGCPoint) geom1).X(); + } else { + com.esri.core.geometry.Envelope envelope = new com.esri.core.geometry.Envelope(); + geom1.getEsriGeometry().queryEnvelope(envelope); + out.value = envelope.getXMin(); + } } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYFunc.java similarity index 66% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYFunc.java index 3a613e1..ce1771a 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYFunc.java @@ -23,19 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Return the Y coordinate of the point, or NaN if not available + */ +@FunctionTemplate(name = "st_y", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STYFunc implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geomParam; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +47,16 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); com.esri.core.geometry.ogc.OGCGeometry geom; - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - - java.nio.ByteBuffer pointBytes = geom.asBinary(); + geom = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geomParam.buffer.nioBuffer(geomParam.start, geomParam.end - geomParam.start)); - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + if (geom != null && geom.geometryType().equals("Point")) { + out.value = ((com.esri.core.geometry.ogc.OGCPoint) geom).Y(); + } else { + out.value = Double.NaN; + } } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYMax.java similarity index 60% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYMax.java index 3a613e1..4101e79 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYMax.java @@ -23,19 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns Y maxima of a bounding box 2d or 3d or a geometry + */ +@FunctionTemplate(name = "st_ymax", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STYMax implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +47,17 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - - java.nio.ByteBuffer pointBytes = geom.asBinary(); - - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + com.esri.core.geometry.ogc.OGCGeometry geom1; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + + com.esri.core.geometry.ogc.OGCGeometry envelopeGeom; + if (geom1.geometryType().equals("Point")) { + out.value = ((com.esri.core.geometry.ogc.OGCPoint) geom1).Y(); + } else { + com.esri.core.geometry.Envelope envelope = new com.esri.core.geometry.Envelope(); + geom1.getEsriGeometry().queryEnvelope(envelope); + out.value = envelope.getYMax(); + } } } diff --git a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYMin.java similarity index 60% copy from contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java copy to contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYMin.java index 3a613e1..85fc7e4 100644 --- a/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STGeomFromText.java +++ b/contrib/gis/src/main/java/org/apache/drill/exec/expr/fn/impl/gis/STYMin.java @@ -23,19 +23,22 @@ import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.NullableVarCharHolder; +import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.VarBinaryHolder; import io.netty.buffer.DrillBuf; -@FunctionTemplate(name = "st_geomfromtext", scope = FunctionTemplate.FunctionScope.SIMPLE, +/* + * Returns Y minima of a bounding box 2d or 3d or a geometry + */ +@FunctionTemplate(name = "st_ymin", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL) -public class STGeomFromText implements DrillSimpleFunc { +public class STYMin implements DrillSimpleFunc { @Param - NullableVarCharHolder input; + VarBinaryHolder geom1Param; @Output - VarBinaryHolder out; + Float8Holder out; @Inject DrillBuf buffer; @@ -44,19 +47,17 @@ public class STGeomFromText implements DrillSimpleFunc { } public void eval() { - String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, - input.buffer); - - com.esri.core.geometry.ogc.OGCGeometry geom; - - geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); - - java.nio.ByteBuffer pointBytes = geom.asBinary(); - - int outputSize = pointBytes.remaining(); - buffer = out.buffer = buffer.reallocIfNeeded(outputSize); - out.start = 0; - out.end = outputSize; - buffer.setBytes(0, pointBytes); + com.esri.core.geometry.ogc.OGCGeometry geom1; + geom1 = com.esri.core.geometry.ogc.OGCGeometry + .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); + + com.esri.core.geometry.ogc.OGCGeometry envelopeGeom; + if (geom1.geometryType().equals("Point")) { + out.value = ((com.esri.core.geometry.ogc.OGCPoint) geom1).Y(); + } else { + com.esri.core.geometry.Envelope envelope = new com.esri.core.geometry.Envelope(); + geom1.getEsriGeometry().queryEnvelope(envelope); + out.value = envelope.getYMin(); + } } } diff --git a/contrib/gis/src/test/java/org/apache/drill/exec/expr/fn/impl/gis/TestGeometryFunctions.java b/contrib/gis/src/test/java/org/apache/drill/exec/expr/fn/impl/gis/TestGeometryFunctions.java index 8e5ead3..379de5c 100644 --- a/contrib/gis/src/test/java/org/apache/drill/exec/expr/fn/impl/gis/TestGeometryFunctions.java +++ b/contrib/gis/src/test/java/org/apache/drill/exec/expr/fn/impl/gis/TestGeometryFunctions.java @@ -29,7 +29,6 @@ public class TestGeometryFunctions extends BaseTestQuery { @Test public void testGeometryFromTextCreation() throws Exception { - testBuilder() .sqlQuery("select ST_AsText(ST_GeomFromText('" + wktPoint + "')) " + "from cp.`sample-data/CA-cities.csv` limit 1") @@ -41,7 +40,6 @@ public class TestGeometryFunctions extends BaseTestQuery { @Test public void testGeometryPointCreation() throws Exception { - testBuilder() .sqlQuery("select ST_AsText(ST_Point(-121.895, 37.339)) " + "from cp.`sample-data/CA-cities.csv` limit 1") @@ -76,6 +74,30 @@ public class TestGeometryFunctions extends BaseTestQuery { } @Test + public void testNullWkt() throws Exception { + testBuilder() + .sqlQuery("select ST_AsText(ST_GeomFromText(columns[4])) " + + "from cp.`/sample-data/CA-cities-with-nulls.csv` limit 1") + .ordered() + .baselineColumns("EXPR$0") + .baselineValues(new Object[]{null}) + .build() + .run(); + } + + @Test + public void testNullGeoJSON() throws Exception { + testBuilder() + .sqlQuery("select ST_AsGeoJson(ST_GeomFromText(columns[4])) " + + "from cp.`/sample-data/CA-cities-with-nulls.csv` limit 1") + .ordered() + .baselineColumns("EXPR$0") + .baselineValues(new Object[]{null}) + .build() + .run(); + } + + @Test public void testGeoJSONCreationFromPoint() throws Exception { testBuilder() .sqlQuery("select ST_AsGeoJSON(ST_Point(-121.895, 37.339)) " @@ -86,7 +108,6 @@ public class TestGeometryFunctions extends BaseTestQuery { .build() .run(); } - @Test public void testGeoJSONCreationFromGeom() throws Exception { testBuilder() @@ -101,7 +122,6 @@ public class TestGeometryFunctions extends BaseTestQuery { @Test public void testSTWithinQuery() throws Exception { - testBuilder() .sqlQuery("select ST_Within(ST_Point(columns[4], columns[3])," + "ST_GeomFromText('POLYGON((-121.95 37.28, -121.94 37.35, -121.84 37.35, -121.84 37.28, -121.95 37.28))')" @@ -123,4 +143,204 @@ public class TestGeometryFunctions extends BaseTestQuery { .build() .run(); } + + @Test + public void testSTXQuery() throws Exception { + testBuilder() + .sqlQuery("select ST_X(ST_Point(-121.895, 37.339)) " + + "from cp.`/sample-data/CA-cities.csv` limit 1") + .ordered().baselineColumns("EXPR$0") + .baselineValues(-121.895) + .build() + .run(); + } + + @Test + public void testSTYQuery() throws Exception { + testBuilder() + .sqlQuery("select ST_Y(ST_Point(-121.895, 37.339)) " + + "from cp.`/sample-data/CA-cities.csv` limit 1") + .ordered().baselineColumns("EXPR$0") + .baselineValues(37.339) + .build() + .run(); + } + + @Test + public void testIntersectQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Intersects(ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('LINESTRING(2 0,0 2)')) " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(false) + .build() + .run(); + + testBuilder() + .sqlQuery("SELECT ST_Intersects(ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('LINESTRING(0 0,0 2)')) " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(true) + .build() + .run(); + } + + @Test + public void testRelateQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Relate(ST_GeomFromText('POINT(1 2)'), ST_Buffer(ST_GeomFromText('POINT(1 2)'),2), '0FFFFF212') " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(true) + .build() + .run(); + + testBuilder() + .sqlQuery("SELECT ST_Relate(ST_GeomFromText('POINT(1 2)'), ST_Buffer(ST_GeomFromText('POINT(1 2)'),2), '*FF*FF212') " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(true) + .build() + .run(); + + testBuilder() + .sqlQuery("SELECT ST_Relate(ST_GeomFromText('POINT(0 0)'), ST_Buffer(ST_GeomFromText('POINT(1 2)'),2), '*FF*FF212') " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(false) + .build() + .run(); + } + + @Test + public void testTouchesQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Touches(ST_GeomFromText('LINESTRING(0 0, 1 1, 0 2)'), ST_GeomFromText('POINT(1 1)')) " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(false) + .build() + .run(); + + testBuilder() + .sqlQuery("SELECT ST_Touches(ST_GeomFromText('LINESTRING(0 0, 1 1, 0 2)'), ST_GeomFromText('POINT(0 2)')) " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(true) + .build() + .run(); + } + + @Test + public void testEqualsQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Equals(ST_GeomFromText('LINESTRING(0 0, 10 10)'), " + + "ST_GeomFromText('LINESTRING(0 0, 5 5, 10 10)')) from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(true) + .build() + .run(); + } + + @Test + public void testContainsQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Contains(smallc, bigc) As smallcontainsbig, " + + "ST_Contains(bigc,smallc) As bigcontainssmall, " + + "ST_Contains(bigc, ST_Union(smallc, bigc)) as bigcontainsunion, " + + "ST_Equals(bigc, ST_Union(smallc, bigc)) as bigisunion " + + "FROM (SELECT ST_Buffer(ST_GeomFromText('POINT(1 2)'), 10) As smallc, " + + "ST_Buffer(ST_GeomFromText('POINT(1 2)'), 20) As bigc from (VALUES(1)) ) As foo") + .ordered().baselineColumns("smallcontainsbig", "bigcontainssmall", "bigcontainsunion", "bigisunion") + .baselineValues(false, true, true, true) + .build() + .run(); + } + + @Test + public void testOverlapsCrossesIntersectsContainsQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Overlaps(a,b) As a_overlap_b, " + + "ST_Crosses(a,b) As a_crosses_b, " + + "ST_Intersects(a, b) As a_intersects_b, " + + "ST_Contains(b,a) As b_contains_a " + + "FROM (SELECT ST_GeomFromText('POINT(1 0.5)') As a, ST_GeomFromText('LINESTRING(1 0, 1 1, 3 5)') As b " + + "from (VALUES(1)) ) As foo") + .ordered().baselineColumns("a_overlap_b", "a_crosses_b", "a_intersects_b", "b_contains_a") + .baselineValues(false, false, true, true) + .build() + .run(); + } + + @Test + public void testDisjointQuery() throws Exception { + testBuilder() + .sqlQuery("SELECT ST_Disjoint(ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('LINESTRING( 2 0, 0 2 )')) " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(true) + .build() + .run(); + + testBuilder() + .sqlQuery("SELECT ST_Disjoint(ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('LINESTRING( 0 0, 0 2 )')) " + + "from (VALUES(1))") + .ordered().baselineColumns("EXPR$0") + .baselineValues(false) + .build() + .run(); + } + + @Test + public void testTransfromQuery() throws Exception { + double targetX = -71.1776848522251; + double targetY = 42.3902896512902; + + testBuilder() + .sqlQuery("SELECT round(st_x(st_transform(st_geomfromtext('POINT (743238 2967416)'), 2249, 4326)), 13)," + + " round(st_y(st_transform(st_geomfromtext('POINT (743238 2967416)'), 2249, 4326)), 13) from (VALUES(1))") + .ordered().baselineColumns("EXPR$0", "EXPR$1") + .baselineValues(targetX, targetY) + .build() + .run(); + } + + @Test + public void testUnionAggregateQuery() throws Exception { + String targetAll = "MULTIPOLYGON (((0 -1, 1 -1, 1 0, 1 1, 0 1, 0 0, 0 -1)), " + + "((10 9, 11 9, 11 10, 11 11, 10 11, 10 10, 10 9)))"; + String targetFirstGroup = "POLYGON ((0 -1, 1 -1, 1 0, 1 1, 0 1, 0 0, 0 -1))"; + String targetSecondGroup = "POLYGON ((10 9, 11 9, 11 10, 11 11, 10 11, 10 10, 10 9))"; + + testBuilder() + .sqlQuery("select ST_AsText(ST_UnionAggregate(ST_GeomFromText(columns[1]))) from cp.`sample-data/polygons.tsv`") + .ordered().baselineColumns("EXPR$0") + .baselineValues(targetAll) + .build() + .run(); + + testBuilder() + .sqlQuery("select columns[0], ST_AsText(ST_UnionAggregate(ST_GeomFromText(columns[1])))" + + " from cp.`sample-data/polygons.tsv` group by columns[0] having columns[0] = '1'") + .ordered().baselineColumns("EXPR$0", "EXPR$1") + .baselineValues("1", targetFirstGroup) + .build() + .run(); + + testBuilder() + .sqlQuery("select columns[0], ST_AsText(ST_UnionAggregate(ST_GeomFromText(columns[1])))" + + " from cp.`sample-data/polygons.tsv` group by columns[0] having columns[0] = '2'") + .ordered().baselineColumns("EXPR$0", "EXPR$1") + .baselineValues("2", targetSecondGroup) + .build() + .run(); + + testBuilder() + .sqlQuery("select count(*) from (select columns[0], ST_AsText(ST_UnionAggregate(ST_GeomFromText(columns[1])))" + + " from cp.`sample-data/polygons.tsv` group by columns[0])") + .ordered().baselineColumns("EXPR$0") + .baselineValues(3L) + .build() + .run(); + } } -- To stop receiving notification emails like this one, please contact [email protected].
