Search in sources :

Example 1 with XContentSubParser

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>{&quot;lat&quot;: <i>&lt;latitude&gt;</i>, &quot;lon&quot;: <i>&lt;longitude&gt;</i>}</pre></li>
 *     <li>String: <pre>&quot;<i>&lt;latitude&gt;</i>,<i>&lt;longitude&gt;</i>&quot;</pre></li>
 *     <li>Geohash: <pre>&quot;<i>&lt;geohash&gt;</i>&quot;</pre></li>
 *     <li>Array: <pre>[<i>&lt;longitude&gt;</i>,<i>&lt;latitude&gt;</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");
    }
}
Also used : XContentSubParser(org.opensearch.common.xcontent.XContentSubParser) OpenSearchParseException(org.opensearch.OpenSearchParseException)

Example 2 with XContentSubParser

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;
    }
}
Also used : XContentSubParser(org.opensearch.common.xcontent.XContentSubParser) Geometry(org.opensearch.geometry.Geometry)

Example 3 with XContentSubParser

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());
}
Also used : Orientation(org.opensearch.common.geo.builders.ShapeBuilder.Orientation) GeometryCollectionBuilder(org.opensearch.common.geo.builders.GeometryCollectionBuilder) XContentSubParser(org.opensearch.common.xcontent.XContentSubParser) OpenSearchParseException(org.opensearch.OpenSearchParseException) DistanceUnit(org.opensearch.common.unit.DistanceUnit) GeoShapeType(org.opensearch.common.geo.GeoShapeType) XContentParser(org.opensearch.common.xcontent.XContentParser)

Aggregations

XContentSubParser (org.opensearch.common.xcontent.XContentSubParser)3 OpenSearchParseException (org.opensearch.OpenSearchParseException)2 GeoShapeType (org.opensearch.common.geo.GeoShapeType)1 GeometryCollectionBuilder (org.opensearch.common.geo.builders.GeometryCollectionBuilder)1 Orientation (org.opensearch.common.geo.builders.ShapeBuilder.Orientation)1 DistanceUnit (org.opensearch.common.unit.DistanceUnit)1 XContentParser (org.opensearch.common.xcontent.XContentParser)1 Geometry (org.opensearch.geometry.Geometry)1