Skip to content

Commit 3607876

Browse files
committed
Geo: Makes coordinate validator in libs/geo plugable (#43657)
Moves coordinate validation from Geometry constructors into parser. Relates #43644
1 parent ce8771f commit 3607876

File tree

31 files changed

+472
-216
lines changed

31 files changed

+472
-216
lines changed

libs/geo/src/main/java/org/elasticsearch/geo/geometry/Circle.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ public Circle(final double lat, final double lon, final double alt, final double
4949
if (radiusMeters < 0 ) {
5050
throw new IllegalArgumentException("Circle radius [" + radiusMeters + "] cannot be negative");
5151
}
52-
GeometryUtils.checkLatitude(lat);
53-
GeometryUtils.checkLongitude(lon);
5452
}
5553

5654
@Override

libs/geo/src/main/java/org/elasticsearch/geo/geometry/GeometryUtils.java

Lines changed: 0 additions & 78 deletions
This file was deleted.

libs/geo/src/main/java/org/elasticsearch/geo/geometry/Line.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ public Line(double[] lats, double[] lons, double[] alts) {
5959
if (alts != null && alts.length != lats.length) {
6060
throw new IllegalArgumentException("alts and lats must be equal length");
6161
}
62-
for (int i = 0; i < lats.length; i++) {
63-
GeometryUtils.checkLatitude(lats[i]);
64-
GeometryUtils.checkLongitude(lons[i]);
65-
}
6662
}
6763

6864
public int length() {

libs/geo/src/main/java/org/elasticsearch/geo/geometry/Point.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ public Point(double lat, double lon) {
4242
}
4343

4444
public Point(double lat, double lon, double alt) {
45-
GeometryUtils.checkLatitude(lat);
46-
GeometryUtils.checkLongitude(lon);
4745
this.lat = lat;
4846
this.lon = lon;
4947
this.alt = alt;

libs/geo/src/main/java/org/elasticsearch/geo/geometry/Rectangle.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ public Rectangle(double minLat, double maxLat, double minLon, double maxLon) {
7171
* Constructs a bounding box by first validating the provided latitude and longitude coordinates
7272
*/
7373
public Rectangle(double minLat, double maxLat, double minLon, double maxLon, double minAlt, double maxAlt) {
74-
GeometryUtils.checkLatitude(minLat);
75-
GeometryUtils.checkLatitude(maxLat);
76-
GeometryUtils.checkLongitude(minLon);
77-
GeometryUtils.checkLongitude(maxLon);
7874
this.minLon = minLon;
7975
this.maxLon = maxLon;
8076
this.minLat = minLat;
@@ -90,17 +86,6 @@ public Rectangle(double minLat, double maxLat, double minLon, double maxLon, dou
9086
}
9187
}
9288

93-
public double getWidth() {
94-
if (crossesDateline()) {
95-
return GeometryUtils.MAX_LON_INCL - minLon + maxLon - GeometryUtils.MIN_LON_INCL;
96-
}
97-
return maxLon - minLon;
98-
}
99-
100-
public double getHeight() {
101-
return maxLat - minLat;
102-
}
103-
10489
public double getMinLat() {
10590
return minLat;
10691
}
@@ -156,21 +141,6 @@ public String toString() {
156141
return b.toString();
157142
}
158143

159-
/**
160-
* Returns true if this bounding box crosses the dateline
161-
*/
162-
public boolean crossesDateline() {
163-
return maxLon < minLon;
164-
}
165-
166-
/** returns true if rectangle (defined by minLat, maxLat, minLon, maxLon) contains the lat lon point */
167-
public boolean containsPoint(final double lat, final double lon) {
168-
if (lat >= minLat && lat <= maxLat) {
169-
return crossesDateline() ? lon >= minLon || lon <= maxLon : lon >= minLon && lon <= maxLon;
170-
}
171-
return false;
172-
}
173-
174144
@Override
175145
public boolean equals(Object o) {
176146
if (this == o) return true;
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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.utils;
21+
22+
import org.elasticsearch.geo.geometry.Circle;
23+
import org.elasticsearch.geo.geometry.Geometry;
24+
import org.elasticsearch.geo.geometry.GeometryCollection;
25+
import org.elasticsearch.geo.geometry.GeometryVisitor;
26+
import org.elasticsearch.geo.geometry.Line;
27+
import org.elasticsearch.geo.geometry.LinearRing;
28+
import org.elasticsearch.geo.geometry.MultiLine;
29+
import org.elasticsearch.geo.geometry.MultiPoint;
30+
import org.elasticsearch.geo.geometry.MultiPolygon;
31+
import org.elasticsearch.geo.geometry.Point;
32+
import org.elasticsearch.geo.geometry.Polygon;
33+
import org.elasticsearch.geo.geometry.Rectangle;
34+
35+
/**
36+
* Validator that checks that lats are between -90 and +90 and lons are between -180 and +180 and altitude is present only if
37+
* ignoreZValue is set to true
38+
*/
39+
public class GeographyValidator implements GeometryValidator {
40+
41+
/**
42+
* Minimum longitude value.
43+
*/
44+
private static final double MIN_LON_INCL = -180.0D;
45+
46+
/**
47+
* Maximum longitude value.
48+
*/
49+
private static final double MAX_LON_INCL = 180.0D;
50+
51+
/**
52+
* Minimum latitude value.
53+
*/
54+
private static final double MIN_LAT_INCL = -90.0D;
55+
56+
/**
57+
* Maximum latitude value.
58+
*/
59+
private static final double MAX_LAT_INCL = 90.0D;
60+
61+
private final boolean ignoreZValue;
62+
63+
public GeographyValidator(boolean ignoreZValue) {
64+
this.ignoreZValue = ignoreZValue;
65+
}
66+
67+
/**
68+
* validates latitude value is within standard +/-90 coordinate bounds
69+
*/
70+
protected void checkLatitude(double latitude) {
71+
if (Double.isNaN(latitude) || latitude < MIN_LAT_INCL || latitude > MAX_LAT_INCL) {
72+
throw new IllegalArgumentException(
73+
"invalid latitude " + latitude + "; must be between " + MIN_LAT_INCL + " and " + MAX_LAT_INCL);
74+
}
75+
}
76+
77+
/**
78+
* validates longitude value is within standard +/-180 coordinate bounds
79+
*/
80+
protected void checkLongitude(double longitude) {
81+
if (Double.isNaN(longitude) || longitude < MIN_LON_INCL || longitude > MAX_LON_INCL) {
82+
throw new IllegalArgumentException(
83+
"invalid longitude " + longitude + "; must be between " + MIN_LON_INCL + " and " + MAX_LON_INCL);
84+
}
85+
}
86+
87+
protected void checkAltitude(double zValue) {
88+
if (ignoreZValue == false && Double.isNaN(zValue) == false) {
89+
throw new IllegalArgumentException("found Z value [" + zValue + "] but [ignore_z_value] "
90+
+ "parameter is [" + ignoreZValue + "]");
91+
}
92+
}
93+
94+
@Override
95+
public void validate(Geometry geometry) {
96+
geometry.visit(new GeometryVisitor<Void, RuntimeException>() {
97+
98+
@Override
99+
public Void visit(Circle circle) throws RuntimeException {
100+
checkLatitude(circle.getLat());
101+
checkLongitude(circle.getLon());
102+
checkAltitude(circle.getAlt());
103+
return null;
104+
}
105+
106+
@Override
107+
public Void visit(GeometryCollection<?> collection) throws RuntimeException {
108+
for (Geometry g : collection) {
109+
g.visit(this);
110+
}
111+
return null;
112+
}
113+
114+
@Override
115+
public Void visit(Line line) throws RuntimeException {
116+
for (int i = 0; i < line.length(); i++) {
117+
checkLatitude(line.getLat(i));
118+
checkLongitude(line.getLon(i));
119+
checkAltitude(line.getAlt(i));
120+
}
121+
return null;
122+
}
123+
124+
@Override
125+
public Void visit(LinearRing ring) throws RuntimeException {
126+
for (int i = 0; i < ring.length(); i++) {
127+
checkLatitude(ring.getLat(i));
128+
checkLongitude(ring.getLon(i));
129+
checkAltitude(ring.getAlt(i));
130+
}
131+
return null;
132+
}
133+
134+
@Override
135+
public Void visit(MultiLine multiLine) throws RuntimeException {
136+
return visit((GeometryCollection<?>) multiLine);
137+
}
138+
139+
@Override
140+
public Void visit(MultiPoint multiPoint) throws RuntimeException {
141+
return visit((GeometryCollection<?>) multiPoint);
142+
}
143+
144+
@Override
145+
public Void visit(MultiPolygon multiPolygon) throws RuntimeException {
146+
return visit((GeometryCollection<?>) multiPolygon);
147+
}
148+
149+
@Override
150+
public Void visit(Point point) throws RuntimeException {
151+
checkLatitude(point.getLat());
152+
checkLongitude(point.getLon());
153+
checkAltitude(point.getAlt());
154+
return null;
155+
}
156+
157+
@Override
158+
public Void visit(Polygon polygon) throws RuntimeException {
159+
polygon.getPolygon().visit(this);
160+
for (int i = 0; i < polygon.getNumberOfHoles(); i++) {
161+
polygon.getHole(i).visit(this);
162+
}
163+
return null;
164+
}
165+
166+
@Override
167+
public Void visit(Rectangle rectangle) throws RuntimeException {
168+
checkLatitude(rectangle.getMinLat());
169+
checkLatitude(rectangle.getMaxLat());
170+
checkLongitude(rectangle.getMinLon());
171+
checkLongitude(rectangle.getMaxLon());
172+
checkAltitude(rectangle.getMinAlt());
173+
checkAltitude(rectangle.getMaxAlt());
174+
return null;
175+
}
176+
});
177+
}
178+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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.utils;
21+
22+
import org.elasticsearch.geo.geometry.Geometry;
23+
24+
/**
25+
* Generic geometry validator that can be used by the parser to verify the validity of the parsed geometry
26+
*/
27+
public interface GeometryValidator {
28+
29+
/**
30+
* Validates the geometry and throws IllegalArgumentException if the geometry is not valid
31+
*/
32+
void validate(Geometry geometry);
33+
34+
}

0 commit comments

Comments
 (0)