Geo: Allow to parse lat/lon as strings and coerce them
In order to be more failsafe parsing GeoPoints can support lat/lon as strings and coerce them. Added support and test for this.
This commit is contained in:
parent
f6bbc894cf
commit
8b8cd26a59
|
@ -343,16 +343,24 @@ public class GeoUtils {
|
||||||
if(parser.currentToken() == Token.FIELD_NAME) {
|
if(parser.currentToken() == Token.FIELD_NAME) {
|
||||||
String field = parser.text();
|
String field = parser.text();
|
||||||
if(LATITUDE.equals(field)) {
|
if(LATITUDE.equals(field)) {
|
||||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
parser.nextToken();
|
||||||
lat = parser.doubleValue();
|
switch (parser.currentToken()) {
|
||||||
} else {
|
case VALUE_NUMBER:
|
||||||
throw new ElasticsearchParseException("latitude must be a number");
|
case VALUE_STRING:
|
||||||
|
lat = parser.doubleValue(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ElasticsearchParseException("latitude must be a number");
|
||||||
}
|
}
|
||||||
} else if (LONGITUDE.equals(field)) {
|
} else if (LONGITUDE.equals(field)) {
|
||||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
parser.nextToken();
|
||||||
lon = parser.doubleValue();
|
switch (parser.currentToken()) {
|
||||||
} else {
|
case VALUE_NUMBER:
|
||||||
throw new ElasticsearchParseException("latitude must be a number");
|
case VALUE_STRING:
|
||||||
|
lon = parser.doubleValue(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ElasticsearchParseException("longitude must be a number");
|
||||||
}
|
}
|
||||||
} else if (GEOHASH.equals(field)) {
|
} else if (GEOHASH.equals(field)) {
|
||||||
if(parser.nextToken() == Token.VALUE_STRING) {
|
if(parser.nextToken() == Token.VALUE_STRING) {
|
||||||
|
|
|
@ -325,20 +325,28 @@ public class GeolocationContextMapping extends ContextMapping {
|
||||||
final String fieldName = parser.text();
|
final String fieldName = parser.text();
|
||||||
if("lat".equals(fieldName)) {
|
if("lat".equals(fieldName)) {
|
||||||
if(point == null) {
|
if(point == null) {
|
||||||
if (parser.nextToken() == Token.VALUE_NUMBER) {
|
parser.nextToken();
|
||||||
lat = parser.doubleValue();
|
switch (parser.currentToken()) {
|
||||||
} else {
|
case VALUE_NUMBER:
|
||||||
throw new ElasticsearchParseException("latitude must be a number");
|
case VALUE_STRING:
|
||||||
|
lat = parser.doubleValue(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ElasticsearchParseException("latitude must be a number");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ElasticsearchParseException("only lat/lon or [" + FIELD_VALUE + "] is allowed");
|
throw new ElasticsearchParseException("only lat/lon or [" + FIELD_VALUE + "] is allowed");
|
||||||
}
|
}
|
||||||
} else if ("lon".equals(fieldName)) {
|
} else if ("lon".equals(fieldName)) {
|
||||||
if(point == null) {
|
if(point == null) {
|
||||||
if(parser.nextToken() == Token.VALUE_NUMBER) {
|
parser.nextToken();
|
||||||
lon = parser.doubleValue();
|
switch (parser.currentToken()) {
|
||||||
} else {
|
case VALUE_NUMBER:
|
||||||
throw new ElasticsearchParseException("longitude must be a number");
|
case VALUE_STRING:
|
||||||
|
lon = parser.doubleValue(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ElasticsearchParseException("longitude must be a number");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ElasticsearchParseException("only lat/lon or [" + FIELD_VALUE + "] is allowed");
|
throw new ElasticsearchParseException("only lat/lon or [" + FIELD_VALUE + "] is allowed");
|
||||||
|
|
|
@ -26,10 +26,13 @@ import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
|
||||||
import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
|
import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.common.geo.GeoUtils;
|
import org.elasticsearch.common.geo.GeoUtils;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,6 +254,17 @@ public class GeoUtilsTests extends ElasticsearchTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTryParsingLatLonFromString() throws Exception {
|
||||||
|
XContentBuilder builder = jsonBuilder().startObject().field("lat", "52").field("lon", "4").endObject();
|
||||||
|
XContentParser parser = XContentHelper.createParser(builder.bytes());
|
||||||
|
parser.nextToken();
|
||||||
|
GeoPoint geoPoint = GeoUtils.parseGeoPoint(parser);
|
||||||
|
assertThat(geoPoint.lat(), is(52.0));
|
||||||
|
assertThat(geoPoint.lon(), is(4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void assertNormalizedPoint(GeoPoint input, GeoPoint expected) {
|
private static void assertNormalizedPoint(GeoPoint input, GeoPoint expected) {
|
||||||
GeoUtils.normalizePoint(input);
|
GeoUtils.normalizePoint(input);
|
||||||
assertThat(input, equalTo(expected));
|
assertThat(input, equalTo(expected));
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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.search.suggest.context;
|
||||||
|
|
||||||
|
import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.collect.Maps;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GeoLocationContextMappingTest extends ElasticsearchTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThatParsingGeoPointsWorksWithCoercion() throws Exception {
|
||||||
|
XContentBuilder builder = jsonBuilder().startObject().field("lat", "52").field("lon", "4").endObject();
|
||||||
|
XContentParser parser = XContentHelper.createParser(builder.bytes());
|
||||||
|
parser.nextToken();
|
||||||
|
|
||||||
|
GeolocationContextMapping mapping = GeolocationContextMapping.load("foo", Maps.newHashMap());
|
||||||
|
mapping.parseQuery("foo", parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue