Skip to content

Commit 6beb6e5

Browse files
authored
[GH-2798] Add ST_ShortestLine function (#2806)
1 parent b3c8279 commit 6beb6e5

23 files changed

Lines changed: 500 additions & 0 deletions

File tree

common/src/main/java/org/apache/sedona/common/Functions.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,15 @@ public static Geometry closestPoint(Geometry left, Geometry right) {
11151115
}
11161116
}
11171117

1118+
public static Geometry shortestLine(Geometry left, Geometry right) {
1119+
if (left.isEmpty() || right.isEmpty()) {
1120+
return null;
1121+
}
1122+
DistanceOp distanceOp = new DistanceOp(left, right);
1123+
Coordinate[] closestPoints = distanceOp.nearestPoints();
1124+
return left.getFactory().createLineString(closestPoints);
1125+
}
1126+
11181127
public static Geometry delaunayTriangle(Geometry geometry) {
11191128
return delaunayTriangle(geometry, 0.0, 0);
11201129
}

common/src/test/java/org/apache/sedona/common/FunctionsTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4195,6 +4195,61 @@ public void closestPointEmpty() {
41954195
assertEquals(expected, e2.getMessage());
41964196
}
41974197

4198+
@Test
4199+
public void shortestLinePointToPoint() {
4200+
Point point1 = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 0));
4201+
Point point2 = GEOMETRY_FACTORY.createPoint(new Coordinate(3, 4));
4202+
String expected = "LINESTRING (0 0, 3 4)";
4203+
String actual = Functions.shortestLine(point1, point2).toText();
4204+
assertEquals(expected, actual);
4205+
}
4206+
4207+
@Test
4208+
public void shortestLinePointToLineString() {
4209+
Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(160, 40));
4210+
LineString lineString =
4211+
GEOMETRY_FACTORY.createLineString(
4212+
coordArray(10, 30, 50, 50, 30, 110, 70, 90, 180, 140, 130, 190));
4213+
Geometry result = Functions.shortestLine(point, lineString);
4214+
assertNotNull(result);
4215+
assertEquals("LineString", result.getGeometryType());
4216+
// First point should be on the point geometry, second on the linestring
4217+
assertEquals(160.0, result.getCoordinates()[0].x, 1e-6);
4218+
assertEquals(40.0, result.getCoordinates()[0].y, 1e-6);
4219+
}
4220+
4221+
@Test
4222+
public void shortestLinePolygonToPolygon() {
4223+
Polygon polygonA =
4224+
GEOMETRY_FACTORY.createPolygon(coordArray(190, 150, 20, 10, 160, 70, 190, 150));
4225+
Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(80, 160));
4226+
Geometry polygonB = Functions.buffer(point, 30);
4227+
Geometry result = Functions.shortestLine(polygonA, polygonB);
4228+
assertNotNull(result);
4229+
assertEquals("LineString", result.getGeometryType());
4230+
// The length of the shortest line should equal the distance between the polygons
4231+
assertEquals(Functions.distance(polygonA, polygonB), result.getLength(), 1e-6);
4232+
}
4233+
4234+
@Test
4235+
public void shortestLineEmptyGeometry() {
4236+
Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(1, 1));
4237+
LineString emptyLineString = GEOMETRY_FACTORY.createLineString();
4238+
assertNull(Functions.shortestLine(point, emptyLineString));
4239+
4240+
Polygon emptyPolygon = GEOMETRY_FACTORY.createPolygon();
4241+
assertNull(Functions.shortestLine(emptyPolygon, emptyLineString));
4242+
}
4243+
4244+
@Test
4245+
public void shortestLineSameGeometry() {
4246+
Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(5, 5));
4247+
Geometry result = Functions.shortestLine(point, point);
4248+
assertNotNull(result);
4249+
assertEquals("LINESTRING (5 5, 5 5)", result.toText());
4250+
assertEquals(0.0, result.getLength(), 1e-6);
4251+
}
4252+
41984253
@Test
41994254
public void testZmFlag() throws ParseException {
42004255
int _2D = 0, _3DM = 1, _3DZ = 2, _4D = 3;

docs/api/flink/Geometry-Functions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ These functions compute measurements of distance, area, length, and angles.
201201
| [ST_MinimumClearanceLine](Measurement-Functions/ST_MinimumClearanceLine.md) | Geometry | This function returns a two-point LineString geometry representing the minimum clearance distance of the input geometry. If the input geometry does not have a defined minimum clearance, such as for... | v1.6.1 |
202202
| [ST_Perimeter](Measurement-Functions/ST_Perimeter.md) | Double | This function calculates the 2D perimeter of a given geometry. It supports Polygon, MultiPolygon, and GeometryCollection geometries (as long as the GeometryCollection contains polygonal geometries)... | v1.7.0 |
203203
| [ST_Perimeter2D](Measurement-Functions/ST_Perimeter2D.md) | Double | This function calculates the 2D perimeter of a given geometry. It supports Polygon, MultiPolygon, and GeometryCollection geometries (as long as the GeometryCollection contains polygonal geometries)... | v1.7.1 |
204+
| [ST_ShortestLine](Measurement-Functions/ST_ShortestLine.md) | Geometry | Returns the shortest LineString between two geometries. The line starts on geom1 and ends on geom2. If either geometry is empty, returns null. | v1.9.0 |
204205

205206
## Geometry Processing
206207

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
20+
# ST_ShortestLine
21+
22+
Introduction: Returns the shortest LineString between two geometries. The line starts on geom1 and ends on geom2. If either geometry is empty, the function returns null.
23+
24+
![ST_ShortestLine](../../../image/ST_ShortestLine/ST_ShortestLine.svg "ST_ShortestLine")
25+
26+
Format: `ST_ShortestLine(geom1: Geometry, geom2: Geometry)`
27+
28+
Return type: `Geometry`
29+
30+
Since: `v1.9.0`
31+
32+
SQL Example:
33+
34+
![ST_ShortestLine Point to Point](../../../image/ST_ShortestLine/ST_ShortestLine_point_point.svg "ST_ShortestLine Point to Point")
35+
36+
```sql
37+
SELECT ST_ShortestLine(
38+
ST_GeomFromText('POINT (0 0)'),
39+
ST_GeomFromText('POINT (3 4)')
40+
)
41+
```
42+
43+
Output:
44+
45+
```
46+
LINESTRING (0 0, 3 4)
47+
```
48+
49+
SQL Example:
50+
51+
![ST_ShortestLine Point to LineString](../../../image/ST_ShortestLine/ST_ShortestLine_point_linestring.svg "ST_ShortestLine Point to LineString")
52+
53+
```sql
54+
SELECT ST_ShortestLine(
55+
ST_GeomFromText('POINT (0 1)'),
56+
ST_GeomFromText('LINESTRING (0 0, 1 0, 2 0, 3 0, 4 0, 5 0)')
57+
)
58+
```
59+
60+
Output:
61+
62+
```
63+
LINESTRING (0 1, 0 0)
64+
```

docs/api/snowflake/vector-data/Geometry-Functions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ These functions compute measurements of distance, area, length, and angles.
193193
| [ST_MinimumClearanceLine](Measurement-Functions/ST_MinimumClearanceLine.md) | This function returns a two-point LineString geometry representing the minimum clearance distance of the input geometry. If the input geometry does not have a defined minimum clearance, such as for... |
194194
| [ST_Perimeter](Measurement-Functions/ST_Perimeter.md) | This function calculates the 2D perimeter of a given geometry. It supports Polygon, MultiPolygon, and GeometryCollection geometries (as long as the GeometryCollection contains polygonal geometries)... |
195195
| [ST_Perimeter2D](Measurement-Functions/ST_Perimeter2D.md) | This function calculates the 2D perimeter of a given geometry. It supports Polygon, MultiPolygon, and GeometryCollection geometries (as long as the GeometryCollection contains polygonal geometries)... |
196+
| [ST_ShortestLine](Measurement-Functions/ST_ShortestLine.md) | Returns the shortest LineString between two geometries. The line starts on geom1 and ends on geom2. If either geometry is empty, returns null. |
196197

197198
## Geometry Processing
198199

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
20+
# ST_ShortestLine
21+
22+
Introduction: Returns the shortest LineString between two geometries. The line starts on geom1 and ends on geom2. If either geometry is empty, the function returns null.
23+
24+
![ST_ShortestLine](../../../../image/ST_ShortestLine/ST_ShortestLine.svg "ST_ShortestLine")
25+
26+
Format: `ST_ShortestLine(geom1: Geometry, geom2: Geometry)`
27+
28+
Return type: `Geometry`
29+
30+
SQL Example:
31+
32+
![ST_ShortestLine Point to Point](../../../../image/ST_ShortestLine/ST_ShortestLine_point_point.svg "ST_ShortestLine Point to Point")
33+
34+
```sql
35+
SELECT ST_ShortestLine(
36+
ST_GeomFromText('POINT (0 0)'),
37+
ST_GeomFromText('POINT (3 4)')
38+
)
39+
```
40+
41+
Output:
42+
43+
```
44+
LINESTRING (0 0, 3 4)
45+
```
46+
47+
SQL Example:
48+
49+
![ST_ShortestLine Point to LineString](../../../../image/ST_ShortestLine/ST_ShortestLine_point_linestring.svg "ST_ShortestLine Point to LineString")
50+
51+
```sql
52+
SELECT ST_ShortestLine(
53+
ST_GeomFromText('POINT (0 1)'),
54+
ST_GeomFromText('LINESTRING (0 0, 1 0, 2 0, 3 0, 4 0, 5 0)')
55+
)
56+
```
57+
58+
Output:
59+
60+
```
61+
LINESTRING (0 1, 0 0)
62+
```

docs/api/sql/Geometry-Functions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ These functions compute measurements of distance, area, length, and angles.
202202
| [ST_MinimumClearanceLine](Measurement-Functions/ST_MinimumClearanceLine.md) | Geometry | This function returns a two-point LineString geometry representing the minimum clearance distance of the input geometry. If the input geometry does not have a defined minimum clearance, such as for... | v1.6.1 |
203203
| [ST_Perimeter](Measurement-Functions/ST_Perimeter.md) | Double | This function calculates the 2D perimeter of a given geometry. It supports Polygon, MultiPolygon, and GeometryCollection geometries (as long as the GeometryCollection contains polygonal geometries)... | v1.7.0 |
204204
| [ST_Perimeter2D](Measurement-Functions/ST_Perimeter2D.md) | Double | This function calculates the 2D perimeter of a given geometry. It supports Polygon, MultiPolygon, and GeometryCollection geometries (as long as the GeometryCollection contains polygonal geometries)... | v1.7.1 |
205+
| [ST_ShortestLine](Measurement-Functions/ST_ShortestLine.md) | Geometry | Returns the shortest LineString between two geometries. The line starts on geom1 and ends on geom2. If either geometry is empty, returns null. | v1.9.0 |
205206

206207
## Geometry Processing
207208

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
20+
# ST_ShortestLine
21+
22+
Introduction: Returns the shortest LineString between two geometries. The line starts on geom1 and ends on geom2. If either geometry is empty, the function returns null.
23+
24+
![ST_ShortestLine](../../../image/ST_ShortestLine/ST_ShortestLine.svg "ST_ShortestLine")
25+
26+
Format: `ST_ShortestLine(geom1: Geometry, geom2: Geometry)`
27+
28+
Return type: `Geometry`
29+
30+
Since: `v1.9.0`
31+
32+
SQL Example:
33+
34+
![ST_ShortestLine Point to Point](../../../image/ST_ShortestLine/ST_ShortestLine_point_point.svg "ST_ShortestLine Point to Point")
35+
36+
```sql
37+
SELECT ST_ShortestLine(
38+
ST_GeomFromText('POINT (0 0)'),
39+
ST_GeomFromText('POINT (3 4)')
40+
)
41+
```
42+
43+
Output:
44+
45+
```
46+
LINESTRING (0 0, 3 4)
47+
```
48+
49+
SQL Example:
50+
51+
![ST_ShortestLine Point to LineString](../../../image/ST_ShortestLine/ST_ShortestLine_point_linestring.svg "ST_ShortestLine Point to LineString")
52+
53+
```sql
54+
SELECT ST_ShortestLine(
55+
ST_GeomFromText('POINT (0 1)'),
56+
ST_GeomFromText('LINESTRING (0 0, 1 0, 2 0, 3 0, 4 0, 5 0)')
57+
)
58+
```
59+
60+
Output:
61+
62+
```
63+
LINESTRING (0 1, 0 0)
64+
```
Lines changed: 36 additions & 0 deletions
Loading
Lines changed: 50 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)