diff --git a/.github/workflows/release-ci.yml b/.github/workflows/release-ci.yml
index 3f3c525..48d8fd3 100644
--- a/.github/workflows/release-ci.yml
+++ b/.github/workflows/release-ci.yml
@@ -27,9 +27,13 @@ jobs:
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg-passphrase: GPG_PASSPHRASE
+ - name: Remove SNAPSHOT suffix from the project version
+ run: |
+ PACKAGE_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
+ ./mvnw versions:set -DnewVersion=${PACKAGE_VERSION%-SNAPSHOT} -DgenerateBackupPoms=false
+
- name: Publish to Release repository
run: ./mvnw -P release deploy
-
env:
NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
diff --git a/.idea/detekt.xml b/.idea/detekt.xml
index 2aed103..80df94c 100644
--- a/.idea/detekt.xml
+++ b/.idea/detekt.xml
@@ -6,6 +6,11 @@
+
diff --git a/pom.xml b/pom.xml
index 99de0e0..2a0cd9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
0.7.0
9.0.0
- 0.9.0${artifact.version.suffix}
+ 0.9.0-SNAPSHOT
dremio-udf-gis
GIS UDF extensions for Dremio
https://github.com/sheinbergon/dremio-udf-gis
@@ -542,14 +542,5 @@
-
- snapshot
-
- true
-
-
- -SNAPSHOT
-
-
\ 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 92a91c6..cf4b534 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
@@ -56,7 +56,7 @@ 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 Pattern EWKT_REGEX_PATTERN = Pattern.compile("^\\s*SRID\\s*=\\s*(\\d+)\\s*;\\s*(.+)\\s*$");
+ public static final Pattern EWKT_REGEX_PATTERN = Pattern.compile("^\\s*SRID\\s*=\\s*(\\d+)\\s*;\\s*(.+)\\s*$");
private GeometryHelpers() {
}
diff --git a/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryTransformation.java b/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryTransformation.java
index 66c9c82..8970905 100644
--- a/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryTransformation.java
+++ b/src/main/java/org/sheinbergon/dremio/udf/gis/util/GeometryTransformation.java
@@ -25,6 +25,8 @@
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
+import java.util.Arrays;
+import java.util.stream.IntStream;
public final class GeometryTransformation {
@@ -138,13 +140,16 @@ private static ProjCoordinate[] transformCoordinates(
private static Polygon transform(
@Nonnull final CoordinateTransform transform,
@Nonnull final Polygon polygon) {
- return polygon.getFactory()
- .createPolygon(
- transformCoordinates(transform, polygon.getCoordinates()));
+ LinearRing exterior = transform(transform, polygon.getExteriorRing());
+ LinearRing[] interior = IntStream.range(0, polygon.getNumInteriorRing())
+ .mapToObj(polygon::getInteriorRingN)
+ .map(ring -> transform(transform, ring))
+ .toArray(LinearRing[]::new);
+ return polygon.getFactory().createPolygon(exterior, interior);
}
@Nonnull
- private static Geometry transform(
+ private static Point transform(
@Nonnull final CoordinateTransform transform,
@Nonnull final Point point) {
return point.getFactory().createPoint(
@@ -153,7 +158,7 @@ private static Geometry transform(
}
@Nonnull
- private static Geometry transform(
+ private static LinearRing transform(
@Nonnull final CoordinateTransform transform,
@Nonnull final LinearRing linearRing) {
return linearRing.getFactory()
@@ -162,7 +167,7 @@ private static Geometry transform(
}
@Nonnull
- private static Geometry transform(
+ private static LineString transform(
@Nonnull final CoordinateTransform transform,
@Nonnull final LineString lineString) {
return lineString.getFactory().createLineString(
@@ -171,16 +176,14 @@ private static Geometry transform(
}
@Nonnull
- private static Geometry transform(
+ private static MultiPolygon transform(
@Nonnull final org.locationtech.proj4j.CoordinateTransform transform,
@Nonnull final MultiPolygon multiPolygon) {
- Polygon[] polygon = new Polygon[multiPolygon.getNumGeometries()];
- for (int i = 0; i < polygon.length; ++i) {
- polygon[i] = multiPolygon.getFactory()
- .createPolygon(transformCoordinates(transform,
- multiPolygon.getGeometryN(i).getCoordinates()));
- }
- return multiPolygon.getFactory().createMultiPolygon(polygon);
+ Polygon[] polygons = new Polygon[multiPolygon.getNumGeometries()];
+ Arrays.setAll(polygons, i -> transform(
+ transform,
+ (Polygon) multiPolygon.getGeometryN(i)));
+ return multiPolygon.getFactory().createMultiPolygon(polygons);
}
@Nonnull
@@ -193,20 +196,18 @@ private static Geometry transform(
}
@Nonnull
- private static Geometry transform(
+ private static MultiLineString transform(
@Nonnull final CoordinateTransform transform,
@Nonnull final MultiLineString multiLineString) {
LineString[] lineString = new LineString[multiLineString.getNumGeometries()];
- for (int index = 0; index < lineString.length; ++index) {
- lineString[index] = multiLineString.getFactory()
- .createLineString(transformCoordinates(transform,
- multiLineString.getGeometryN(index).getCoordinates()));
- }
+ Arrays.setAll(lineString, index -> transform(
+ transform,
+ (LineString) multiLineString.getGeometryN(index)));
return multiLineString.getFactory().createMultiLineString(lineString);
}
@Nonnull
- private static Geometry transform(
+ private static GeometryCollection transform(
@Nonnull final CoordinateTransform transform,
@Nonnull final GeometryCollection collection) {
Geometry[] geometry = new Geometry[collection.getNumGeometries()];
diff --git a/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STCollectAggregateTests.kt b/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STCollectAggregateTests.kt
index b0111dd..761ebf9 100644
--- a/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STCollectAggregateTests.kt
+++ b/src/test/kotlin/org/sheinbergon/dremio/udf/gis/STCollectAggregateTests.kt
@@ -12,11 +12,10 @@ internal class STCollectAggregateTests : GeometryAggregationFunSpec Geometry,
serializer: (Geometry) -> ByteArray,
) {
- val evaluated = GeometryHelpers.toGeometry(this)
- val reduced = GeometryPrecisionReducer.reducePointwise(evaluated, SCALED_PRECISION_MODEL)
- reduced.srid = evaluated.srid
+ val evaluated = toGeometry(this)
val expected = NullableVarCharHolder()
.apply { setUtf8(text) }
.let(adapter)
-
- kotlin.runCatching { serializer(reduced) shouldBe serializer(expected) }
- .recoverCatching { serializer(evaluated) shouldBe serializer(expected) }
- .onSuccess { this.isSet shouldBeExactly 1 }
- .getOrThrow()
+ serializer(evaluated) shouldBe serializer(expected)
+ this.isSet shouldBeExactly 1
+}
+
+private fun toGeometry(holder: NullableVarBinaryHolder) = holder.buffer?.run {
+ val buffer = holder.buffer.nioBuffer(holder.start.toLong(), holder.end - holder.start)
+ ByteBufferInputStream.toInputStream(buffer).use { stream ->
+ val adapter = InputStreamInStream(stream)
+ val reader = WKBReader(GeometryFactory(SCALED_PRECISION_MODEL))
+ reader.read(adapter)
+ }
+} ?: GeometryHelpers.emptyGeometry()
+
+private fun toGeometryFromWKT(holder: NullableVarCharHolder): Geometry {
+ val wkt = GeometryHelpers.toUTF8String(holder)
+ val reader = WKTReader(GeometryFactory(SCALED_PRECISION_MODEL))
+ return reader.read(wkt)
+}
+
+private fun toGeometryFromEWKT(
+ holder: NullableVarCharHolder
+): Geometry {
+ val ewkt = GeometryHelpers.toUTF8String(holder)
+ val reader = WKTReader(GeometryFactory(SCALED_PRECISION_MODEL))
+ val matcher = GeometryHelpers.EWKT_REGEX_PATTERN.matcher(ewkt)
+ return if (matcher.find()) {
+ reader
+ .read(matcher.group(2))
+ .also { geometry ->
+ geometry.srid = matcher.group(1).toInt()
+ }
+ } else {
+ throw IllegalArgumentException("input '$ewkt' is not a valid EWKT")
+ }
}
internal fun NullableVarBinaryHolder.valueIsNotSet() {