use of org.opensearch.common.xcontent.XContentSubParser in project OpenSearch by opensearch-project.
the class GeoUtils method parseGeoPoint.
/**
* 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
*/
public static GeoPoint parseGeoPoint(XContentParser parser, GeoPoint point, final boolean ignoreZValue, EffectivePoint effectivePoint) throws IOException, OpenSearchParseException {
double lat = Double.NaN;
double lon = Double.NaN;
String geohash = null;
NumberFormatException numberFormatException = null;
if (parser.currentToken() == Token.START_OBJECT) {
try (XContentSubParser subParser = new XContentSubParser(parser)) {
while (subParser.nextToken() != Token.END_OBJECT) {
if (subParser.currentToken() == Token.FIELD_NAME) {
String field = subParser.currentName();
if (LATITUDE.equals(field)) {
subParser.nextToken();
switch(subParser.currentToken()) {
case VALUE_NUMBER:
case VALUE_STRING:
try {
lat = subParser.doubleValue(true);
} catch (NumberFormatException e) {
numberFormatException = e;
}
break;
default:
throw new OpenSearchParseException("latitude must be a number");
}
} else if (LONGITUDE.equals(field)) {
subParser.nextToken();
switch(subParser.currentToken()) {
case VALUE_NUMBER:
case VALUE_STRING:
try {
lon = subParser.doubleValue(true);
} catch (NumberFormatException e) {
numberFormatException = e;
}
break;
default:
throw new OpenSearchParseException("longitude must be a number");
}
} else if (GEOHASH.equals(field)) {
if (subParser.nextToken() == Token.VALUE_STRING) {
geohash = subParser.text();
} else {
throw new OpenSearchParseException("geohash must be a string");
}
} else {
throw new OpenSearchParseException("field must be either [{}], [{}] or [{}]", LATITUDE, LONGITUDE, GEOHASH);
}
} else {
throw new OpenSearchParseException("token [{}] not allowed", subParser.currentToken());
}
}
}
if (geohash != null) {
if (!Double.isNaN(lat) || !Double.isNaN(lon)) {
throw new OpenSearchParseException("field must be either lat/lon or geohash");
} else {
return point.parseGeoHash(geohash, effectivePoint);
}
} else if (numberFormatException != null) {
throw new OpenSearchParseException("[{}] and [{}] must be valid double values", numberFormatException, LATITUDE, LONGITUDE);
} else if (Double.isNaN(lat)) {
throw new OpenSearchParseException("field [{}] missing", LATITUDE);
} else if (Double.isNaN(lon)) {
throw new OpenSearchParseException("field [{}] missing", LONGITUDE);
} else {
return point.reset(lat, lon);
}
} else if (parser.currentToken() == Token.START_ARRAY) {
try (XContentSubParser subParser = new XContentSubParser(parser)) {
int element = 0;
while (subParser.nextToken() != Token.END_ARRAY) {
if (subParser.currentToken() == Token.VALUE_NUMBER) {
element++;
if (element == 1) {
lon = subParser.doubleValue();
} else if (element == 2) {
lat = subParser.doubleValue();
} else if (element == 3) {
GeoPoint.assertZValue(ignoreZValue, subParser.doubleValue());
} else {
throw new OpenSearchParseException("[geo_point] field type does not accept > 3 dimensions");
}
} else {
throw new OpenSearchParseException("numeric value expected");
}
}
}
return point.reset(lat, lon);
} else if (parser.currentToken() == Token.VALUE_STRING) {
String val = parser.text();
return point.resetFromString(val, ignoreZValue, effectivePoint);
} else {
throw new OpenSearchParseException("geo_point expected");
}
}
use of org.opensearch.common.xcontent.XContentSubParser in project OpenSearch by opensearch-project.
the class GeoJson method fromXContent.
public Geometry fromXContent(XContentParser parser) throws IOException {
try (XContentSubParser subParser = new XContentSubParser(parser)) {
Geometry geometry = PARSER.apply(subParser, this);
validator.validate(geometry);
return geometry;
}
}
use of org.opensearch.common.xcontent.XContentSubParser in project OpenSearch by opensearch-project.
the class GeoJsonParser method parse.
protected static ShapeBuilder parse(XContentParser parser, AbstractShapeGeometryFieldMapper shapeMapper) throws IOException {
GeoShapeType shapeType = null;
DistanceUnit.Distance radius = null;
CoordinateNode coordinateNode = null;
GeometryCollectionBuilder geometryCollections = null;
Orientation orientation = (shapeMapper == null) ? AbstractShapeGeometryFieldMapper.Defaults.ORIENTATION.value() : shapeMapper.orientation();
Explicit<Boolean> coerce = (shapeMapper == null) ? AbstractShapeGeometryFieldMapper.Defaults.COERCE : shapeMapper.coerce();
Explicit<Boolean> ignoreZValue = (shapeMapper == null) ? AbstractShapeGeometryFieldMapper.Defaults.IGNORE_Z_VALUE : shapeMapper.ignoreZValue();
String malformedException = null;
XContentParser.Token token;
try (XContentParser subParser = new XContentSubParser(parser)) {
while ((token = subParser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
String fieldName = subParser.currentName();
if (ShapeParser.FIELD_TYPE.match(fieldName, subParser.getDeprecationHandler())) {
subParser.nextToken();
final GeoShapeType type = GeoShapeType.forName(subParser.text());
if (shapeType != null && shapeType.equals(type) == false) {
malformedException = ShapeParser.FIELD_TYPE + " already parsed as [" + shapeType + "] cannot redefine as [" + type + "]";
} else {
shapeType = type;
}
} else if (ShapeParser.FIELD_COORDINATES.match(fieldName, subParser.getDeprecationHandler())) {
subParser.nextToken();
CoordinateNode tempNode = parseCoordinates(subParser, ignoreZValue.value());
if (coordinateNode != null && tempNode.numDimensions() != coordinateNode.numDimensions()) {
throw new OpenSearchParseException("Exception parsing coordinates: " + "number of dimensions do not match");
}
coordinateNode = tempNode;
} else if (ShapeParser.FIELD_GEOMETRIES.match(fieldName, subParser.getDeprecationHandler())) {
if (shapeType == null) {
shapeType = GeoShapeType.GEOMETRYCOLLECTION;
} else if (shapeType.equals(GeoShapeType.GEOMETRYCOLLECTION) == false) {
malformedException = "cannot have [" + ShapeParser.FIELD_GEOMETRIES + "] with type set to [" + shapeType + "]";
}
subParser.nextToken();
geometryCollections = parseGeometries(subParser, shapeMapper);
} else if (CircleBuilder.FIELD_RADIUS.match(fieldName, subParser.getDeprecationHandler())) {
if (shapeType == null) {
shapeType = GeoShapeType.CIRCLE;
} else if (shapeType != null && shapeType.equals(GeoShapeType.CIRCLE) == false) {
malformedException = "cannot have [" + CircleBuilder.FIELD_RADIUS + "] with type set to [" + shapeType + "]";
}
subParser.nextToken();
radius = DistanceUnit.Distance.parseDistance(subParser.text());
} else if (ShapeParser.FIELD_ORIENTATION.match(fieldName, subParser.getDeprecationHandler())) {
if (shapeType != null && (shapeType.equals(GeoShapeType.POLYGON) || shapeType.equals(GeoShapeType.MULTIPOLYGON)) == false) {
malformedException = "cannot have [" + ShapeParser.FIELD_ORIENTATION + "] with type set to [" + shapeType + "]";
}
subParser.nextToken();
orientation = ShapeBuilder.Orientation.fromString(subParser.text());
} else {
subParser.nextToken();
subParser.skipChildren();
}
}
}
}
if (malformedException != null) {
throw new OpenSearchParseException(malformedException);
} else if (shapeType == null) {
throw new OpenSearchParseException("shape type not included");
} else if (coordinateNode == null && GeoShapeType.GEOMETRYCOLLECTION != shapeType) {
throw new OpenSearchParseException("coordinates not included");
} else if (geometryCollections == null && GeoShapeType.GEOMETRYCOLLECTION == shapeType) {
throw new OpenSearchParseException("geometries not included");
} else if (radius != null && GeoShapeType.CIRCLE != shapeType) {
throw new OpenSearchParseException("field [{}] is supported for [{}] only", CircleBuilder.FIELD_RADIUS, CircleBuilder.TYPE);
}
if (shapeType.equals(GeoShapeType.GEOMETRYCOLLECTION)) {
return geometryCollections;
}
return shapeType.getBuilder(coordinateNode, radius, orientation, coerce.value());
}
Aggregations