Skip to content

Commit

Permalink
temp affine commit
Browse files Browse the repository at this point in the history
  • Loading branch information
iGN5117 committed Jun 19, 2023
1 parent cd12ce2 commit 19016ae
Show file tree
Hide file tree
Showing 16 changed files with 441 additions and 222 deletions.
15 changes: 15 additions & 0 deletions common/src/main/java/org/apache/sedona/common/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,21 @@ public static Geometry translate(Geometry geometry, double deltaX, double deltaY
return geometry;
}

public static Geometry affine(Geometry geometry, double a, double b, double d, double e, double xOff, double yOff, double c,
double f, double g, double h, double i, double zOff) {
if (!geometry.isEmpty()) {
GeomUtils.affineGeom(geometry, a, b, d, e, xOff, yOff, c, f, g, h, i, zOff, true);
}
return geometry;
}

public static Geometry affine(Geometry geometry, double a, double b, double d, double e, double xOff, double yOff) {
if (!geometry.isEmpty()) {
GeomUtils.affineGeom(geometry, a, b, d, e, xOff, yOff, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false);
}
return geometry;
}

public static Geometry geometricMedian(Geometry geometry, double tolerance, int maxIter, boolean failIfNotConverged) throws Exception {
String geometryType = geometry.getGeometryType();
if(!(Geometry.TYPENAME_POINT.equals(geometryType) || Geometry.TYPENAME_MULTIPOINT.equals(geometryType))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.locationtech.jts.operation.polygonize.Polygonizer;
import org.locationtech.jts.operation.union.UnaryUnionOp;

import java.awt.*;
import java.nio.ByteOrder;
import java.util.*;
import java.util.List;
Expand Down Expand Up @@ -461,4 +460,21 @@ public static void translateGeom(Geometry geometry, double deltaX, double deltaY
geometry.geometryChanged();
}
}

public static void affineGeom(Geometry geometry, double a, double b, double d, double e, double xOff, double yOff, double c,
double f, double g, double h, double i, double zOff, boolean set3d) {
Coordinate[] coordinates = geometry.getCoordinates();
for (Coordinate currCoordinate: coordinates) {
double x = currCoordinate.getX(), y = currCoordinate.getY(), z = Double.isNaN(currCoordinate.getZ()) ? 0 : currCoordinate.getZ();
double newX = a * x + b * y + c * z + xOff;
double newY = d * x + e * y + f * z + yOff;
currCoordinate.setX(newX);
currCoordinate.setY(newY);
if (set3d && !Double.isNaN(currCoordinate.getZ())) {
double newZ = g * x + h * y + i * z + zOff;
currCoordinate.setZ(newZ);
}
}
geometry.geometryChanged();
}
}
90 changes: 89 additions & 1 deletion common/src/test/java/org/apache/sedona/common/FunctionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;

import javax.sound.sampled.Line;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -857,4 +856,93 @@ public void translateHybridGeomCollectionDeltaZ() {
assertEquals(wktWriter3D.write(expectedPoint3D), wktWriter3D.write(actualGeometry.getGeometryN(0).getGeometryN(1)));
assertEquals(emptyLineString.toText(), actualGeometry.getGeometryN(0).getGeometryN(2).toText());
}

@Test
public void affineEmpty3D() {
LineString emptyLineString = GEOMETRY_FACTORY.createLineString();
String expected = emptyLineString.toText();
String actual = Functions.affine(emptyLineString, 1, 1, 2, 3, 5, 6, 2, 3, 4, 4, 5, 6).toText();
assertEquals(expected, actual);
}

@Test
public void affineEmpty2D() {
LineString emptyLineString = GEOMETRY_FACTORY.createLineString();
String expected = emptyLineString.toText();
String actual = Functions.affine(emptyLineString, 1, 2, 3, 4, 1, 2).toText();
assertEquals(expected, actual);
}

@Test
public void affine3DGeom2D() {
LineString lineString = GEOMETRY_FACTORY.createLineString(coordArray(1, 0, 1, 1, 1, 2));
String expected = GEOMETRY_FACTORY.createLineString(coordArray(6, 18, 7, 11, 8, 14)).toText();
String actual = Functions.affine(lineString, 1, 1, 2, 3, 5, 6, 2, 3, 4, 4, 5, 6).toText();
assertEquals(expected, actual);
}

@Test
public void affine3DGeom3D() {
WKTWriter wktWriter = new WKTWriter(3);
// 2 3 1, 4 5 1, 7 8 2 ,2 3 1
Polygon polygon3D = GEOMETRY_FACTORY.createPolygon(coordArray3d(2, 3, 1, 4, 5, 1, 7, 8, 2, 2, 3, 1));

LineString lineString = GEOMETRY_FACTORY.createLineString(coordArray3d(1, 0, 1, 1, 1, 2, 1, 2, 2));
String expected = wktWriter.write(GEOMETRY_FACTORY.createLineString(coordArray3d(8, 11, 15, 11, 17, 24, 12, 20, 28)));
String actual = wktWriter.write(Functions.affine(lineString, 1, 1, 2, 3, 5, 6, 2, 3, 4, 4, 5, 6));
assertEquals(expected, actual);
}

@Test
public void affine3DHybridGeomCollection() {
Point point3D = GEOMETRY_FACTORY.createPoint(new Coordinate(1, 1, 1));
Polygon polygon1 = GEOMETRY_FACTORY.createPolygon(coordArray3d(1, 0, 2, 1, 1, 2, 2, 1, 2, 2, 0, 2, 1, 0, 2));
Polygon polygon2 = GEOMETRY_FACTORY.createPolygon(coordArray3d(1, 0, 1, 1, 1, 1, 2, 2, 2, 1, 0, 1));
MultiPolygon multiPolygon = GEOMETRY_FACTORY.createMultiPolygon(new Polygon[] {polygon1, polygon2});
Geometry geomCollection = GEOMETRY_FACTORY.createGeometryCollection(new Geometry[] {GEOMETRY_FACTORY.createGeometryCollection(new Geometry[] {point3D, multiPolygon})});
Geometry actualGeomCollection = Functions.affine(geomCollection, 1, 2, 1, 2, 1, 2, 3, 3, 1, 2, 3, 3);
WKTWriter wktWriter3D = new WKTWriter(3);
Point expectedPoint3D = GEOMETRY_FACTORY.createPoint(new Coordinate(7, 8, 9));
Polygon expectedPolygon1 = GEOMETRY_FACTORY.createPolygon(coordArray3d(8, 9, 10, 10, 11, 12, 11, 12, 13, 9, 10, 11, 8, 9, 10));
Polygon expectedPolygon2 = GEOMETRY_FACTORY.createPolygon(coordArray3d(5, 6, 7, 7, 8, 9, 13, 14, 15, 5, 6, 7));
assertEquals(wktWriter3D.write(expectedPoint3D), wktWriter3D.write(actualGeomCollection.getGeometryN(0).getGeometryN(0)));
assertEquals(wktWriter3D.write(expectedPolygon1), wktWriter3D.write(actualGeomCollection.getGeometryN(0).getGeometryN(1).getGeometryN(0)));
assertEquals(wktWriter3D.write(expectedPolygon2), wktWriter3D.write(actualGeomCollection.getGeometryN(0).getGeometryN(1).getGeometryN(1)));

}

@Test
public void affine2DGeom3D() {
//1 0 1, 1 1 1, 2 2 2, 1 0 1
WKTWriter wktWriter = new WKTWriter(3);
LineString lineString = GEOMETRY_FACTORY.createLineString(coordArray3d(1, 0, 1, 1, 1, 2, 1, 2, 2));
String expected = wktWriter.write(GEOMETRY_FACTORY.createLineString(coordArray3d(6, 8, 1, 7, 11, 2, 8, 14, 2)));
String actual = wktWriter.write(Functions.affine(lineString, 1, 1, 2, 3, 5, 6));
assertEquals(expected, actual);
}

@Test
public void affine2DGeom2D() {
LineString lineString = GEOMETRY_FACTORY.createLineString(coordArray(1, 0, 1, 1, 1, 2));
String expected = GEOMETRY_FACTORY.createLineString(coordArray(6, 8, 7, 11, 8, 14)).toText();
String actual = Functions.affine(lineString, 1, 1, 2, 3, 5, 6).toText();
assertEquals(expected, actual);
}

@Test
public void affine2DHybridGeomCollection() {
Point point3D = GEOMETRY_FACTORY.createPoint(new Coordinate(1, 1));
Polygon polygon1 = GEOMETRY_FACTORY.createPolygon(coordArray(1, 0, 1, 1, 2, 1, 2, 0, 1, 0));
Polygon polygon2 = GEOMETRY_FACTORY.createPolygon(coordArray(3, 4, 3, 5, 3, 7, 10, 7, 3, 4));
MultiPolygon multiPolygon = GEOMETRY_FACTORY.createMultiPolygon(new Polygon[] {polygon1, polygon2});
Geometry geomCollection = GEOMETRY_FACTORY.createGeometryCollection(new Geometry[] {GEOMETRY_FACTORY.createGeometryCollection(new Geometry[] {point3D, multiPolygon})});
Geometry actualGeomCollection = Functions.affine(geomCollection, 1, 2, 1, 2, 1, 2);
Point expectedPoint3D = GEOMETRY_FACTORY.createPoint(new Coordinate(4, 5));
Polygon expectedPolygon1 = GEOMETRY_FACTORY.createPolygon(coordArray(2, 3, 4, 5, 5, 6, 3, 4, 2, 3));
Polygon expectedPolygon2 = GEOMETRY_FACTORY.createPolygon(coordArray(12, 13, 14, 15, 18, 19, 25, 26, 12, 13));
assertEquals(expectedPoint3D.toText(), actualGeomCollection.getGeometryN(0).getGeometryN(0).toText());
assertEquals(expectedPolygon1.toText(), actualGeomCollection.getGeometryN(0).getGeometryN(1).getGeometryN(0).toText());
assertEquals(expectedPolygon2.toText(), actualGeomCollection.getGeometryN(0).getGeometryN(1).getGeometryN(1).toText());
}

}
64 changes: 3 additions & 61 deletions docs/api/flink/Function.md
Original file line number Diff line number Diff line change
Expand Up @@ -703,47 +703,14 @@ SELECT ST_NDims(ST_GeomFromEWKT('POINT(1 1 2)'))

Output: `3`

Example with x,y coordinate:
Spark SQL example with x,y coordinate:

```sql
SELECT ST_NDims(ST_GeomFromText('POINT(1 1)'))
```

Output: `2`

## ST_NRings

Introduction: Returns the number of rings in a Polygon or MultiPolygon. Contrary to ST_NumInteriorRings,
this function also takes into account the number of exterior rings.

This function returns 0 for an empty Polygon or MultiPolygon.
If the geometry is not a Polygon or MultiPolygon, an IllegalArgument Exception is thrown.

Format: `ST_NRings(geom: geometry)`

Since: `1.4.1`


Examples:

Input: `POLYGON ((1 0, 1 1, 2 1, 2 0, 1 0))`

Output: `1`

Input: `'MULTIPOLYGON (((1 0, 1 6, 6 6, 6 0, 1 0), (2 1, 2 2, 3 2, 3 1, 2 1)), ((10 0, 10 6, 16 6, 16 0, 10 0), (12 1, 12 2, 13 2, 13 1, 12 1)))'`

Output: `4`

Input: `'POLYGON EMPTY'`

Output: `0`

Input: `'LINESTRING (1 0, 1 1, 2 1)'`

Output: `Unsupported geometry type: LineString, only Polygon or MultiPolygon geometries are supported.`



## ST_NumGeometries

Introduction: Returns the number of Geometries. If geometry is a GEOMETRYCOLLECTION (or MULTI*) return the number of geometries, for single geometries will return 1.
Expand Down Expand Up @@ -978,13 +945,13 @@ Format: `ST_Transform (A:geometry, SourceCRS:string, TargetCRS:string ,[Optional

Since: `v1.2.0`

Example (simple):
Spark SQL example (simple):
```sql
SELECT ST_Transform(polygondf.countyshape, 'epsg:4326','epsg:3857')
FROM polygondf
```

Example (with optional parameters):
Spark SQL example (with optional parameters):
```sql
SELECT ST_Transform(polygondf.countyshape, 'epsg:4326','epsg:3857', false)
FROM polygondf
Expand All @@ -993,31 +960,6 @@ FROM polygondf
!!!note
The detailed EPSG information can be searched on [EPSG.io](https://epsg.io/).

## ST_Translate
Introduction: Returns the input geometry with its X, Y and Z coordinates (if present in the geometry) translated by deltaX, deltaY and deltaZ (if specified)

If the geometry is 2D, and a deltaZ parameter is specified, no change is done to the Z coordinate of the geometry and the resultant geometry is also 2D.

If the geometry is empty, no change is done to it.

If the given geometry contains sub-geometries (GEOMETRY COLLECTION, MULTI POLYGON/LINE/POINT), all underlying geometries are individually translated.

Format: `ST_Translate(geometry: geometry, deltaX: deltaX, deltaY: deltaY, deltaZ: deltaZ)`

Since: `1.4.1`

Example:

Input: `ST_Translate(GEOMETRYCOLLECTION(MULTIPOLYGON (((1 0, 1 1, 2 1, 2 0, 1 0)), ((1 2, 3 4, 3 5, 1 2))), POINT(1, 1, 1), LINESTRING EMPTY), 2, 2, 3)`

Output: `GEOMETRYCOLLECTION(MULTIPOLYGON (((3 2, 3 3, 4 3, 4 2, 3 2)), ((3 4, 5 6, 5 7, 3 4))), POINT(3, 3, 4), LINESTRING EMPTY)`

Input: `ST_Translate(POINT(1, 3, 2), 1, 2)`

Output: `POINT(2, 5, 2)`



## ST_X

Introduction: Returns X Coordinate of given Point, null otherwise.
Expand Down
54 changes: 0 additions & 54 deletions docs/api/sql/Function.md
Original file line number Diff line number Diff line change
Expand Up @@ -1108,37 +1108,6 @@ SELECT ST_NPoints(polygondf.countyshape)
FROM polygondf
```

## ST_NRings

Introduction: Returns the number of rings in a Polygon or MultiPolygon. Contrary to ST_NumInteriorRings,
this function also takes into account the number of exterior rings.

This function returns 0 for an empty Polygon or MultiPolygon.
If the geometry is not a Polygon or MultiPolygon, an IllegalArgument Exception is thrown.

Format: `ST_NRings(geom: geometry)`

Since: `1.4.1`


Examples:

Input: `POLYGON ((1 0, 1 1, 2 1, 2 0, 1 0))`

Output: `1`

Input: `'MULTIPOLYGON (((1 0, 1 6, 6 6, 6 0, 1 0), (2 1, 2 2, 3 2, 3 1, 2 1)), ((10 0, 10 6, 16 6, 16 0, 10 0), (12 1, 12 2, 13 2, 13 1, 12 1)))'`

Output: `4`

Input: `'POLYGON EMPTY'`

Output: `0`

Input: `'LINESTRING (1 0, 1 1, 2 1)'`

Output: `Unsupported geometry type: LineString, only Polygon or MultiPolygon geometries are supported.`

## ST_NumGeometries

Introduction: Returns the number of Geometries. If geometry is a GEOMETRYCOLLECTION (or MULTI*) return the number of geometries, for single geometries will return 1.
Expand Down Expand Up @@ -1598,29 +1567,6 @@ FROM polygondf
!!!note
The detailed EPSG information can be searched on [EPSG.io](https://epsg.io/).


## ST_Translate
Introduction: Returns the input geometry with its X, Y and Z coordinates (if present in the geometry) translated by deltaX, deltaY and deltaZ (if specified)

If the geometry is 2D, and a deltaZ parameter is specified, no change is done to the Z coordinate of the geometry and the resultant geometry is also 2D.

If the geometry is empty, no change is done to it.
If the given geometry contains sub-geometries (GEOMETRY COLLECTION, MULTI POLYGON/LINE/POINT), all underlying geometries are individually translated.

Format: `ST_Translate(geometry: geometry, deltaX: deltaX, deltaY: deltaY, deltaZ: deltaZ)`

Since: `1.4.1`

Example:

Input: `ST_Translate(GEOMETRYCOLLECTION(MULTIPOLYGON (((1 0, 1 1, 2 1, 2 0, 1 0)), ((1 2, 3 4, 3 5, 1 2))), POINT(1, 1, 1), LINESTRING EMPTY), 2, 2, 3)`

Output: `GEOMETRYCOLLECTION(MULTIPOLYGON (((3 2, 3 3, 4 3, 4 2, 3 2)), ((3 4, 5 6, 5 7, 3 4))), POINT(3, 3, 4), LINESTRING EMPTY)`

Input: `ST_Translate(POINT(1, 3, 2), 1, 2)`

Output: `POINT(2, 5, 2)`

## ST_Union

Introduction: Return the union of geometry A and B
Expand Down
20 changes: 2 additions & 18 deletions docs/community/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

### IDE

We recommend Intellij IDEA with Scala plugin installed. Please make sure that the IDE has JDK 1.8 set as project default.
We recommend Intellij IDEA with Scala plugin installed.

### Import the project

Expand Down Expand Up @@ -51,10 +51,6 @@ Make sure you reload the POM.xml or reload the maven project. The IDE will ask y
#### Run all unit tests

In a terminal, go to the Sedona root folder. Run `mvn clean install`. All tests will take more than 15 minutes. To only build the project jars, run `mvn clean install -DskipTests`.
!!!Note
`mvn clean install` will compile Sedona with Spark 3.0 and Scala 2.12. If you have a different version of Spark in $SPARK_HOME, make sure to specify that using -Dspark command line arg.
For example, to compile sedona with Spark 3.4 and Scala 2.12, use: `mvn clean install -Dspark=3.4 -Dscala=2.12`


More details can be found on [Compile Sedona](../../setup/compile/)

Expand Down Expand Up @@ -82,19 +78,7 @@ Re-run the test case. Do NOT right click the test case to re-run. Instead, click

## Python developers

#### Run all python tests

To run all Python test cases, follow steps mentioned [here](../../setup/compile/#run-python-test).

#### Run all python tests in a single test file
To run a particular python test file, specify the path of the .py file to pipenv.

For example, to run all tests in `test_function.py` located in `python/tests/sql/`, use: `pipenv run pytest tests/sql/test_function.py`.

#### Run a single test
To run a particular test in a particular .py test file, specify `file_name::class_name::test_name` to the pytest command.

For example, to run the test on ST_Contains function located in sql/test_predicate.py, use: `pipenv run pytest tests/sql/test_predicate.py::TestPredicate::test_st_contains`
More details to come.

### IDE

Expand Down
1 change: 1 addition & 0 deletions flink/src/main/java/org/apache/sedona/flink/Catalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public static UserDefinedFunction[] getFuncs() {
new Functions.ST_Force3D(),
new Functions.ST_NRings(),
new Functions.ST_Translate(),
new Functions.ST_Affine(),
};
}

Expand Down
Loading

0 comments on commit 19016ae

Please sign in to comment.