Skip to content

Commit 6f91f06

Browse files
authored
Geo: Adds a set of no dependency geo classes for JDBC driver (#36477)
Adds a set of geo classes to represent geo data in the JDBC driver and to be used as an intermediate format to pass geo shapes for indexing and query generation in #35320. Relates to #35767 and #35320
1 parent 0b396a0 commit 6f91f06

29 files changed

+2435
-1
lines changed

libs/geo/build.gradle

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* 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+
apply plugin: 'elasticsearch.build'
21+
apply plugin: 'nebula.maven-base-publish'
22+
apply plugin: 'nebula.maven-scm'
23+
24+
dependencies {
25+
if (isEclipse == false || project.path == ":libs:geo-tests") {
26+
testCompile("org.elasticsearch.test:framework:${version}") {
27+
exclude group: 'org.elasticsearch', module: 'elasticsearch-geo'
28+
}
29+
}
30+
}
31+
32+
forbiddenApisMain {
33+
// geo does not depend on server
34+
// TODO: Need to decide how we want to handle for forbidden signatures with the changes to core
35+
replaceSignatureFiles 'jdk-signatures'
36+
}
37+
38+
if (isEclipse) {
39+
// in eclipse the project is under a fake root, we need to change around the source sets
40+
sourceSets {
41+
if (project.path == ":libs:geo") {
42+
main.java.srcDirs = ['java']
43+
main.resources.srcDirs = ['resources']
44+
} else {
45+
test.java.srcDirs = ['java']
46+
test.resources.srcDirs = ['resources']
47+
}
48+
}
49+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* 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+
package org.elasticsearch.geo.geometry;
21+
22+
/**
23+
* Circle geometry (not part of WKT standard, but used in elasticsearch)
24+
*/
25+
public class Circle implements Geometry {
26+
public static final Circle EMPTY = new Circle();
27+
private final double lat;
28+
private final double lon;
29+
private final double radiusMeters;
30+
31+
private Circle() {
32+
lat = 0;
33+
lon = 0;
34+
radiusMeters = -1;
35+
}
36+
37+
public Circle(final double lat, final double lon, final double radiusMeters) {
38+
this.lat = lat;
39+
this.lon = lon;
40+
this.radiusMeters = radiusMeters;
41+
if (radiusMeters < 0 ) {
42+
throw new IllegalArgumentException("Circle radius [" + radiusMeters + "] cannot be negative");
43+
}
44+
GeometryUtils.checkLatitude(lat);
45+
GeometryUtils.checkLongitude(lon);
46+
}
47+
48+
@Override
49+
public ShapeType type() {
50+
return ShapeType.CIRCLE;
51+
}
52+
53+
public double getLat() {
54+
return lat;
55+
}
56+
57+
public double getLon() {
58+
return lon;
59+
}
60+
61+
public double getRadiusMeters() {
62+
return radiusMeters;
63+
}
64+
65+
@Override
66+
public boolean equals(Object o) {
67+
if (this == o) return true;
68+
if (o == null || getClass() != o.getClass()) return false;
69+
70+
Circle circle = (Circle) o;
71+
if (Double.compare(circle.lat, lat) != 0) return false;
72+
if (Double.compare(circle.lon, lon) != 0) return false;
73+
return (Double.compare(circle.radiusMeters, radiusMeters) == 0);
74+
}
75+
76+
@Override
77+
public int hashCode() {
78+
int result;
79+
long temp;
80+
temp = Double.doubleToLongBits(lat);
81+
result = (int) (temp ^ (temp >>> 32));
82+
temp = Double.doubleToLongBits(lon);
83+
result = 31 * result + (int) (temp ^ (temp >>> 32));
84+
temp = Double.doubleToLongBits(radiusMeters);
85+
result = 31 * result + (int) (temp ^ (temp >>> 32));
86+
return result;
87+
}
88+
89+
@Override
90+
public <T> T visit(GeometryVisitor<T> visitor) {
91+
return visitor.visit(this);
92+
}
93+
94+
@Override
95+
public boolean isEmpty() {
96+
return radiusMeters < 0;
97+
}
98+
99+
@Override
100+
public String toString() {
101+
return "lat=" + lat + ", lon=" + lon + ", radius=" + radiusMeters;
102+
}
103+
104+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* 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+
package org.elasticsearch.geo.geometry;
21+
22+
/**
23+
* Base class for all Geometry objects supported by elasticsearch
24+
*/
25+
public interface Geometry {
26+
27+
ShapeType type();
28+
29+
<T> T visit(GeometryVisitor<T> visitor);
30+
31+
boolean isEmpty();
32+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* 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+
package org.elasticsearch.geo.geometry;
20+
21+
import java.util.Collections;
22+
import java.util.Iterator;
23+
import java.util.List;
24+
import java.util.Objects;
25+
26+
/**
27+
* Collection of arbitrary geometry classes
28+
*/
29+
public class GeometryCollection<G extends Geometry> implements Geometry, Iterable<G> {
30+
public static final GeometryCollection<Geometry> EMPTY = new GeometryCollection<>();
31+
32+
private final List<G> shapes;
33+
34+
public GeometryCollection() {
35+
shapes = Collections.emptyList();
36+
}
37+
38+
public GeometryCollection(List<G> shapes) {
39+
if (shapes == null || shapes.isEmpty()) {
40+
throw new IllegalArgumentException("the list of shapes cannot be null or empty");
41+
}
42+
this.shapes = shapes;
43+
}
44+
45+
@Override
46+
public ShapeType type() {
47+
return ShapeType.GEOMETRYCOLLECTION;
48+
}
49+
50+
@Override
51+
public <T> T visit(GeometryVisitor<T> visitor) {
52+
return visitor.visit(this);
53+
}
54+
55+
@Override
56+
public boolean isEmpty() {
57+
return shapes.isEmpty();
58+
}
59+
60+
public int size() {
61+
return shapes.size();
62+
}
63+
64+
public G get(int i) {
65+
return shapes.get(i);
66+
}
67+
68+
@Override
69+
public boolean equals(Object o) {
70+
if (this == o) return true;
71+
if (o == null || getClass() != o.getClass()) return false;
72+
GeometryCollection<?> that = (GeometryCollection<?>) o;
73+
return Objects.equals(shapes, that.shapes);
74+
}
75+
76+
@Override
77+
public int hashCode() {
78+
return Objects.hash(shapes);
79+
}
80+
81+
@Override
82+
public Iterator<G> iterator() {
83+
return shapes.iterator();
84+
}
85+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* 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+
package org.elasticsearch.geo.geometry;
21+
22+
/**
23+
* Geometry-related utility methods
24+
*/
25+
final class GeometryUtils {
26+
/**
27+
* Minimum longitude value.
28+
*/
29+
static final double MIN_LON_INCL = -180.0D;
30+
31+
/**
32+
* Maximum longitude value.
33+
*/
34+
static final double MAX_LON_INCL = 180.0D;
35+
36+
/**
37+
* Minimum latitude value.
38+
*/
39+
static final double MIN_LAT_INCL = -90.0D;
40+
41+
/**
42+
* Maximum latitude value.
43+
*/
44+
static final double MAX_LAT_INCL = 90.0D;
45+
46+
// No instance:
47+
private GeometryUtils() {
48+
}
49+
50+
/**
51+
* validates latitude value is within standard +/-90 coordinate bounds
52+
*/
53+
static void checkLatitude(double latitude) {
54+
if (Double.isNaN(latitude) || latitude < MIN_LAT_INCL || latitude > MAX_LAT_INCL) {
55+
throw new IllegalArgumentException(
56+
"invalid latitude " + latitude + "; must be between " + MIN_LAT_INCL + " and " + MAX_LAT_INCL);
57+
}
58+
}
59+
60+
/**
61+
* validates longitude value is within standard +/-180 coordinate bounds
62+
*/
63+
static void checkLongitude(double longitude) {
64+
if (Double.isNaN(longitude) || longitude < MIN_LON_INCL || longitude > MAX_LON_INCL) {
65+
throw new IllegalArgumentException(
66+
"invalid longitude " + longitude + "; must be between " + MIN_LON_INCL + " and " + MAX_LON_INCL);
67+
}
68+
}
69+
70+
}

0 commit comments

Comments
 (0)