Skip to content

Commit dd07273

Browse files
authored
SQL: Add ST_X, ST_Y and ST_GEOMETRY_TYPE functions (#41104)
Adds 3 new geosql functions. The ST_Z functions as well as ST_X and ST_Y functions for polygons are not supported because of the issues described in #40908. This support will be added as soon as the ShapeBuilder issues are resolved. Relates to #29872
1 parent 07ad376 commit dd07273

File tree

18 files changed

+598
-23
lines changed

18 files changed

+598
-23
lines changed

docs/reference/sql/functions/geo.asciidoc

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Returns the WKT representation of the `geometry`. The return type is string.
2828

2929
["source","sql",subs="attributes,macros"]
3030
--------------------------------------------------
31-
include-tagged::{sql-specs}/geo/docs.csv-spec[aswkt]
31+
include-tagged::{sql-specs}/docs/geo.csv-spec[aswkt]
3232
--------------------------------------------------
3333

3434

@@ -53,7 +53,85 @@ Returns the geometry from WKT representation. The return type is geometry.
5353

5454
["source","sql",subs="attributes,macros"]
5555
--------------------------------------------------
56-
include-tagged::{sql-specs}/geo/docs.csv-spec[aswkt]
56+
include-tagged::{sql-specs}/docs/geo.csv-spec[aswkt]
57+
--------------------------------------------------
58+
59+
==== Geometry Properties
60+
61+
[[sql-functions-geo-st-geometrytype]]
62+
===== `ST_GeometryType`
63+
64+
.Synopsis:
65+
[source, sql]
66+
--------------------------------------------------
67+
ST_GeometryType(geometry<1>)
68+
--------------------------------------------------
69+
70+
*Input*:
71+
72+
<1> geometry
73+
74+
*Output*: string
75+
76+
.Description:
77+
78+
Returns the type of the `geometry` such as POINT, MULTIPOINT, LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, GEOMETRYCOLLECTION, ENVELOPE or CIRCLE.
79+
80+
The return type is string.
81+
82+
["source","sql",subs="attributes,macros"]
83+
--------------------------------------------------
84+
include-tagged::{sql-specs}/docs/geo.csv-spec[geometrytype]
85+
--------------------------------------------------
86+
87+
[[sql-functions-geo-st-x]]
88+
===== `ST_X`
89+
90+
.Synopsis:
91+
[source, sql]
92+
--------------------------------------------------
93+
ST_X(geometry<1>)
94+
--------------------------------------------------
95+
96+
*Input*:
97+
98+
<1> geometry
99+
100+
*Output*: double
101+
102+
.Description:
103+
104+
Returns the longitude of the first point in the geometry.
105+
The return type is double.
106+
107+
["source","sql",subs="attributes,macros"]
108+
--------------------------------------------------
109+
include-tagged::{sql-specs}/docs/geo.csv-spec[x]
110+
--------------------------------------------------
111+
112+
[[sql-functions-geo-st-y]]
113+
===== `ST_Y`
114+
115+
.Synopsis:
116+
[source, sql]
117+
--------------------------------------------------
118+
ST_Y(geometry<1>)
119+
--------------------------------------------------
120+
121+
*Input*:
122+
123+
<1> geometry
124+
125+
*Output*: double
126+
127+
.Description:
128+
129+
Returns the the latitude of the first point in the geometry.
130+
The return type is double.
131+
132+
["source","sql",subs="attributes,macros"]
133+
--------------------------------------------------
134+
include-tagged::{sql-specs}/docs/geo.csv-spec[y]
57135
--------------------------------------------------
58136

59137
[[sql-functions-geo-st-distance]]
@@ -78,5 +156,5 @@ Returns the distance between geometries in meters. Both geometries have to be po
78156

79157
["source","sql",subs="attributes,macros"]
80158
--------------------------------------------------
81-
include-tagged::{sql-specs}/geo/docs.csv-spec[distance]
159+
include-tagged::{sql-specs}/docs/geo.csv-spec[distance]
82160
--------------------------------------------------

docs/reference/sql/functions/index.asciidoc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,11 @@
136136
** <<sql-functions-conditional-nvl>>
137137
* <<sql-functions-geo>>
138138
** <<sql-functions-geo-st-as-wkt>>
139-
** <<sql-functions-geo-st-wkt-to-sql>>
140139
** <<sql-functions-geo-st-distance>>
140+
** <<sql-functions-geo-st-geometrytype>>
141+
** <<sql-functions-geo-st-wkt-to-sql>>
142+
** <<sql-functions-geo-st-x>>
143+
** <<sql-functions-geo-st-y>>
141144
* <<sql-functions-system>>
142145
** <<sql-functions-system-database>>
143146
** <<sql-functions-system-user>>

x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static List<Object[]> readScriptSpec() throws Exception {
3636
List<Object[]> tests = new ArrayList<>();
3737
tests.addAll(readScriptSpec("/ogc/ogc.csv-spec", parser));
3838
tests.addAll(readScriptSpec("/geo/geosql.csv-spec", parser));
39-
tests.addAll(readScriptSpec("/geo/docs.csv-spec", parser));
39+
tests.addAll(readScriptSpec("/docs/geo.csv-spec", parser));
4040
return tests;
4141
}
4242

x-pack/plugin/sql/qa/src/main/resources/command.csv-spec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,11 @@ USER |SCALAR
135135
ST_ASTEXT |SCALAR
136136
ST_ASWKT |SCALAR
137137
ST_DISTANCE |SCALAR
138+
ST_GEOMETRYTYPE |SCALAR
138139
ST_GEOMFROMTEXT |SCALAR
139140
ST_WKTTOSQL |SCALAR
141+
ST_X |SCALAR
142+
ST_Y |SCALAR
140143
SCORE |SCORE
141144
;
142145

x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,11 @@ USER |SCALAR
312312
ST_ASTEXT |SCALAR
313313
ST_ASWKT |SCALAR
314314
ST_DISTANCE |SCALAR
315+
ST_GEOMETRYTYPE |SCALAR
315316
ST_GEOMFROMTEXT |SCALAR
316317
ST_WKTTOSQL |SCALAR
318+
ST_X |SCALAR
319+
ST_Y |SCALAR
317320
SCORE |SCORE
318321
// end::showFunctions
319322
;

x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec renamed to x-pack/plugin/sql/qa/src/main/resources/docs/geo.csv-spec

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,36 @@ SELECT ST_Distance(ST_WKTToSQL('POINT (10 20)'), ST_WKTToSQL('POINT (20 30)')) d
3535
1499101.2889383635
3636
// end::distance
3737
;
38+
39+
///////////////////////////////
40+
//
41+
// Geometry Properties
42+
//
43+
///////////////////////////////
44+
45+
selectGeometryType
46+
// tag::geometrytype
47+
SELECT ST_GeometryType(ST_WKTToSQL('POINT (10 20)')) type;
48+
49+
type:s
50+
POINT
51+
// end::geometrytype
52+
;
53+
54+
selectX
55+
// tag::x
56+
SELECT ST_X(ST_WKTToSQL('POINT (10 20)')) x;
57+
58+
x:d
59+
10.0
60+
// end::x
61+
;
62+
63+
selectY
64+
// tag::y
65+
SELECT ST_Y(ST_WKTToSQL('POINT (10 20)')) y;
66+
67+
y:d
68+
20.0
69+
// end::y
70+
;

x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,75 @@ SELECT ST_Distance(ST_WktToSql(NULL), ST_WktToSQL('POINT (-71 42)')) shape;
214214
shape:d
215215
null
216216
;
217+
218+
groupByGeometryType
219+
SELECT COUNT(*) cnt, ST_GeometryType(location) gt FROM geo GROUP BY ST_GeometryType(location);
220+
221+
cnt:l | gt:s
222+
15 |POINT
223+
;
224+
225+
226+
groupAndOrderByGeometryType
227+
SELECT COUNT(*) cnt, ST_GeometryType(location) gt FROM geo GROUP BY gt ORDER BY gt;
228+
229+
cnt:l | gt:s
230+
15 |POINT
231+
;
232+
233+
groupByEastWest
234+
SELECT COUNT(*) cnt, FLOOR(ST_X(location)/90) east FROM geo GROUP BY east ORDER BY east;
235+
236+
cnt:l | east:l
237+
3 |-2
238+
3 |-1
239+
4 |0
240+
5 |1
241+
;
242+
243+
groupByNorthSouth
244+
SELECT COUNT(*) cnt, FLOOR(ST_Y(location)/45) north FROM geo GROUP BY north ORDER BY north;
245+
246+
cnt:l | north:l
247+
1 |-1
248+
9 |0
249+
5 |1
250+
;
251+
252+
groupByNorthEastSortByEastNorth
253+
SELECT COUNT(*) cnt, FLOOR(ST_Y(location)/45) north, FLOOR(ST_X(location)/90) east FROM geo GROUP BY north, east ORDER BY east, north;
254+
255+
cnt:l | north:l | east:l
256+
3 |0 |-2
257+
2 |0 |-1
258+
1 |1 |-1
259+
4 |1 |0
260+
1 |-1 |1
261+
4 |0 |1
262+
;
263+
264+
selectFilterByXOfLocation
265+
SELECT city, ST_X(shape) x, ST_Y(shape) y, ST_X(location) lx, ST_Y(location) ly FROM geo WHERE lx > 0 ORDER BY ly;
266+
267+
city:s | x:d | y:d | lx:d | ly:d
268+
Sydney |151.208629 |-33.863385 |151.20862897485495|-33.863385021686554
269+
Singapore |103.855535 |1.295868 |103.8555349688977 |1.2958679627627134
270+
Hong Kong |114.183925 |22.281397 |114.18392493389547|22.28139698971063
271+
Tokyo |139.76402225 |35.669616 |139.76402222178876|35.66961596254259
272+
Seoul |127.060851 |37.509132 |127.06085099838674|37.50913198571652
273+
Munich |11.537505 |48.146321 |11.537504978477955|48.14632098656148
274+
Paris |2.351773 |48.845538 |2.3517729341983795|48.84553796611726
275+
Amsterdam |4.850312 |52.347557 |4.850311987102032 |52.347556999884546
276+
Berlin |13.390889 |52.486701 |13.390888944268227|52.48670099303126
277+
;
278+
279+
selectFilterByRegionPoint
280+
SELECT city, region, ST_X(location) x FROM geo WHERE ST_X(ST_WKTTOSQL(region_point)) < 0 ORDER BY x;
281+
282+
city:s | region:s | x:d
283+
San Francisco |Americas |-122.39422800019383
284+
Mountain View |Americas |-122.08384302444756
285+
Phoenix |Americas |-111.97350500151515
286+
Chicago |Americas |-87.63787407428026
287+
New York |Americas |-73.9900270756334
288+
;

x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,55 @@ SELECT fid, name, num_lanes, aliases, REPLACE(UCASE(ST_AsText(centerline)), '.0'
3434

3535
selectSinglePoint
3636
SELECT ST_GeomFromText('point (10.0 12.0)') point;
37+
38+
39+
//
40+
// Geometry Property Functions
41+
//
42+
// H2GIS doesn't follow the standard here that mandates ST_Dimension returns SMALLINT
43+
selectLakesProps
44+
SELECT fid, UCASE(ST_GeometryType(shore)) type FROM lakes ORDER BY fid;
45+
selectRoadSegmentsProps
46+
SELECT fid, UCASE(ST_GeometryType(centerline)) type FROM road_segments ORDER BY fid;
47+
selectDividedRoutesProps
48+
SELECT fid, UCASE(ST_GeometryType(centerlines)) type FROM divided_routes ORDER BY fid;
49+
selectForestsProps
50+
SELECT fid, UCASE(ST_GeometryType(boundary)) type FROM forests ORDER BY fid;
51+
selectBridgesProps
52+
SELECT fid, UCASE(ST_GeometryType(position)) type FROM bridges ORDER BY fid;
53+
selectStreamsProps
54+
SELECT fid, UCASE(ST_GeometryType(centerline)) type FROM streams ORDER BY fid;
55+
selectBuildingsProps
56+
SELECT fid, UCASE(ST_GeometryType(position)) type1, UCASE(ST_GeometryType(footprint)) type2 FROM buildings ORDER BY fid;
57+
selectPondsProps
58+
SELECT fid, UCASE(ST_GeometryType(shores)) type FROM ponds ORDER BY fid;
59+
selectNamedPlacesProps
60+
SELECT fid, UCASE(ST_GeometryType(boundary)) type FROM named_places ORDER BY fid;
61+
selectMapNeatLinesProps
62+
SELECT fid, UCASE(ST_GeometryType(neatline)) type FROM map_neatlines ORDER BY fid;
63+
64+
// AwaitsFix https://github.com/elastic/elasticsearch/issues/40908
65+
// selectLakesXY
66+
// SELECT fid, ST_X(shore) x, ST_Y(shore) y FROM lakes ORDER BY fid;
67+
selectRoadSegmentsXY
68+
SELECT fid, ST_X(centerline) x, ST_Y(centerline) y FROM road_segments ORDER BY fid;
69+
selectDividedRoutesXY
70+
SELECT fid, ST_X(centerlines) x, ST_Y(centerlines) y FROM divided_routes ORDER BY fid;
71+
// AwaitsFix https://github.com/elastic/elasticsearch/issues/40908
72+
// selectForestsXY
73+
// SELECT fid, ST_X(boundary) x, ST_Y(boundary) y FROM forests ORDER BY fid;
74+
selectBridgesPositionsXY
75+
SELECT fid, ST_X(position) x, ST_Y(position) y FROM bridges ORDER BY fid;
76+
selectStreamsXY
77+
SELECT fid, ST_X(centerline) x, ST_Y(centerline) y FROM streams ORDER BY fid;
78+
selectBuildingsXY
79+
SELECT fid, ST_X(position) x, ST_Y(position) y FROM buildings ORDER BY fid;
80+
// AwaitsFix https://github.com/elastic/elasticsearch/issues/40908
81+
// selectBuildingsFootprintsXY
82+
// SELECT fid, ST_X(footprint) x, ST_Y(footprint) y FROM buildings ORDER BY fid;
83+
// selectPondsXY
84+
// SELECT fid, ST_X(shores) x, ST_Y(shores) y FROM ponds ORDER BY fid;
85+
// selectNamedPlacesXY
86+
// SELECT fid, ST_X(boundary) x, ST_Y(boundary) y FROM named_places ORDER BY fid;
87+
// selectMapNeatLinesXY
88+
// SELECT fid, ST_X(neatline) x, ST_Y(neatline) y FROM map_neatlines ORDER BY fid;

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@
4848
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.Year;
4949
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StAswkt;
5050
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StDistance;
51+
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StGeometryType;
5152
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StWkttosql;
53+
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StX;
54+
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StY;
5255
import org.elasticsearch.xpack.sql.expression.function.scalar.math.ACos;
5356
import org.elasticsearch.xpack.sql.expression.function.scalar.math.ASin;
5457
import org.elasticsearch.xpack.sql.expression.function.scalar.math.ATan;
@@ -258,7 +261,10 @@ private void defineDefaultFunctions() {
258261
// Geo Functions
259262
addToMap(def(StAswkt.class, StAswkt::new, "ST_ASWKT", "ST_ASTEXT"),
260263
def(StWkttosql.class, StWkttosql::new, "ST_WKTTOSQL", "ST_GEOMFROMTEXT"),
261-
def(StDistance.class, StDistance::new, "ST_DISTANCE")
264+
def(StDistance.class, StDistance::new, "ST_DISTANCE"),
265+
def(StX.class, StX::new, "ST_X"),
266+
def(StY.class, StY::new, "ST_Y"),
267+
def(StGeometryType.class, StGeometryType::new, "ST_GEOMETRYTYPE")
262268
);
263269

264270
// Special

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoProcessor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ default R apply(Object o) {
2828
}
2929

3030
public enum GeoOperation {
31-
ASWKT(GeoShape::toString);
31+
ASWKT(GeoShape::toString),
32+
GEOMETRY_TYPE(GeoShape::getGeometryType),
33+
X(GeoShape::getX),
34+
Y(GeoShape::getY);
3235

3336
private final Function<Object, Object> apply;
3437

0 commit comments

Comments
 (0)