Add exceptions to `GeoPointFieldMapper` when parsing `geo_point` object
* moved `geo_point` parsing to GeoUtils * cleaned up `gzipped.json` for bulktest * merged `GeoPointFieldMapper` and `GeoPoint` parsing methods Closes #5390
This commit is contained in:
parent
12d1bf8485
commit
689fd15d78
|
@ -19,22 +19,12 @@
|
|||
|
||||
package org.elasticsearch.common.geo;
|
||||
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class GeoPoint {
|
||||
|
||||
public static final String LATITUDE = GeoPointFieldMapper.Names.LAT;
|
||||
public static final String LONGITUDE = GeoPointFieldMapper.Names.LON;
|
||||
public static final String GEOHASH = GeoPointFieldMapper.Names.GEOHASH;
|
||||
|
||||
private double lat;
|
||||
private double lon;
|
||||
|
||||
|
@ -150,98 +140,4 @@ public final class GeoPoint {
|
|||
point.resetFromString(latLon);
|
||||
return point;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a {@link GeoPoint} with a {@link XContentParser}:
|
||||
*
|
||||
* @param parser {@link XContentParser} to parse the value from
|
||||
* @return new {@link GeoPoint} parsed from the parse
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws org.elasticsearch.ElasticsearchParseException
|
||||
*/
|
||||
public static GeoPoint parse(XContentParser parser) throws IOException, ElasticsearchParseException {
|
||||
return parse(parser, new GeoPoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a {@link GeoPoint} with a {@link XContentParser}. A geopoint has one of the following forms:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Object: <pre>{"lat": <i><latitude></i>, "lon": <i><longitude></i>}</pre></li>
|
||||
* <li>String: <pre>"<i><latitude></i>,<i><longitude></i>"</pre></li>
|
||||
* <li>Geohash: <pre>"<i><geohash></i>"</pre></li>
|
||||
* <li>Array: <pre>[<i><longitude></i>,<i><latitude></i>]</pre></li>
|
||||
* </ul>
|
||||
*
|
||||
* @param parser {@link XContentParser} to parse the value from
|
||||
* @param point A {@link GeoPoint} that will be reset by the values parsed
|
||||
* @return new {@link GeoPoint} parsed from the parse
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws org.elasticsearch.ElasticsearchParseException
|
||||
*/
|
||||
public static GeoPoint parse(XContentParser parser, GeoPoint point) throws IOException, ElasticsearchParseException {
|
||||
if(parser.currentToken() == Token.START_OBJECT) {
|
||||
while(parser.nextToken() != Token.END_OBJECT) {
|
||||
if(parser.currentToken() == Token.FIELD_NAME) {
|
||||
String field = parser.text();
|
||||
if(LATITUDE.equals(field)) {
|
||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
||||
point.resetLat(parser.doubleValue());
|
||||
} else {
|
||||
throw new ElasticsearchParseException("latitude must be a number");
|
||||
}
|
||||
} else if (LONGITUDE.equals(field)) {
|
||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
||||
point.resetLon(parser.doubleValue());
|
||||
} else {
|
||||
throw new ElasticsearchParseException("latitude must be a number");
|
||||
}
|
||||
} else if (GEOHASH.equals(field)) {
|
||||
if(parser.nextToken() == Token.VALUE_STRING) {
|
||||
point.resetFromGeoHash(parser.text());
|
||||
} else {
|
||||
throw new ElasticsearchParseException("geohash must be a string");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("field must be either '" + LATITUDE + "', '" + LONGITUDE + "' or '" + GEOHASH + "'");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("Token '"+parser.currentToken()+"' not allowed");
|
||||
}
|
||||
}
|
||||
return point;
|
||||
} else if(parser.currentToken() == Token.START_ARRAY) {
|
||||
int element = 0;
|
||||
while(parser.nextToken() != Token.END_ARRAY) {
|
||||
if(parser.currentToken() == Token.VALUE_NUMBER) {
|
||||
element++;
|
||||
if(element == 1) {
|
||||
point.resetLon(parser.doubleValue());
|
||||
} else if(element == 2) {
|
||||
point.resetLat(parser.doubleValue());
|
||||
} else {
|
||||
throw new ElasticsearchParseException("only two values allowed");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("Numeric value expected");
|
||||
}
|
||||
}
|
||||
return point;
|
||||
} else if(parser.currentToken() == Token.VALUE_STRING) {
|
||||
String data = parser.text();
|
||||
int comma = data.indexOf(',');
|
||||
if(comma > 0) {
|
||||
double lat = Double.parseDouble(data.substring(0, comma).trim());
|
||||
double lon = Double.parseDouble(data.substring(comma + 1).trim());
|
||||
return point.reset(lat, lon);
|
||||
} else {
|
||||
point.resetFromGeoHash(data);
|
||||
return point;
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("geo_point expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,22 @@ package org.elasticsearch.common.geo;
|
|||
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
|
||||
import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
|
||||
import org.apache.lucene.util.SloppyMath;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class GeoUtils {
|
||||
|
||||
public static final String LATITUDE = GeoPointFieldMapper.Names.LAT;
|
||||
public static final String LONGITUDE = GeoPointFieldMapper.Names.LON;
|
||||
public static final String GEOHASH = GeoPointFieldMapper.Names.GEOHASH;
|
||||
|
||||
/** Earth ellipsoid major axis defined by WGS 84 in meters */
|
||||
public static final double EARTH_SEMI_MAJOR_AXIS = 6378137.0; // meters (WGS 84)
|
||||
|
||||
|
@ -293,5 +303,114 @@ public class GeoUtils {
|
|||
}
|
||||
return rtn;
|
||||
}
|
||||
/**
|
||||
* Parse a {@link GeoPoint} with a {@link XContentParser}:
|
||||
*
|
||||
* @param parser {@link XContentParser} to parse the value from
|
||||
* @return new {@link GeoPoint} parsed from the parse
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws org.elasticsearch.ElasticsearchParseException
|
||||
*/
|
||||
public static GeoPoint parseGeoPoint(XContentParser parser) throws IOException, ElasticsearchParseException {
|
||||
return parseGeoPoint(parser, new GeoPoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a {@link GeoPoint} with a {@link XContentParser}. A geopoint has one of the following forms:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Object: <pre>{"lat": <i><latitude></i>, "lon": <i><longitude></i>}</pre></li>
|
||||
* <li>String: <pre>"<i><latitude></i>,<i><longitude></i>"</pre></li>
|
||||
* <li>Geohash: <pre>"<i><geohash></i>"</pre></li>
|
||||
* <li>Array: <pre>[<i><longitude></i>,<i><latitude></i>]</pre></li>
|
||||
* </ul>
|
||||
*
|
||||
* @param parser {@link XContentParser} to parse the value from
|
||||
* @param point A {@link GeoPoint} that will be reset by the values parsed
|
||||
* @return new {@link GeoPoint} parsed from the parse
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws org.elasticsearch.ElasticsearchParseException
|
||||
*/
|
||||
public static GeoPoint parseGeoPoint(XContentParser parser, GeoPoint point) throws IOException, ElasticsearchParseException {
|
||||
double lat = Double.NaN;
|
||||
double lon = Double.NaN;
|
||||
String geohash = null;
|
||||
|
||||
if(parser.currentToken() == Token.START_OBJECT) {
|
||||
while(parser.nextToken() != Token.END_OBJECT) {
|
||||
if(parser.currentToken() == Token.FIELD_NAME) {
|
||||
String field = parser.text();
|
||||
if(LATITUDE.equals(field)) {
|
||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
||||
lat = parser.doubleValue();
|
||||
} else {
|
||||
throw new ElasticsearchParseException("latitude must be a number");
|
||||
}
|
||||
} else if (LONGITUDE.equals(field)) {
|
||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
||||
lon = parser.doubleValue();
|
||||
} else {
|
||||
throw new ElasticsearchParseException("latitude must be a number");
|
||||
}
|
||||
} else if (GEOHASH.equals(field)) {
|
||||
if(parser.nextToken() == Token.VALUE_STRING) {
|
||||
geohash = parser.text();
|
||||
} else {
|
||||
throw new ElasticsearchParseException("geohash must be a string");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("field must be either '" + LATITUDE + "', '" + LONGITUDE + "' or '" + GEOHASH + "'");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("Token '"+parser.currentToken()+"' not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
if (geohash != null) {
|
||||
if(!Double.isNaN(lat) || !Double.isNaN(lon)) {
|
||||
throw new ElasticsearchParseException("field must be either lat/lon or geohash");
|
||||
} else {
|
||||
return point.resetFromGeoHash(geohash);
|
||||
}
|
||||
} else if (Double.isNaN(lat)) {
|
||||
throw new ElasticsearchParseException("field [" + LATITUDE + "] missing");
|
||||
} else if (Double.isNaN(lon)) {
|
||||
throw new ElasticsearchParseException("field [" + LONGITUDE + "] missing");
|
||||
} else {
|
||||
return point.reset(lat, lon);
|
||||
}
|
||||
|
||||
} else if(parser.currentToken() == Token.START_ARRAY) {
|
||||
int element = 0;
|
||||
while(parser.nextToken() != Token.END_ARRAY) {
|
||||
if(parser.currentToken() == Token.VALUE_NUMBER) {
|
||||
element++;
|
||||
if(element == 1) {
|
||||
lon = parser.doubleValue();
|
||||
} else if(element == 2) {
|
||||
lat = parser.doubleValue();
|
||||
} else {
|
||||
throw new ElasticsearchParseException("only two values allowed");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("Numeric value expected");
|
||||
}
|
||||
}
|
||||
return point.reset(lat, lon);
|
||||
} else if(parser.currentToken() == Token.VALUE_STRING) {
|
||||
String data = parser.text();
|
||||
int comma = data.indexOf(',');
|
||||
if(comma > 0) {
|
||||
lat = Double.parseDouble(data.substring(0, comma).trim());
|
||||
lon = Double.parseDouble(data.substring(comma + 1).trim());
|
||||
return point.reset(lat, lon);
|
||||
} else {
|
||||
return point.resetFromGeoHash(data);
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("geo_point expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,9 +57,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.MapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
|
||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
|
||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parsePathType;
|
||||
import static org.elasticsearch.index.mapper.core.TypeParsers.*;
|
||||
|
||||
/**
|
||||
* Parsing: We handle:
|
||||
|
@ -488,24 +486,19 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
|
|||
context.path().pathType(pathType);
|
||||
context.path().add(name());
|
||||
|
||||
GeoPoint value = context.parseExternalValue(GeoPoint.class);
|
||||
if (value != null) {
|
||||
parseLatLon(context, value.lat(), value.lon());
|
||||
GeoPoint sparse = context.parseExternalValue(GeoPoint.class);
|
||||
|
||||
if (sparse != null) {
|
||||
parse(context, sparse, null);
|
||||
} else {
|
||||
sparse = new GeoPoint();
|
||||
XContentParser.Token token = context.parser().currentToken();
|
||||
if (token == XContentParser.Token.START_ARRAY) {
|
||||
token = context.parser().nextToken();
|
||||
if (token == XContentParser.Token.START_ARRAY) {
|
||||
// its an array of array of lon/lat [ [1.2, 1.3], [1.4, 1.5] ]
|
||||
while (token != XContentParser.Token.END_ARRAY) {
|
||||
token = context.parser().nextToken();
|
||||
double lon = context.parser().doubleValue();
|
||||
token = context.parser().nextToken();
|
||||
double lat = context.parser().doubleValue();
|
||||
while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
|
||||
}
|
||||
parseLatLon(context, lat, lon);
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
token = context.parser().nextToken();
|
||||
}
|
||||
} else {
|
||||
|
@ -517,22 +510,22 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
|
|||
while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
|
||||
}
|
||||
parseLatLon(context, lat, lon);
|
||||
parse(context, sparse.reset(lat, lon), null);
|
||||
} else {
|
||||
while (token != XContentParser.Token.END_ARRAY) {
|
||||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
parseObjectLatLon(context);
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
parseStringLatLon(context);
|
||||
if (token == XContentParser.Token.VALUE_STRING) {
|
||||
parsePointFromString(context, sparse, context.parser().text());
|
||||
} else {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
}
|
||||
token = context.parser().nextToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
parseObjectLatLon(context);
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
parseStringLatLon(context);
|
||||
parsePointFromString(context, sparse, context.parser().text());
|
||||
} else {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,44 +533,6 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
|
|||
context.path().pathType(origPathType);
|
||||
}
|
||||
|
||||
private void parseStringLatLon(ParseContext context) throws IOException {
|
||||
String value = context.parser().text();
|
||||
int comma = value.indexOf(',');
|
||||
if (comma != -1) {
|
||||
double lat = Double.parseDouble(value.substring(0, comma).trim());
|
||||
double lon = Double.parseDouble(value.substring(comma + 1).trim());
|
||||
parseLatLon(context, lat, lon);
|
||||
} else { // geo hash
|
||||
parseGeohash(context, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseObjectLatLon(ParseContext context) throws IOException {
|
||||
XContentParser.Token token;
|
||||
String currentName = context.parser().currentName();
|
||||
Double lat = null;
|
||||
Double lon = null;
|
||||
String geohash = null;
|
||||
while ((token = context.parser().nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentName = context.parser().currentName();
|
||||
} else if (token.isValue()) {
|
||||
if (currentName.equals(Names.LAT)) {
|
||||
lat = context.parser().doubleValue();
|
||||
} else if (currentName.equals(Names.LON)) {
|
||||
lon = context.parser().doubleValue();
|
||||
} else if (currentName.equals(Names.GEOHASH)) {
|
||||
geohash = context.parser().text();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (geohash != null) {
|
||||
parseGeohash(context, geohash);
|
||||
} else if (lat != null && lon != null) {
|
||||
parseLatLon(context, lat, lon);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGeohashField(ParseContext context, String geohash) throws IOException {
|
||||
int len = Math.min(geoHashPrecision, geohash.length());
|
||||
int min = enableGeohashPrefix ? 1 : geohash.length();
|
||||
|
@ -589,13 +544,12 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
|
|||
}
|
||||
}
|
||||
|
||||
private void parseLatLon(ParseContext context, double lat, double lon) throws IOException {
|
||||
parse(context, new GeoPoint(lat, lon), null);
|
||||
}
|
||||
|
||||
private void parseGeohash(ParseContext context, String geohash) throws IOException {
|
||||
GeoPoint point = GeoHashUtils.decode(geohash);
|
||||
parse(context, point, geohash);
|
||||
private void parsePointFromString(ParseContext context, GeoPoint sparse, String point) throws IOException {
|
||||
if (point.indexOf(',') < 0) {
|
||||
parse(context, sparse.resetFromGeoHash(point), point);
|
||||
} else {
|
||||
parse(context, sparse.resetFromString(point), null);
|
||||
}
|
||||
}
|
||||
|
||||
private void parse(ParseContext context, GeoPoint point, String geohash) throws IOException {
|
||||
|
|
|
@ -113,19 +113,19 @@ public class GeoBoundingBoxFilterParser implements FilterParser {
|
|||
right = parser.doubleValue();
|
||||
} else {
|
||||
if (TOP_LEFT.equals(currentFieldName) || TOPLEFT.equals(currentFieldName)) {
|
||||
GeoPoint.parse(parser, sparse);
|
||||
GeoUtils.parseGeoPoint(parser, sparse);
|
||||
top = sparse.getLat();
|
||||
left = sparse.getLon();
|
||||
} else if (BOTTOM_RIGHT.equals(currentFieldName) || BOTTOMRIGHT.equals(currentFieldName)) {
|
||||
GeoPoint.parse(parser, sparse);
|
||||
GeoUtils.parseGeoPoint(parser, sparse);
|
||||
bottom = sparse.getLat();
|
||||
right = sparse.getLon();
|
||||
} else if (TOP_RIGHT.equals(currentFieldName) || TOPRIGHT.equals(currentFieldName)) {
|
||||
GeoPoint.parse(parser, sparse);
|
||||
GeoUtils.parseGeoPoint(parser, sparse);
|
||||
top = sparse.getLat();
|
||||
right = sparse.getLon();
|
||||
} else if (BOTTOM_LEFT.equals(currentFieldName) || BOTTOMLEFT.equals(currentFieldName)) {
|
||||
GeoPoint.parse(parser, sparse);
|
||||
GeoUtils.parseGeoPoint(parser, sparse);
|
||||
bottom = sparse.getLat();
|
||||
left = sparse.getLon();
|
||||
} else {
|
||||
|
|
|
@ -83,7 +83,7 @@ public class GeoDistanceFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
fieldName = currentFieldName;
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
// the json in the format of -> field : { lat : 30, lon : 12 }
|
||||
String currentName = parser.currentName();
|
||||
|
|
|
@ -84,12 +84,12 @@ public class GeoDistanceRangeFilterParser implements FilterParser {
|
|||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
fieldName = currentFieldName;
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
// the json in the format of -> field : { lat : 30, lon : 12 }
|
||||
fieldName = currentFieldName;
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
} else if (token.isValue()) {
|
||||
if (currentFieldName.equals("from")) {
|
||||
if (token == XContentParser.Token.VALUE_NULL) {
|
||||
|
|
|
@ -93,7 +93,7 @@ public class GeoPolygonFilterParser implements FilterParser {
|
|||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if (POINTS.equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != Token.END_ARRAY) {
|
||||
shell.add(GeoPoint.parse(parser));
|
||||
shell.add(GeoUtils.parseGeoPoint(parser));
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]");
|
||||
|
|
|
@ -217,12 +217,12 @@ public class GeohashCellFilter {
|
|||
// A string indicates either a gehash or a lat/lon string
|
||||
String location = parser.text();
|
||||
if(location.indexOf(",")>0) {
|
||||
geohash = GeoPoint.parse(parser).geohash();
|
||||
geohash = GeoUtils.parseGeoPoint(parser).geohash();
|
||||
} else {
|
||||
geohash = location;
|
||||
}
|
||||
} else {
|
||||
geohash = GeoPoint.parse(parser).geohash();
|
||||
geohash = GeoUtils.parseGeoPoint(parser).geohash();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
|||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.lucene.search.function.CombineFunction;
|
||||
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
|
@ -206,7 +207,7 @@ public abstract class DecayFunctionParser implements ScoreFunctionParser {
|
|||
} else if (parameterName.equals(DecayFunctionBuilder.SCALE)) {
|
||||
scaleString = parser.text();
|
||||
} else if (parameterName.equals(DecayFunctionBuilder.ORIGIN)) {
|
||||
origin = GeoPoint.parse(parser);
|
||||
origin = GeoUtils.parseGeoPoint(parser);
|
||||
} else if (parameterName.equals(DecayFunctionBuilder.DECAY)) {
|
||||
decay = parser.doubleValue();
|
||||
} else if (parameterName.equals(DecayFunctionBuilder.OFFSET)) {
|
||||
|
|
|
@ -109,7 +109,7 @@ public class GeoDistanceFacetParser extends AbstractComponent implements FacetPa
|
|||
entries.add(new GeoDistanceFacet.Entry(from, to, 0, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
|
||||
}
|
||||
} else {
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
fieldName = currentName;
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
|
@ -118,7 +118,7 @@ public class GeoDistanceFacetParser extends AbstractComponent implements FacetPa
|
|||
} else {
|
||||
// the json in the format of -> field : { lat : 30, lon : 12 }
|
||||
fieldName = currentName;
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if (currentName.equals("unit")) {
|
||||
|
|
|
@ -69,7 +69,7 @@ public class GeoDistanceSortParser implements SortParser {
|
|||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
fieldName = currentName;
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
// the json in the format of -> field : { lat : 30, lon : 12 }
|
||||
|
@ -78,7 +78,7 @@ public class GeoDistanceSortParser implements SortParser {
|
|||
nestedFilter = parsedFilter == null ? null : parsedFilter.filter();
|
||||
} else {
|
||||
fieldName = currentName;
|
||||
GeoPoint.parse(parser, point);
|
||||
GeoUtils.parseGeoPoint(parser, point);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if ("reverse".equals(currentName)) {
|
||||
|
|
|
@ -210,13 +210,13 @@ public class GeolocationContextMapping extends ContextMapping {
|
|||
// otherwise it's a list of locations
|
||||
ArrayList<String> result = Lists.newArrayList();
|
||||
while (token != Token.END_ARRAY) {
|
||||
result.add(GeoPoint.parse(parser).geohash());
|
||||
result.add(GeoUtils.parseGeoPoint(parser).geohash());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
// or a single location
|
||||
return Collections.singleton(GeoPoint.parse(parser).geohash());
|
||||
return Collections.singleton(GeoUtils.parseGeoPoint(parser).geohash());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,8 +337,8 @@ public class GeolocationContextMapping extends ContextMapping {
|
|||
precision = new int[] { parsePrecision(parser) };
|
||||
}
|
||||
} else if (FIELD_VALUE.equals(fieldName)) {
|
||||
if(lat == Double.NaN && lon == Double.NaN) {
|
||||
point = GeoPoint.parse(parser);
|
||||
if(Double.isNaN(lon) && Double.isNaN(lat)) {
|
||||
point = GeoUtils.parseGeoPoint(parser);
|
||||
} else {
|
||||
throw new ElasticsearchParseException("only lat/lon or [" + FIELD_VALUE + "] is allowed");
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ public class GeolocationContextMapping extends ContextMapping {
|
|||
}
|
||||
|
||||
if (point == null) {
|
||||
if (lat == Double.NaN || lon == Double.NaN) {
|
||||
if (Double.isNaN(lat) || Double.isNaN(lon)) {
|
||||
throw new ElasticsearchParseException("location is missing");
|
||||
} else {
|
||||
point = new GeoPoint(lat, lon);
|
||||
|
@ -357,7 +357,7 @@ public class GeolocationContextMapping extends ContextMapping {
|
|||
|
||||
return new GeoQuery(name, point.geohash(), precision);
|
||||
} else {
|
||||
return new GeoQuery(name, GeoPoint.parse(parser).getGeohash(), precision);
|
||||
return new GeoQuery(name, GeoUtils.parseGeoPoint(parser).getGeohash(), precision);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.search.geo;
|
||||
|
||||
|
||||
import org.elasticsearch.common.geo.GeoHashUtils;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.closeTo;
|
||||
|
||||
|
||||
public class GeoPointParsingTests extends ElasticsearchTestCase {
|
||||
|
||||
// mind geohash precision and error
|
||||
private static final double ERROR = 0.00001d;
|
||||
|
||||
@Test
|
||||
public void testGeoPointReset() throws IOException {
|
||||
double lat = 1 + randomDouble() * 89;
|
||||
double lon = 1 + randomDouble() * 179;
|
||||
|
||||
GeoPoint point = new GeoPoint(0, 0);
|
||||
assertCloseTo(point, 0, 0);
|
||||
|
||||
assertCloseTo(point.reset(lat, lon), lat, lon);
|
||||
assertCloseTo(point.reset(0, 0), 0, 0);
|
||||
assertCloseTo(point.resetLat(lat), lat, 0);
|
||||
assertCloseTo(point.resetLat(0), 0, 0);
|
||||
assertCloseTo(point.resetLon(lon), 0, lon);
|
||||
assertCloseTo(point.resetLon(0), 0, 0);
|
||||
assertCloseTo(point.resetFromGeoHash(GeoHashUtils.encode(lat, lon)), lat, lon);
|
||||
assertCloseTo(point.reset(0, 0), 0, 0);
|
||||
assertCloseTo(point.resetFromString(Double.toString(lat) + ", " + Double.toHexString(lon)), lat, lon);
|
||||
assertCloseTo(point.reset(0, 0), 0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoPointParsing() throws IOException {
|
||||
double lat = randomDouble() * 180 - 90;
|
||||
double lon = randomDouble() * 360 - 180;
|
||||
|
||||
GeoPoint point = GeoUtils.parseGeoPoint(objectLatLon(lat, lon));
|
||||
assertCloseTo(point, lat, lon);
|
||||
|
||||
GeoUtils.parseGeoPoint(arrayLatLon(lat, lon), point);
|
||||
assertCloseTo(point, lat, lon);
|
||||
|
||||
GeoUtils.parseGeoPoint(geohash(lat, lon), point);
|
||||
assertCloseTo(point, lat, lon);
|
||||
|
||||
GeoUtils.parseGeoPoint(stringLatLon(lat, lon), point);
|
||||
assertCloseTo(point, lat, lon);
|
||||
}
|
||||
|
||||
// Based on issue5390
|
||||
@Test
|
||||
public void testInvalidPointEmbeddedObject() throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.startObject();
|
||||
content.startObject("location");
|
||||
content.field("lat", 0).field("lon", 0);
|
||||
content.endObject();
|
||||
content.endObject();
|
||||
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
|
||||
try {
|
||||
GeoUtils.parseGeoPoint(parser);
|
||||
assertTrue(false);
|
||||
} catch (Throwable e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidPointLatHashMix() throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.startObject();
|
||||
content.field("lat", 0).field("geohash", GeoHashUtils.encode(0, 0));
|
||||
content.endObject();
|
||||
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
|
||||
try {
|
||||
GeoUtils.parseGeoPoint(parser);
|
||||
assertTrue(false);
|
||||
} catch (Throwable e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidPointLonHashMix() throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.startObject();
|
||||
content.field("lon", 0).field("geohash", GeoHashUtils.encode(0, 0));
|
||||
content.endObject();
|
||||
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
|
||||
try {
|
||||
GeoUtils.parseGeoPoint(parser);
|
||||
assertTrue(false);
|
||||
} catch (Throwable e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidField() throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.startObject();
|
||||
content.field("lon", 0).field("lat", 0).field("test", 0);
|
||||
content.endObject();
|
||||
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
|
||||
try {
|
||||
GeoUtils.parseGeoPoint(parser);
|
||||
assertTrue(false);
|
||||
} catch (Throwable e) {}
|
||||
}
|
||||
|
||||
private static XContentParser objectLatLon(double lat, double lon) throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.startObject();
|
||||
content.field("lat", lat).field("lon", lon);
|
||||
content.endObject();
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
return parser;
|
||||
}
|
||||
|
||||
private static XContentParser arrayLatLon(double lat, double lon) throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.startArray().value(lon).value(lat).endArray();
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
return parser;
|
||||
}
|
||||
|
||||
private static XContentParser stringLatLon(double lat, double lon) throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.value(Double.toString(lat) + ", " + Double.toString(lon));
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
return parser;
|
||||
}
|
||||
|
||||
private static XContentParser geohash(double lat, double lon) throws IOException {
|
||||
XContentBuilder content = JsonXContent.contentBuilder();
|
||||
content.value(GeoHashUtils.encode(lat, lon));
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(content.bytes());
|
||||
parser.nextToken();
|
||||
return parser;
|
||||
}
|
||||
|
||||
public static void assertCloseTo(GeoPoint point, double lat, double lon) {
|
||||
assertThat(point.lat(), closeTo(lat, ERROR));
|
||||
assertThat(point.lon(), closeTo(lon, ERROR));
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
|
@ -668,11 +668,9 @@ public class SimpleSortTests extends ElasticsearchIntegrationTest {
|
|||
.field("lvalue", new long[]{i, i + 1, i + 2})
|
||||
.field("dvalue", new double[]{i, i + 1, i + 2})
|
||||
.startObject("gvalue")
|
||||
.startObject("location")
|
||||
.field("lat", (double) i + 1)
|
||||
.field("lon", (double) i)
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject());
|
||||
req.execute().actionGet();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue