-
Notifications
You must be signed in to change notification settings - Fork 25.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SQL: Add basic support for ST_AsWKT geo function (#34205)
Adds basic support for ST_AsWKT function. The function takes accepts geo shape or geo point and returns its WKT representation.
- Loading branch information
Showing
23 changed files
with
609 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
[role="xpack"] | ||
[testenv="basic"] | ||
[[sql-functions-geo]] | ||
=== Geo Functions | ||
|
||
The geo functions work with geometries stored in `geo_point` and `geo_shape` fields, or returned by other geo functions. | ||
|
||
==== Geometry Conversion | ||
|
||
[[sql-functions-geo-st-as-wkt]] | ||
===== `ST_AsWKT` | ||
|
||
.Synopsis: | ||
[source, sql] | ||
-------------------------------------------------- | ||
ST_AsWKT(geometry<1>) | ||
-------------------------------------------------- | ||
|
||
*Input*: | ||
|
||
<1> geometry | ||
|
||
*Output*: string | ||
|
||
.Description: | ||
|
||
Returns the WKT representation of the `geometry`. The return type is string. | ||
|
||
["source","sql",subs="attributes,macros"] | ||
-------------------------------------------------- | ||
include-tagged::{sql-specs}/geo/docs.csv-spec[aswkt] | ||
-------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
...rc/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.sql.expression.function.scalar.geo; | ||
|
||
import org.elasticsearch.common.geo.GeoPoint; | ||
import org.elasticsearch.common.geo.builders.PointBuilder; | ||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; | ||
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; | ||
|
||
import java.io.IOException; | ||
import java.util.function.Function; | ||
|
||
public class GeoProcessor implements Processor { | ||
|
||
private interface GeoPointFunction<R> { | ||
default R apply(Object o) { | ||
if (!(o instanceof GeoPoint)) { | ||
throw new SqlIllegalArgumentException("A geo_point is required; received [{}]", o); | ||
} | ||
return doApply((GeoPoint) o); | ||
} | ||
|
||
R doApply(GeoPoint s); | ||
} | ||
|
||
|
||
private interface GeoShapeFunction<R> { | ||
default R apply(Object o) { | ||
if (!(o instanceof GeoShape)) { | ||
throw new SqlIllegalArgumentException("A geo_shape is required; received [{}]", o); | ||
} | ||
|
||
return doApply((GeoShape) o); | ||
} | ||
|
||
R doApply(GeoShape s); | ||
} | ||
|
||
public enum GeoOperation { | ||
ASWKT_POINT((GeoPoint p) -> new PointBuilder(p.getLon(), p.getLat()).toWKT()), | ||
ASWKT_SHAPE(GeoShape::toString); | ||
|
||
private final Function<Object, Object> apply; | ||
|
||
GeoOperation(GeoPointFunction<Object> apply) { | ||
this.apply = l -> l == null ? null : apply.apply(l); | ||
} | ||
|
||
GeoOperation(GeoShapeFunction<Object> apply) { | ||
this.apply = l -> l == null ? null : apply.apply(l); | ||
} | ||
|
||
public final Object apply(Object l) { | ||
return apply.apply(l); | ||
} | ||
} | ||
|
||
public static final String NAME = "geo"; | ||
|
||
private final GeoOperation processor; | ||
|
||
public GeoProcessor(GeoOperation processor) { | ||
this.processor = processor; | ||
} | ||
|
||
public GeoProcessor(StreamInput in) throws IOException { | ||
processor = in.readEnum(GeoOperation.class); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
out.writeEnum(processor); | ||
} | ||
|
||
@Override | ||
public String getWriteableName() { | ||
return NAME; | ||
} | ||
|
||
@Override | ||
public Object process(Object input) { | ||
return processor.apply(input); | ||
} | ||
|
||
GeoOperation processor() { | ||
return processor; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == null || obj.getClass() != getClass()) { | ||
return false; | ||
} | ||
GeoProcessor other = (GeoProcessor) obj; | ||
return processor == other.processor; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return processor.hashCode(); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return processor.toString(); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
...ql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoShape.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.sql.expression.function.scalar.geo; | ||
|
||
import org.elasticsearch.common.geo.builders.ShapeBuilder; | ||
import org.elasticsearch.common.geo.parsers.ShapeParser; | ||
import org.elasticsearch.common.xcontent.ToXContentFragment; | ||
import org.elasticsearch.common.xcontent.XContentBuilder; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* Wrapper class to represent a GeoShape in SQL | ||
* | ||
* It is required to override the XContent serialization. The ShapeBuilder serializes using GeoJSON by default, | ||
* but in SQL we need the serialization to be WKT-based. | ||
*/ | ||
public class GeoShape implements ToXContentFragment { | ||
|
||
private final ShapeBuilder<?, ?> shapeBuilder; | ||
|
||
public GeoShape(Object value) throws IOException { | ||
shapeBuilder = ShapeParser.parse(value); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return shapeBuilder.toWKT(); | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
return builder.value(shapeBuilder.toWKT()); | ||
} | ||
} |
Oops, something went wrong.