DATAES-930 - Add support for geo_shape type entity properties.

Original PR: #531
This commit is contained in:
Peter-Josef Meisch 2020-10-05 21:50:38 +02:00 committed by GitHub
parent 36d8e7cc5e
commit 2a8c1dbdf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 2804 additions and 25 deletions

View File

@ -44,8 +44,8 @@ The following annotations are available:
** `name`: The name of the field as it will be represented in the Elasticsearch document, if not set, the Java field name is used.
** `type`: the field type, can be one of _Text, Keyword, Long, Integer, Short, Byte, Double, Float, Half_Float, Scaled_Float, Date, Date_Nanos, Boolean, Binary, Integer_Range, Float_Range, Long_Range, Double_Range, Date_Range, Ip_Range, Object, Nested, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types]
** `format` and `pattern` definitions for the _Date_ type. `format` must be defined for date types.
** `store`: Flag wether the original field value should be store in Elasticsearch, default value is _false_.
** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer.
** `store`: Flag whether the original field value should be store in Elasticsearch, default value is _false_.
** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom analyzers and normalizer.
* `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class.
NOTE: Properties that derive from `TemporalAccessor` must either have a `@Field` annotation of type `FieldType.Date` or a custom converter must be registered for this type. +
@ -136,6 +136,44 @@ public class Address {
----
====
==== GeoJson Types
Spring Data Elasticsearch supports the GeoJson types by providing an interface `GeoJson` and implementations for the different geometries. They are mapped to Elasticsearch
documents according to the GeoJson specification. The corresponding properties of the entity are specified as `geo_shape` when the index mappings is written.
.GeoJson types
====
[source,java]
----
public class Address {
String city, street;
GeoJsonPoint location;
}
----
[source,json]
----
{
"city": "Los Angeles",
"street": "2800 East Observatory Road",
"location": {
"type": "Point",
"coordinates": [-118.3026284, 34.118347]
}
}
----
====
The following GeoJson types are implemented:
* `GeoJsonPoint`
* `GeoJsonMultiPoint`
* `GeoJsonLineString`
* `GeoJsonMultiLineString`
* `GeoJsonPolygon`
* `GeoJsonMultiPolygon`
* `GeoJsonGeometryCollection`
==== Collections
For values inside Collections apply the same mapping rules as for aggregate roots when it comes to _type hints_ and <<elasticsearch.mapping.meta-model.conversions>>.

View File

@ -18,13 +18,25 @@ package org.springframework.data.elasticsearch.core.convert;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.elasticsearch.core.geo.GeoJson;
import org.springframework.data.elasticsearch.core.geo.GeoJsonGeometryCollection;
import org.springframework.data.elasticsearch.core.geo.GeoJsonLineString;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiLineString;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPoint;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPolygon;
import org.springframework.data.elasticsearch.core.geo.GeoJsonPoint;
import org.springframework.data.elasticsearch.core.geo.GeoJsonPolygon;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
/**
@ -38,10 +50,19 @@ class GeoConverters {
static Collection<Converter<?, ?>> getConvertersToRegister() {
return Arrays.asList(PointToMapConverter.INSTANCE, MapToPointConverter.INSTANCE, GeoPointToMapConverter.INSTANCE,
MapToGeoPointConverter.INSTANCE);
return Arrays.asList(PointToMapConverter.INSTANCE, MapToPointConverter.INSTANCE, //
GeoPointToMapConverter.INSTANCE, MapToGeoPointConverter.INSTANCE, //
GeoJsonToMapConverter.INSTANCE, MapToGeoJsonConverter.INSTANCE, //
GeoJsonPointToMapConverter.INSTANCE, MapToGeoJsonPointConverter.INSTANCE, //
GeoJsonMultiPointToMapConverter.INSTANCE, MapToGeoJsonMultiPointConverter.INSTANCE, //
GeoJsonLineStringToMapConverter.INSTANCE, MapToGeoJsonLineStringConverter.INSTANCE, //
GeoJsonMultiLineStringToMapConverter.INSTANCE, MapToGeoJsonMultiLineStringConverter.INSTANCE, //
GeoJsonPolygonToMapConverter.INSTANCE, MapToGeoJsonPolygonConverter.INSTANCE, //
GeoJsonMultiPolygonToMapConverter.INSTANCE, MapToGeoJsonMultiPolygonConverter.INSTANCE, //
GeoJsonGeometryCollectionToMapConverter.INSTANCE, MapToGeoJsonGeometryCollectionConverter.INSTANCE);
}
// region Point
/**
* {@link Converter} to write a {@link Point} to {@link Map} using {@code lat/long} properties.
*/
@ -60,23 +81,6 @@ class GeoConverters {
}
}
/**
* {@link Converter} to write a {@link GeoPoint} to {@link Map} using {@code lat/long} properties.
*/
@WritingConverter
enum GeoPointToMapConverter implements Converter<GeoPoint, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoPoint source) {
Map<String, Object> target = new LinkedHashMap<>();
target.put("lat", source.getLat());
target.put("lon", source.getLon());
return target;
}
}
/**
* {@link Converter} to read a {@link Point} from {@link Map} using {@code lat/long} properties.
*/
@ -93,10 +97,27 @@ class GeoConverters {
return new Point(x, y);
}
}
// endregion
// region GeoPoint
/**
* {@link Converter} to read a {@link GeoPoint} from {@link Map} using {@code lat/long} properties.
* {@link Converter} to write a {@link GeoPoint} to {@link Map} using {@code lat/long} properties.
*/
@WritingConverter
enum GeoPointToMapConverter implements Converter<GeoPoint, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoPoint source) {
Map<String, Object> target = new LinkedHashMap<>();
target.put("lat", source.getLat());
target.put("lon", source.getLon());
return target;
}
}
@ReadingConverter
enum MapToGeoPointConverter implements Converter<Map<String, Object>, GeoPoint> {
@ -110,4 +131,375 @@ class GeoConverters {
return new GeoPoint(lat, lon);
}
}
// endregion
// region GeoJson
@WritingConverter
enum GeoJsonToMapConverter implements Converter<GeoJson<? extends Iterable<?>>, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJson<? extends Iterable<?>> source) {
if (source instanceof GeoJsonPoint) {
return GeoJsonPointToMapConverter.INSTANCE.convert((GeoJsonPoint) source);
} else if (source instanceof GeoJsonMultiPoint) {
return GeoJsonMultiPointToMapConverter.INSTANCE.convert((GeoJsonMultiPoint) source);
} else if (source instanceof GeoJsonLineString) {
return GeoJsonLineStringToMapConverter.INSTANCE.convert((GeoJsonLineString) source);
} else if (source instanceof GeoJsonMultiLineString) {
return GeoJsonMultiLineStringToMapConverter.INSTANCE.convert((GeoJsonMultiLineString) source);
} else if (source instanceof GeoJsonPolygon) {
return GeoJsonPolygonToMapConverter.INSTANCE.convert((GeoJsonPolygon) source);
} else if (source instanceof GeoJsonMultiPolygon) {
return GeoJsonMultiPolygonToMapConverter.INSTANCE.convert((GeoJsonMultiPolygon) source);
} else if (source instanceof GeoJsonGeometryCollection) {
return GeoJsonGeometryCollectionToMapConverter.INSTANCE.convert((GeoJsonGeometryCollection) source);
} else {
throw new IllegalArgumentException("unknown GeoJson class " + source.getClass().getSimpleName());
}
}
}
@ReadingConverter
enum MapToGeoJsonConverter implements Converter<Map<String, Object>, GeoJson<? extends Iterable<?>>> {
INSTANCE;
@Override
public GeoJson<? extends Iterable<?>> convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
switch (type) {
case GeoJsonPoint.TYPE:
return MapToGeoJsonPointConverter.INSTANCE.convert(source);
case GeoJsonMultiPoint.TYPE:
return MapToGeoJsonMultiPointConverter.INSTANCE.convert(source);
case GeoJsonLineString.TYPE:
return MapToGeoJsonLineStringConverter.INSTANCE.convert(source);
case GeoJsonMultiLineString.TYPE:
return MapToGeoJsonMultiLineStringConverter.INSTANCE.convert(source);
case GeoJsonPolygon.TYPE:
return MapToGeoJsonPolygonConverter.INSTANCE.convert(source);
case GeoJsonMultiPolygon.TYPE:
return MapToGeoJsonMultiPolygonConverter.INSTANCE.convert(source);
case GeoJsonGeometryCollection.TYPE:
return MapToGeoJsonGeometryCollectionConverter.INSTANCE.convert(source);
default:
throw new IllegalArgumentException("unknown GeoJson type " + type);
}
}
}
// endregion
// region GeoJsonPoint
@WritingConverter
enum GeoJsonPointToMapConverter implements Converter<GeoJsonPoint, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonPoint geoJsonPoint) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", geoJsonPoint.getType());
map.put("coordinates", geoJsonPoint.getCoordinates());
return map;
}
}
@ReadingConverter
enum MapToGeoJsonPointConverter implements Converter<Map<String, Object>, GeoJsonPoint> {
INSTANCE;
@Override
public GeoJsonPoint convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonPoint.TYPE), "does not contain a type 'Point'");
Object coordinates = source.get("coordinates");
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
Assert.isTrue(coordinates instanceof List, "coordinates must be a List of Numbers");
// noinspection unchecked
List<Number> numbers = (List<Number>) coordinates;
Assert.isTrue(numbers.size() >= 2, "coordinates must have at least 2 elements");
return GeoJsonPoint.of(numbers.get(0).doubleValue(), numbers.get(1).doubleValue());
}
}
// endregion
// region GeoJsonMultiPoint
@WritingConverter
enum GeoJsonMultiPointToMapConverter implements Converter<GeoJsonMultiPoint, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonMultiPoint geoJsonMultiPoint) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", geoJsonMultiPoint.getType());
map.put("coordinates", pointsToCoordinates(geoJsonMultiPoint.getCoordinates()));
return map;
}
}
@ReadingConverter
enum MapToGeoJsonMultiPointConverter implements Converter<Map<String, Object>, GeoJsonMultiPoint> {
INSTANCE;
@Override
public GeoJsonMultiPoint convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonMultiPoint.TYPE), "does not contain a type 'MultiPoint'");
Object coordinates = source.get("coordinates");
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
Assert.isTrue(coordinates instanceof List, "coordinates must be a List");
// noinspection unchecked
return GeoJsonMultiPoint.of(coordinatesToPoints((List<List<Number>>) coordinates));
}
}
// endregion
// region GeoJsonLineString
@WritingConverter
enum GeoJsonLineStringToMapConverter implements Converter<GeoJsonLineString, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonLineString geoJsonLineString) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", geoJsonLineString.getType());
map.put("coordinates", pointsToCoordinates(geoJsonLineString.getCoordinates()));
return map;
}
}
@ReadingConverter
enum MapToGeoJsonLineStringConverter implements Converter<Map<String, Object>, GeoJsonLineString> {
INSTANCE;
@Override
public GeoJsonLineString convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonLineString.TYPE), "does not contain a type 'LineString'");
Object coordinates = source.get("coordinates");
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
Assert.isTrue(coordinates instanceof List, "coordinates must be a List");
// noinspection unchecked
return GeoJsonLineString.of(coordinatesToPoints((List<List<Number>>) coordinates));
}
}
// endregion
// region GeoJsonMultiLineString
@WritingConverter
enum GeoJsonMultiLineStringToMapConverter implements Converter<GeoJsonMultiLineString, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonMultiLineString source) {
return geoJsonLinesStringsToMap(source.getType(), source.getCoordinates());
}
}
@ReadingConverter
enum MapToGeoJsonMultiLineStringConverter implements Converter<Map<String, Object>, GeoJsonMultiLineString> {
INSTANCE;
@Override
public GeoJsonMultiLineString convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonMultiLineString.TYPE), "does not contain a type 'MultiLineString'");
List<GeoJsonLineString> lines = geoJsonLineStringsFromMap(source);
return GeoJsonMultiLineString.of(lines);
}
}
// endregion
// region GeoJsonPolygon
@WritingConverter
enum GeoJsonPolygonToMapConverter implements Converter<GeoJsonPolygon, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonPolygon source) {
return geoJsonLinesStringsToMap(source.getType(), source.getCoordinates());
}
}
@ReadingConverter
enum MapToGeoJsonPolygonConverter implements Converter<Map<String, Object>, GeoJsonPolygon> {
INSTANCE;
@Override
public GeoJsonPolygon convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonPolygon.TYPE), "does not contain a type 'Polygon'");
List<GeoJsonLineString> lines = geoJsonLineStringsFromMap(source);
Assert.isTrue(lines.size() > 0, "no linestrings defined in polygon");
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon.of(lines.get(0));
for (int i = 1; i < lines.size(); i++) {
geoJsonPolygon = geoJsonPolygon.withInnerRing(lines.get(i));
}
return geoJsonPolygon;
}
}
// endregion
// region GeoJsonMultiPolygon
@WritingConverter
enum GeoJsonMultiPolygonToMapConverter implements Converter<GeoJsonMultiPolygon, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonMultiPolygon source) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", source.getType());
List<Object> coordinates = source.getCoordinates().stream() //
.map(GeoJsonPolygonToMapConverter.INSTANCE::convert) //
.filter(Objects::nonNull) //
.map(it -> it.get("coordinates")) //
.collect(Collectors.toList()); //
map.put("coordinates", coordinates);
return map;
}
}
@ReadingConverter
enum MapToGeoJsonMultiPolygonConverter implements Converter<Map<String, Object>, GeoJsonMultiPolygon> {
INSTANCE;
@Override
public GeoJsonMultiPolygon convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonMultiPolygon.TYPE), "does not contain a type 'MultiPolygon'");
Object coordinates = source.get("coordinates");
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
Assert.isTrue(coordinates instanceof List, "coordinates must be a List");
List<GeoJsonPolygon> geoJsonPolygons = ((List<?>) coordinates).stream().map(it -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", GeoJsonPolygon.TYPE);
map.put("coordinates", it);
return map;
}).map(MapToGeoJsonPolygonConverter.INSTANCE::convert).collect(Collectors.toList());
return GeoJsonMultiPolygon.of(geoJsonPolygons);
}
}
// endregion
// region GeoJsonGeometryCollection
@WritingConverter
enum GeoJsonGeometryCollectionToMapConverter implements Converter<GeoJsonGeometryCollection, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoJsonGeometryCollection source) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", source.getType());
List<Map<String, Object>> geometries = source.getGeometries().stream()
.map(GeoJsonToMapConverter.INSTANCE::convert).collect(Collectors.toList());
map.put("geometries", geometries);
return map;
}
}
@ReadingConverter
enum MapToGeoJsonGeometryCollectionConverter implements Converter<Map<String, Object>, GeoJsonGeometryCollection> {
INSTANCE;
@Override
public GeoJsonGeometryCollection convert(Map<String, Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equals(GeoJsonGeometryCollection.TYPE), "does not contain a type 'GeometryCollection'");
Object geometries = source.get("geometries");
Assert.notNull(geometries, "Document to convert does not contain geometries");
Assert.isTrue(geometries instanceof List, "geometries must be a List");
// noinspection unchecked
List<GeoJson<?>> geoJsonList = ((List<Map<String, Object>>) geometries).stream()
.map(MapToGeoJsonConverter.INSTANCE::convert).collect(Collectors.toList());
return GeoJsonGeometryCollection.of(geoJsonList);
}
}
// endregion
// region helper functions
private static String getGeoJsonType(Map<String, Object> source) {
Object type = source.get("type");
Assert.notNull(type, "Document to convert does not contain a type");
Assert.isTrue(type instanceof String, "type must be a String");
return type.toString();
}
private static List<Double> toCoordinates(Point point) {
return Arrays.asList(point.getX(), point.getY());
}
private static List<List<Double>> pointsToCoordinates(List<Point> points) {
return points.stream().map(GeoConverters::toCoordinates).collect(Collectors.toList());
}
private static List<Point> coordinatesToPoints(List<List<Number>> pointList) {
Assert.isTrue(pointList.size() >= 2, "pointList must have at least 2 elements");
return pointList.stream().map(numbers -> {
Assert.isTrue(numbers.size() >= 2, "coordinates must have at least 2 elements");
return new Point(numbers.get(0).doubleValue(), numbers.get(1).doubleValue());
}).collect(Collectors.toList());
}
private static Map<String, Object> geoJsonLinesStringsToMap(String type, List<GeoJsonLineString> lineStrings) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", type);
List<List<List<Double>>> coordinates = lineStrings.stream()
.map(it -> GeoConverters.pointsToCoordinates(it.getCoordinates())).collect(Collectors.toList());
map.put("coordinates", coordinates);
return map;
}
private static List<GeoJsonLineString> geoJsonLineStringsFromMap(Map<String, Object> source) {
Object coordinates = source.get("coordinates");
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
Assert.isTrue(coordinates instanceof List, "coordinates must be a List");
// noinspection unchecked
List<GeoJsonLineString> lines = ((List<?>) coordinates).stream()
.map(it -> GeoJsonLineString.of(coordinatesToPoints((List<List<Number>>) it))).collect(Collectors.toList());
return lines;
}
// endregion
}

View File

@ -13,7 +13,9 @@ import org.springframework.data.geo.Point;
/**
* @author Artur Konaczak
* @deprecated since 4.1, not used anymore
*/
@Deprecated
public class CustomGeoModule extends SimpleModule {
private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,43 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
/**
* Interface definition for structures defined in <a href="https://geojson.org/>GeoJSON</a> format.
* copied from Spring Data Mongodb
*
* @author Christoph Strobl
* @since 1.7
*/
public interface GeoJson<T extends Iterable<?>> {
/**
* String value representing the type of the {@link GeoJson} object.
*
* @return will never be {@literal null}.
* @see <a href="https://geojson.org/geojson-spec.html#geojson-objects">https://geojson.org/geojson-spec.html#geojson-objects</a>
*/
String getType();
/**
* The value of the coordinates member is always an {@link Iterable}. The structure for the elements within is
* determined by {@link #getType()} of geometry.
*
* @return will never be {@literal null}.
* @see <a href="https://geojson.org/geojson-spec.html#geometry-objects">https://geojson.org/geojson-spec.html#geometry-objects</a>
*/
T getCoordinates();
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.util.Assert;
/**
* Defines a {@link GeoJsonGeometryCollection} that consists of a {@link List} of {@link GeoJson} objects.<br/>
* Copied from Spring Data Mongodb
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.1
* @see <a href=
* "https://geojson.org/geojson-spec.html#geometry-collection">https://geojson.org/geojson-spec.html#geometry-collection</a>
*/
public class GeoJsonGeometryCollection implements GeoJson<Iterable<GeoJson<?>>> {
public static final String TYPE = "GeometryCollection";
private final List<GeoJson<?>> geometries = new ArrayList<>();
private GeoJsonGeometryCollection(List<GeoJson<?>> geometries) {
this.geometries.addAll(geometries);
}
/**
* Creates a new {@link GeoJsonGeometryCollection} for the given {@link GeoJson} instances.
*
* @param geometries must not be {@literal null}.
*/
public static GeoJsonGeometryCollection of(List<GeoJson<?>> geometries) {
Assert.notNull(geometries, "Geometries must not be null!");
return new GeoJsonGeometryCollection(geometries);
}
@Override
public String getType() {
return TYPE;
}
@Override
public Iterable<GeoJson<?>> getCoordinates() {
return getGeometries();
}
public List<GeoJson<?>> getGeometries() {
return Collections.unmodifiableList(this.geometries);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonGeometryCollection that = (GeoJsonGeometryCollection) o;
return geometries.equals(that.geometries);
}
@Override
public int hashCode() {
return geometries.hashCode();
}
@Override
public String toString() {
return "GeoJsonGeometryCollection{" + "geometries=" + geometries + '}';
}
}

View File

@ -0,0 +1,145 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
/**
* {@link GeoJsonLineString} is defined as list of {@link Point}s.<br/>
* Copied from Spring Data Mongodb
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.1
* @see <a href="https://geojson.org/geojson-spec.html#multipoint">https://geojson.org/geojson-spec.html#multipoint</a>
*/
public class GeoJsonLineString implements GeoJson<Iterable<Point>> {
public static final String TYPE = "LineString";
private final List<Point> points;
private GeoJsonLineString(List<Point> points) {
this.points = new ArrayList<>(points);
}
/**
* Creates a new {@link GeoJsonLineString} for the given {@link Point}s.
*
* @param points points must not be {@literal null} and have at least 2 entries.
*/
public static GeoJsonLineString of(List<Point> points) {
Assert.notNull(points, "Points must not be null.");
Assert.isTrue(points.size() >= 2, "Minimum of 2 Points required.");
return new GeoJsonLineString(points);
}
/**
* Creates a new {@link GeoJsonLineString} for the given {@link Point}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param others must not be {@literal null}.
*/
public static GeoJsonLineString of(Point first, Point second, Point... others) {
Assert.notNull(first, "First point must not be null!");
Assert.notNull(second, "Second point must not be null!");
Assert.notNull(others, "Additional points must not be null!");
List<Point> points = new ArrayList<>();
points.add(first);
points.add(second);
points.addAll(Arrays.asList(others));
return new GeoJsonLineString(points);
}
/**
* Creates a new {@link GeoJsonLineString} for the given {@link GeoPoint}s.
*
* @param geoPoints geoPoints must not be {@literal null} and have at least 2 entries.
*/
public static GeoJsonLineString ofGeoPoints(List<GeoPoint> geoPoints) {
Assert.notNull(geoPoints, "Points must not be null.");
Assert.isTrue(geoPoints.size() >= 2, "Minimum of 2 Points required.");
return new GeoJsonLineString(geoPoints.stream().map(GeoPoint::toPoint).collect(Collectors.toList()));
}
/**
* Creates a new {@link GeoJsonLineString} for the given {@link GeoPoint}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param others must not be {@literal null}.
*/
public static GeoJsonLineString of(GeoPoint first, GeoPoint second, GeoPoint... others) {
Assert.notNull(first, "First point must not be null!");
Assert.notNull(second, "Second point must not be null!");
Assert.notNull(others, "Additional points must not be null!");
List<Point> points = new ArrayList<>();
points.add(GeoPoint.toPoint(first));
points.add(GeoPoint.toPoint(second));
points.addAll(Arrays.stream(others).map(GeoPoint::toPoint).collect(Collectors.toList()));
return new GeoJsonLineString(points);
}
@Override
public String getType() {
return TYPE;
}
@Override
public List<Point> getCoordinates() {
return Collections.unmodifiableList(this.points);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonLineString that = (GeoJsonLineString) o;
return points.equals(that.points);
}
@Override
public int hashCode() {
return points.hashCode();
}
@Override
public String toString() {
return "GeoJsonLineString{" + "points=" + points + '}';
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
/**
* {@link GeoJsonMultiLineString} is defined as list of {@link GeoJsonLineString}s. <br/>
* Copied from Spring Data Mongodb
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.1
* @see <a href=
* "https://geojson.org/geojson-spec.html#multilinestring">https://geojson.org/geojson-spec.html#multilinestring</a>
*/
public class GeoJsonMultiLineString implements GeoJson<Iterable<GeoJsonLineString>> {
public static final String TYPE = "MultiLineString";
private final List<GeoJsonLineString> coordinates = new ArrayList<>();
private GeoJsonMultiLineString(List<GeoJsonLineString> lines) {
this.coordinates.addAll(lines);
}
/**
* Creates new {@link GeoJsonMultiLineString} for the given {@link GeoJsonLineString}s.
*
* @param lines must not be {@literal null}.
*/
public static GeoJsonMultiLineString of(List<GeoJsonLineString> lines) {
Assert.notNull(lines, "Lines for MultiLineString must not be null!");
return new GeoJsonMultiLineString(lines);
}
/**
* Creates new {@link GeoJsonMultiLineString} for the given {@link Point}s.
*
* @param lines must not be {@literal null}.
*/
public static GeoJsonMultiLineString of(List<Point>... lines) {
Assert.notEmpty(lines, "Points for MultiLineString must not be null!");
List<GeoJsonLineString> geoJsonLineStrings = Arrays.stream(lines).map(GeoJsonLineString::of)
.collect(Collectors.toList());
return new GeoJsonMultiLineString(geoJsonLineStrings);
}
@Override
public String getType() {
return TYPE;
}
@Override
public List<GeoJsonLineString> getCoordinates() {
return Collections.unmodifiableList(this.coordinates);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonMultiLineString that = (GeoJsonMultiLineString) o;
return coordinates.equals(that.coordinates);
}
@Override
public int hashCode() {
return coordinates.hashCode();
}
@Override
public String toString() {
return "GeoJsonMultiLineString{" + "coordinates=" + coordinates + '}';
}
}

View File

@ -0,0 +1,145 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
/**
* {@link GeoJsonMultiPoint} is defined as list of {@link Point}s.<br/>
* Copied from Spring Data Mongodb
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.1
* @see <a href="https://geojson.org/geojson-spec.html#multipoint">https://geojson.org/geojson-spec.html#multipoint</a>
*/
public class GeoJsonMultiPoint implements GeoJson<Iterable<Point>> {
public static final String TYPE = "MultiPoint";
private final List<Point> points;
private GeoJsonMultiPoint(List<Point> points) {
this.points = new ArrayList<>(points);
}
/**
* Creates a new {@link GeoJsonMultiPoint} for the given {@link Point}s.
*
* @param points points must not be {@literal null} and have at least 2 entries.
*/
public static GeoJsonMultiPoint of(List<Point> points) {
Assert.notNull(points, "Points must not be null.");
Assert.isTrue(points.size() >= 2, "Minimum of 2 Points required.");
return new GeoJsonMultiPoint(points);
}
/**
* Creates a new {@link GeoJsonMultiPoint} for the given {@link Point}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param others must not be {@literal null}.
*/
public static GeoJsonMultiPoint of(Point first, Point second, Point... others) {
Assert.notNull(first, "First point must not be null!");
Assert.notNull(second, "Second point must not be null!");
Assert.notNull(others, "Additional points must not be null!");
List<Point> points = new ArrayList<>();
points.add(first);
points.add(second);
points.addAll(Arrays.asList(others));
return new GeoJsonMultiPoint(points);
}
/**
* Creates a new {@link GeoJsonMultiPoint} for the given {@link GeoPoint}s.
*
* @param geoPoints geoPoints must not be {@literal null} and have at least 2 entries.
*/
public static GeoJsonMultiPoint ofGeoPoints(List<GeoPoint> geoPoints) {
Assert.notNull(geoPoints, "Points must not be null.");
Assert.isTrue(geoPoints.size() >= 2, "Minimum of 2 Points required.");
return new GeoJsonMultiPoint(geoPoints.stream().map(GeoPoint::toPoint).collect(Collectors.toList()));
}
/**
* Creates a new {@link GeoJsonMultiPoint} for the given {@link GeoPoint}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param others must not be {@literal null}.
*/
public static GeoJsonMultiPoint of(GeoPoint first, GeoPoint second, GeoPoint... others) {
Assert.notNull(first, "First point must not be null!");
Assert.notNull(second, "Second point must not be null!");
Assert.notNull(others, "Additional points must not be null!");
List<Point> points = new ArrayList<>();
points.add(GeoPoint.toPoint(first));
points.add(GeoPoint.toPoint(second));
points.addAll(Arrays.stream(others).map(GeoPoint::toPoint).collect(Collectors.toList()));
return new GeoJsonMultiPoint(points);
}
@Override
public String getType() {
return TYPE;
}
@Override
public List<Point> getCoordinates() {
return Collections.unmodifiableList(this.points);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonMultiPoint that = (GeoJsonMultiPoint) o;
return points.equals(that.points);
}
@Override
public int hashCode() {
return points.hashCode();
}
@Override
public String toString() {
return "GeoJsonMultiPoint{" + "points=" + points + '}';
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.util.Assert;
/**
* {@link GeoJsonMultiPolygon} is defined as a list of {@link GeoJsonPolygon}s.<br/>
* Copied fro Spring Data Mongodb.
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.1
*/
public class GeoJsonMultiPolygon implements GeoJson<Iterable<GeoJsonPolygon>> {
public static final String TYPE = "MultiPolygon";
private List<GeoJsonPolygon> coordinates = new ArrayList<GeoJsonPolygon>();
private GeoJsonMultiPolygon(List<GeoJsonPolygon> polygons) {
this.coordinates.addAll(polygons);
}
/**
* Creates a new {@link GeoJsonMultiPolygon} for the given {@link GeoJsonPolygon}s.
*
* @param polygons must not be {@literal null}.
*/
public static GeoJsonMultiPolygon of(List<GeoJsonPolygon> polygons) {
Assert.notNull(polygons, "Polygons for MultiPolygon must not be null!");
return new GeoJsonMultiPolygon(polygons);
}
@Override
public String getType() {
return TYPE;
}
@Override
public List<GeoJsonPolygon> getCoordinates() {
return Collections.unmodifiableList(this.coordinates);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonMultiPolygon that = (GeoJsonMultiPolygon) o;
return coordinates.equals(that.coordinates);
}
@Override
public int hashCode() {
return coordinates.hashCode();
}
@Override
public String toString() {
return "GeoJsonMultiPolygon{" + "coordinates=" + coordinates + '}';
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.Arrays;
import java.util.List;
import org.springframework.data.geo.Point;
/**
* {@link GeoJson} representation of {@link Point}.<br/>
* Copied from Spring Data Mongodb, not derived from {@link Point} as this conflicts with the already existing converter
* for Point in {@link org.springframework.data.elasticsearch.core.convert.GeoConverters}.
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.1
* @see <a href="https://geojson.org/geojson-spec.html#point">https://geojson.org/geojson-spec.html#point</a>
*/
public class GeoJsonPoint implements GeoJson<List<Double>> {
private final double x;
private final double y;
public static final String TYPE = "Point";
private GeoJsonPoint(double x, double y) {
this.x = x;
this.y = y;
}
/**
* Creates {@link GeoJsonPoint} for given coordinates.
*
* @param x
* @param y
*/
public static GeoJsonPoint of(double x, double y) {
return new GeoJsonPoint(x, y);
}
/**
* Creates {@link GeoJsonPoint} for given {@link Point}.
*
* @param point must not be {@literal null}.
*/
public static GeoJsonPoint of(Point point) {
return new GeoJsonPoint(point.getX(), point.getY());
}
/**
* Creates {@link GeoJsonPoint} for given {@link GeoPoint}.
*
* @param geoPoint must not be {@literal null}.
*/
public static GeoJsonPoint of(GeoPoint geoPoint) {
return new GeoJsonPoint(geoPoint.getLon(), geoPoint.getLat());
}
@Override
public String getType() {
return TYPE;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
@Override
public List<Double> getCoordinates() {
return Arrays.asList(getX(), getY());
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonPoint that = (GeoJsonPoint) o;
if (Double.compare(that.x, x) != 0)
return false;
return Double.compare(that.y, y) == 0;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(x);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public String toString() {
return "GeoJsonPoint{" + "x=" + x + ", y=" + y + '}';
}
}

View File

@ -0,0 +1,224 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
/**
* {@link GeoJson} representation of a polygon. <br/>
* Copied from Spring Data Mongodb
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Peter-Josef Meisch
* @since 4.1
* @see <a href="https://geojson.org/geojson-spec.html#polygon">https://geojson.org/geojson-spec.html#polygon</a>
*/
public class GeoJsonPolygon implements GeoJson<Iterable<GeoJsonLineString>> {
public static final String TYPE = "Polygon";
private final List<GeoJsonLineString> coordinates = new ArrayList<>();
private GeoJsonPolygon(GeoJsonLineString geoJsonLineString) {
Assert.notNull(geoJsonLineString, "geoJsonLineString must not be null");
Assert.isTrue(geoJsonLineString.getCoordinates().size() >= 4, "geoJsonLineString must have at least 4 points");
this.coordinates.add(geoJsonLineString);
}
private GeoJsonPolygon(List<Point> points) {
this(GeoJsonLineString.of(points));
}
/**
* Creates new {@link GeoJsonPolygon} from the given {@link GeoJsonLineString}.
*
* @param geoJsonLineString must not be {@literal null}.
*/
public static GeoJsonPolygon of(GeoJsonLineString geoJsonLineString) {
return new GeoJsonPolygon(geoJsonLineString);
}
/**
* Creates new {@link GeoJsonPolygon} from the given {@link Point}s.
*
* @param points must not be {@literal null}.
*/
public static GeoJsonPolygon of(List<Point> points) {
return new GeoJsonPolygon(points);
}
/**
* Creates new {@link GeoJsonPolygon} from the given {@link GeoPoint}s.
*
* @param geoPoints must not be {@literal null}.
*/
public static GeoJsonPolygon ofGeoPoints(List<GeoPoint> geoPoints) {
return new GeoJsonPolygon(GeoJsonLineString.ofGeoPoints(geoPoints));
}
/**
* Creates new {@link GeoJsonPolygon} from the given {@link Point}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param third must not be {@literal null}.
* @param fourth must not be {@literal null}
* @param others can be empty.
*/
public static GeoJsonPolygon of(Point first, Point second, Point third, Point fourth, Point... others) {
return new GeoJsonPolygon(asList(first, second, third, fourth, others));
}
/**
* Creates new {@link GeoJsonPolygon} from the given {@link GeoPoint}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param third must not be {@literal null}.
* @param fourth must not be {@literal null}
* @param others can be empty.
*/
public static GeoJsonPolygon of(GeoPoint first, GeoPoint second, GeoPoint third, GeoPoint fourth,
GeoPoint... others) {
return new GeoJsonPolygon(GeoJsonLineString.ofGeoPoints(asList(first, second, third, fourth, others)));
}
/**
* Creates a new {@link GeoJsonPolygon} with an inner ring defined be the given {@link Point}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param third must not be {@literal null}.
* @param fourth must not be {@literal null}.
* @param others can be empty.
* @return new {@link GeoJsonPolygon}.
*/
public GeoJsonPolygon withInnerRing(Point first, Point second, Point third, Point fourth, Point... others) {
return withInnerRing(asList(first, second, third, fourth, others));
}
/**
* Creates a new {@link GeoJsonPolygon} with an inner ring defined be the given {@link GeoPoint}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param third must not be {@literal null}.
* @param fourth must not be {@literal null}.
* @param others can be empty.
* @return new {@link GeoJsonPolygon}.
*/
public GeoJsonPolygon withInnerRing(GeoPoint first, GeoPoint second, GeoPoint third, GeoPoint fourth,
GeoPoint... others) {
return withInnerRingOfGeoPoints(asList(first, second, third, fourth, others));
}
/**
* Creates a new {@link GeoJsonPolygon} with an inner ring defined be the given {@link List} of {@link Point}s.
*
* @param points must not be {@literal null}.
* @return new {@link GeoJsonPolygon}.
*/
public GeoJsonPolygon withInnerRing(List<Point> points) {
return withInnerRing(GeoJsonLineString.of(points));
}
/**
* Creates a new {@link GeoJsonPolygon} with an inner ring defined be the given {@link List} of {@link GeoPoint}s.
*
* @param geoPoints must not be {@literal null}.
* @return new {@link GeoJsonPolygon}.
*/
public GeoJsonPolygon withInnerRingOfGeoPoints(List<GeoPoint> geoPoints) {
return withInnerRing(GeoJsonLineString.ofGeoPoints(geoPoints));
}
/**
* Creates a new {@link GeoJsonPolygon} with an inner ring defined be the given {@link GeoJsonLineString}.
*
* @param lineString must not be {@literal null}.
* @return new {@link GeoJsonPolygon}.
* @since 1.10
*/
public GeoJsonPolygon withInnerRing(GeoJsonLineString lineString) {
Assert.notNull(lineString, "LineString must not be null!");
Iterator<GeoJsonLineString> it = this.coordinates.iterator();
GeoJsonPolygon polygon = new GeoJsonPolygon(it.next().getCoordinates());
while (it.hasNext()) {
polygon.coordinates.add(it.next());
}
polygon.coordinates.add(lineString);
return polygon;
}
@Override
public String getType() {
return TYPE;
}
@Override
public List<GeoJsonLineString> getCoordinates() {
return Collections.unmodifiableList(this.coordinates);
}
@SafeVarargs
private static <T> List<T> asList(T first, T second, T third, T fourth, T... others) {
ArrayList<T> result = new ArrayList<>(3 + others.length);
result.add(first);
result.add(second);
result.add(third);
result.add(fourth);
result.addAll(Arrays.asList(others));
return result;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoJsonPolygon that = (GeoJsonPolygon) o;
return coordinates.equals(that.coordinates);
}
@Override
public int hashCode() {
return coordinates.hashCode();
}
@Override
public String toString() {
return "GeoJsonPolygon{" + "coordinates=" + coordinates + '}';
}
}

View File

@ -126,6 +126,20 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty<Elas
*/
boolean isCompletionProperty();
/**
* calls {@link #getActualType()} but returns null when an exception is thrown
*
* @since 4.1
*/
@Nullable
default Class<?> getActualTypeOrNull() {
try {
return getActualType();
} catch (Exception e) {
return null;
}
}
enum PropertyToFieldNameConverter implements Converter<ElasticsearchPersistentProperty, String> {
INSTANCE;

View File

@ -234,7 +234,8 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
}
}
if (property.getActualType() == JoinField.class) {
Class<?> actualType = property.getActualTypeOrNull();
if (actualType == JoinField.class) {
ElasticsearchPersistentProperty joinProperty = this.joinFieldProperty;
if (joinProperty != null) {

View File

@ -33,6 +33,7 @@ import org.springframework.data.elasticsearch.annotations.Parent;
import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.elasticsearch.core.completion.Completion;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter;
import org.springframework.data.elasticsearch.core.geo.GeoJson;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.join.JoinField;
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
@ -148,7 +149,13 @@ public class SimpleElasticsearchPersistentProperty extends
*/
private void initDateConverter() {
Field field = findAnnotation(Field.class);
Class<?> actualType = getActualType();
Class<?> actualType = getActualTypeOrNull();
if (actualType == null) {
return;
}
boolean isTemporalAccessor = TemporalAccessor.class.isAssignableFrom(actualType);
boolean isDate = Date.class.isAssignableFrom(actualType);
@ -262,7 +269,7 @@ public class SimpleElasticsearchPersistentProperty extends
@Override
public boolean isGeoShapeProperty() {
return isAnnotationPresent(GeoShapeField.class);
return GeoJson.class.isAssignableFrom(getActualType()) || isAnnotationPresent(GeoShapeField.class);
}
@Override

View File

@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.config.namespace;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
@ -25,6 +26,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.client.RestClientFactoryBean;
import org.springframework.data.elasticsearch.client.TransportClientFactoryBean;
import org.springframework.data.elasticsearch.junit.jupiter.Tags;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ -38,6 +40,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@ContextConfiguration("namespace.xml")
@Tag(Tags.INTEGRATION_TEST)
public class ElasticsearchNamespaceHandlerTests {
@Autowired private ApplicationContext context;

View File

@ -0,0 +1,400 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.convert;
import static org.assertj.core.api.Assertions.*;
import static org.skyscreamer.jsonassert.JSONAssert.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.json.JSONException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.geo.GeoJson;
import org.springframework.data.elasticsearch.core.geo.GeoJsonGeometryCollection;
import org.springframework.data.elasticsearch.core.geo.GeoJsonLineString;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiLineString;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPoint;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPolygon;
import org.springframework.data.elasticsearch.core.geo.GeoJsonPoint;
import org.springframework.data.elasticsearch.core.geo.GeoJsonPolygon;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoConvertersUnitTests {
@Nested
@DisplayName("GeoJson Converters")
class GeoJsonTests {
private final GeoConverters.GeoJsonToMapConverter geoJsonToMapConverter = GeoConverters.GeoJsonToMapConverter.INSTANCE;
private final GeoConverters.MapToGeoJsonConverter mapToGeoJsonConverter = GeoConverters.MapToGeoJsonConverter.INSTANCE;
@Nested
@DisplayName("GeoJsonPoint")
class GeoJsonPointUnitTests {
@Test // DATAES-930
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12.0, 34.0]\n" + //
"}"; //
GeoJsonPoint geoJsonPoint = GeoJsonPoint.of(12, 34);
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonPoint);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
// make sure we can read int values as well
String json = "{\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12, 34.0]\n" + //
"}"; //
Document document = Document.parse(json);
GeoJsonPoint expected = GeoJsonPoint.of(12, 34);
GeoJson<? extends Iterable<?>> geoJsonPoint = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonPoint).isInstanceOf(GeoJsonPoint.class).isEqualTo(expected);
}
}
@Nested
@DisplayName("GeoJsonMultiPoint")
class GeoJsonMultipointUnitTests {
@Test // DATAES-930
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"MultiPoint\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34.0],\n" + //
" [56.0, 78.0]\n" + //
" ]\n" + //
"}\n"; //
GeoJsonMultiPoint geoJsonMultiPoint = GeoJsonMultiPoint.of(new Point(12, 34), new Point(56, 78));
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonMultiPoint);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
// make sure we can read int values as well
String json = "{\n" + " \"type\": \"MultiPoint\",\n" + " \"coordinates\": [\n" + " [12.0, 34],\n"
+ " [56, 78.0]\n" + " ]\n" + "}\n";
Document document = Document.parse(json);
GeoJsonMultiPoint expected = GeoJsonMultiPoint.of(new Point(12, 34), new Point(56, 78));
GeoJson<? extends Iterable<?>> geoJsonMultiPoint = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonMultiPoint).isInstanceOf(GeoJsonMultiPoint.class).isEqualTo(expected);
}
}
@Nested
@DisplayName("GeoJsonLineString")
class GeoJsonLineStringUnitTests {
@Test // DATAES-930
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"LineString\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34.0],\n" + //
" [56.0, 78.0]\n" + //
" ]\n" + //
"}\n"; //
GeoJsonLineString geoJsonLineString = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78));
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonLineString);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
// make sure we can read int values as well
String json = "{\n" + //
" \"type\": \"LineString\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34],\n" + //
" [56, 78.0]\n" //
+ " ]\n" //
+ "}\n"; //
Document document = Document.parse(json);
GeoJsonLineString expected = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78));
GeoJson<? extends Iterable<?>> geoJsonLineString = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonLineString).isInstanceOf(GeoJsonLineString.class).isEqualTo(expected);
}
}
@Nested
@DisplayName("GeoJsonMultiLineString")
class GeoJsonMultiLineStringUnitTests {
@Test // DATAES-930
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"MultiLineString\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0]],\n" + //
" [[90.0, 12.0], [34.0, 56.0]]\n" + //
" ]\n" + //
"}\n"; //
List<GeoJsonLineString> lines = Arrays.asList( //
GeoJsonLineString.of(new Point(12, 34), new Point(56, 78)), //
GeoJsonLineString.of(new Point(90, 12), new Point(34, 56)) //
);
GeoJsonMultiLineString geoJsonLineString = GeoJsonMultiLineString.of(lines);
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonLineString);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
// make sure we can read int values as well
String json = "{\n" + //
" \"type\": \"MultiLineString\",\n" + //
" \"coordinates\": [\n" + //
" [[12, 34.0], [56.0, 78]],\n" + //
" [[90.0, 12], [34, 56.0]]\n" + //
" ]\n" + //
"}\n"; //
Document document = Document.parse(json);
List<GeoJsonLineString> lines = Arrays.asList( //
GeoJsonLineString.of(new Point(12, 34), new Point(56, 78)), //
GeoJsonLineString.of(new Point(90, 12), new Point(34, 56)) //
);
GeoJsonMultiLineString expected = GeoJsonMultiLineString.of(lines);
GeoJson<? extends Iterable<?>> geoJsonLineString = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonLineString).isInstanceOf(GeoJsonMultiLineString.class).isEqualTo(expected);
}
}
@Nested
@DisplayName("GeoJsonPolygon")
class GeoJsonPolygonUnitTests {
@Test // DATAES-930
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0], [90.0, 12.0], [12.0, 34.0]],\n" + //
" [[56.0, 78.0], [90.0, 12.0], [34.0, 56.0], [56.0, 78.0]]\n" + //
" ]\n" + //
"}\n"; //
GeoJsonLineString polygonLineString = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78),
new Point(90, 12), new Point(12, 34));
GeoJsonLineString innerRingLineString = GeoJsonLineString.of(new Point(56, 78), new Point(90, 12),
new Point(34, 56), new Point(56, 78));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon.of(polygonLineString).withInnerRing(innerRingLineString);
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonPolygon);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
String json = "{\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12, 34.0], [56.0, 78], [90, 12.0], [12, 34.0]],\n" + //
" [[56.0, 78], [90, 12.0], [34.0, 56], [56.0, 78]]\n" + //
" ]\n" + //
"}\n"; //
Document document = Document.parse(json);
GeoJsonLineString polygonLineString = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78),
new Point(90, 12), new Point(12, 34));
GeoJsonLineString innerRingLineString = GeoJsonLineString.of(new Point(56, 78), new Point(90, 12),
new Point(34, 56), new Point(56, 78));
GeoJsonPolygon expected = GeoJsonPolygon.of(polygonLineString).withInnerRing(innerRingLineString);
GeoJson<? extends Iterable<?>> geoJsonLineString = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonLineString).isInstanceOf(GeoJsonPolygon.class).isEqualTo(expected);
}
}
@Nested
@DisplayName("GeoJsonMultiPolygon")
class GeoJsonMultiPolygonUnitTests {
@Test // DATAES-390
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"MultiPolygon\",\n" + //
" \"coordinates\": [\n" + //
" [[[12.0, 34.0], [56.0, 78.0], [90.0, 12.0], [12.0, 34.0]]],\n" + //
" [[[56.0, 78.0], [90.0, 12.0], [34.0, 56.0], [56.0, 78.0]]]\n" + //
" ]\n" + //
"}\n"; //
GeoJsonLineString polygonLineString1 = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78),
new Point(90, 12), new Point(12, 34));
GeoJsonLineString polygonLineString2 = GeoJsonLineString.of(new Point(56, 78), new Point(90, 12),
new Point(34, 56), new Point(56, 78));
GeoJsonMultiPolygon geoJsonMultiPolygon = GeoJsonMultiPolygon
.of(Arrays.asList(GeoJsonPolygon.of(polygonLineString1), GeoJsonPolygon.of(polygonLineString2)));
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonMultiPolygon);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
String json = "{\n" + //
" \"type\": \"MultiPolygon\",\n" + //
" \"coordinates\": [\n" + //
" [[[12, 34.0], [56.0, 78], [90, 12.0], [12, 34.0]]],\n" + //
" [[[56, 78.0], [90, 12.0], [34.0, 56], [56, 78.0]]]\n" + //
" ]\n" + //
"}\n"; //
Document document = Document.parse(json);
GeoJsonLineString polygonLineString1 = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78),
new Point(90, 12), new Point(12, 34));
GeoJsonLineString polygonLineString2 = GeoJsonLineString.of(new Point(56, 78), new Point(90, 12),
new Point(34, 56), new Point(56, 78));
GeoJsonMultiPolygon expected = GeoJsonMultiPolygon
.of(Arrays.asList(GeoJsonPolygon.of(polygonLineString1), GeoJsonPolygon.of(polygonLineString2)));
GeoJson<? extends Iterable<?>> geoJsonMultiPolygon = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonMultiPolygon).isInstanceOf(GeoJsonMultiPolygon.class).isEqualTo(expected);
}
}
@Nested
@DisplayName("GeoJsonGeometryCollection")
class GeoJsonGeometryCollectionUnitTests {
@Test // DATAES-930
@DisplayName("should be converted to a Map")
void shouldBeConvertedToAMap() throws JSONException {
String expected = "{\n" + //
" \"type\": \"GeometryCollection\",\n" + //
" \"geometries\": [\n" + //
" {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12.0, 34.0]\n" + //
" },\n" + //
" {\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0], [90.0, 12.0], [12.0, 34.0]]\n" + //
" ]\n" + //
" }\n" + //
" ]\n" + //
"}\n"; //
GeoJsonPoint geoJsonPoint = GeoJsonPoint.of(12, 34);
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.of(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)));
GeoJsonGeometryCollection geoJsonGeometryCollection = GeoJsonGeometryCollection
.of(Arrays.asList(geoJsonPoint, geoJsonPolygon));
Map<String, Object> map = geoJsonToMapConverter.convert(geoJsonGeometryCollection);
String json = Document.from(map).toJson();
assertEquals(expected, json, false);
}
@Test // DATAES-930
@DisplayName("should be converted from a Map")
void shouldBeConvertedFromAMap() {
String json = "{\n" + //
" \"type\": \"GeometryCollection\",\n" + //
" \"geometries\": [\n" + //
" {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12.0, 34.0]\n" + //
" },\n" + //
" {\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0], [90.0, 12.0], [12.0, 34.0]]\n" + //
" ]\n" + //
" }\n" + //
" ]\n" + //
"}\n"; //
Document document = Document.parse(json);
GeoJsonPoint geoJsonPoint = GeoJsonPoint.of(12, 34);
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.of(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)));
GeoJsonGeometryCollection expected = GeoJsonGeometryCollection.of(Arrays.asList(geoJsonPoint, geoJsonPolygon));
GeoJson<? extends Iterable<?>> geoJsonGeometryCollection = mapToGeoJsonConverter.convert(document);
assertThat(geoJsonGeometryCollection).isInstanceOf(GeoJsonGeometryCollection.class).isEqualTo(expected);
}
}
}
}

View File

@ -41,6 +41,7 @@ import java.util.Map;
import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
@ -56,6 +57,14 @@ import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.geo.GeoJsonEntity;
import org.springframework.data.elasticsearch.core.geo.GeoJsonGeometryCollection;
import org.springframework.data.elasticsearch.core.geo.GeoJsonLineString;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiLineString;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPoint;
import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPolygon;
import org.springframework.data.elasticsearch.core.geo.GeoJsonPoint;
import org.springframework.data.elasticsearch.core.geo.GeoJsonPolygon;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
@ -889,6 +898,300 @@ public class MappingElasticsearchConverterUnitTests {
assertEquals(expected, document.toJson(), false);
}
@Nested
class GeoJsonUnitTests {
private GeoJsonEntity entity;
@BeforeEach
void setup() {
GeoJsonMultiLineString multiLineString = GeoJsonMultiLineString.of(Arrays.asList( //
GeoJsonLineString.of(new Point(12, 34), new Point(56, 78)), //
GeoJsonLineString.of(new Point(90, 12), new Point(34, 56)) //
));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon //
.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)) //
.withInnerRing(new Point(21, 43), new Point(65, 87), new Point(9, 21), new Point(21, 43));
GeoJsonMultiPolygon geoJsonMultiPolygon = GeoJsonMultiPolygon.of(
Arrays.asList(GeoJsonPolygon.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)),
GeoJsonPolygon.of(new Point(21, 43), new Point(65, 87), new Point(9, 21), new Point(21, 43))));
GeoJsonPoint geoJsonPoint = GeoJsonPoint.of(12, 34);
GeoJsonGeometryCollection geoJsonGeometryCollection = GeoJsonGeometryCollection
.of(Arrays.asList(GeoJsonPoint.of(12, 34), GeoJsonPolygon
.of(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)))));
entity = GeoJsonEntity.builder() //
.id("42") //
.point1(GeoJsonPoint.of(12, 34)) //
.point2(GeoJsonPoint.of(56, 78)) //
.multiPoint1(GeoJsonMultiPoint.of(new Point(12, 34), new Point(56, 78), new Point(90, 12))) //
.multiPoint2(GeoJsonMultiPoint.of(new Point(90, 12), new Point(56, 78), new Point(12, 34))) //
.lineString1(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12))) //
.lineString2(GeoJsonLineString.of(new Point(90, 12), new Point(56, 78), new Point(12, 34))) //
.multiLineString1(multiLineString) //
.multiLineString2(multiLineString) //
.polygon1(geoJsonPolygon) //
.polygon2(geoJsonPolygon) //
.multiPolygon1(geoJsonMultiPolygon) //
.multiPolygon2(geoJsonMultiPolygon) //
.geometryCollection1(geoJsonGeometryCollection) //
.geometryCollection2(geoJsonGeometryCollection) //
.build();
}
@Test // DATAES-930
@DisplayName("should write GeoJson properties")
void shouldWriteGeoJsonProperties() throws JSONException {
String json = "{\n" + //
" \"id\": \"42\",\n" + //
" \"point1\": {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12.0, 34.0]\n" + //
" },\n" + //
" \"point2\": {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [56.0, 78.0]\n" + //
" },\n" + //
" \"multiPoint1\": {\n" + //
" \"type\": \"MultiPoint\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34.0],\n" + //
" [56.0, 78.0],\n" + //
" [90.0, 12.0]\n" + //
" ]\n" + //
" },\n" + //
" \"multiPoint2\": {\n" + //
" \"type\": \"MultiPoint\",\n" + //
" \"coordinates\": [\n" + //
" [90.0, 12.0],\n" + //
" [56.0, 78.0],\n" + //
" [12.0, 34.0]\n" + //
" ]\n" + //
" },\n" + //
" \"lineString1\": {\n" + //
" \"type\": \"LineString\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34.0],\n" + //
" [56.0, 78.0],\n" + //
" [90.0, 12.0]\n" + //
" ]\n" + //
" },\n" + //
" \"lineString2\": {\n" + //
" \"type\": \"LineString\",\n" + //
" \"coordinates\": [\n" + //
" [90.0, 12.0],\n" + //
" [56.0, 78.0],\n" + //
" [12.0, 34.0]\n" + //
" ]\n" + //
" },\n" + //
" \"multiLineString1\":{\n" + //
" \"type\": \"MultiLineString\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0]],\n" + //
" [[90.0, 12.0], [34.0, 56.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"multiLineString2\":{\n" + //
" \"type\": \"MultiLineString\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0]],\n" + //
" [[90.0, 12.0], [34.0, 56.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"polygon1\":{\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0],[56.0, 78.0],[90.0, 12.0],[12.0, 34.0]],\n" + //
" [[21.0, 43.0],[65.0, 87.0],[9.0, 21.0],[21.0, 43.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"polygon2\":{\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0],[56.0, 78.0],[90.0, 12.0],[12.0, 34.0]],\n" + //
" [[21.0, 43.0],[65.0, 87.0],[9.0, 21.0],[21.0, 43.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"multiPolygon1\":{\n" + //
" \"type\": \"MultiPolygon\",\n" + //
" \"coordinates\": [\n" + //
" [[[12.0, 34.0],[56.0, 78.0],[90.0, 12.0],[12.0, 34.0]]],\n" + //
" [[[21.0, 43.0],[65.0, 87.0],[9.0, 21.0],[21.0, 43.0]]]\n" + //
" ]\n" + //
" },\n" + //
" \"multiPolygon2\":{\n" + //
" \"type\": \"MultiPolygon\",\n" + //
" \"coordinates\": [\n" + //
" [[[12.0, 34.0],[56.0, 78.0],[90.0, 12.0],[12.0, 34.0]]],\n" + //
" [[[21.0, 43.0],[65.0, 87.0],[9.0, 21.0],[21.0, 43.0]]]\n" + //
" ]\n" + //
" },\n" + //
" \"geometryCollection1\": {\n" + //
" \"type\": \"GeometryCollection\",\n" + //
" \"geometries\": [\n" + //
" {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12.0, 34.0]\n" + //
" },\n" + //
" {\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0], [90.0, 12.0], [12.0, 34.0]]\n" + //
" ]\n" + //
" }\n" + //
" ]\n" + //
" },\n" + //
" \"geometryCollection2\": {\n" + //
" \"type\": \"GeometryCollection\",\n" + //
" \"geometries\": [\n" + //
" {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12.0, 34.0]\n" + //
" },\n" + //
" {\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34.0], [56.0, 78.0], [90.0, 12.0], [12.0, 34.0]]\n" + //
" ]\n" + //
" }\n" + //
" ]\n" + //
" }\n" + //
"}\n"; //
Document document = Document.create();
mappingElasticsearchConverter.write(entity, document);
assertEquals(json, document.toJson(), false);
}
@Test // DATAES-930
@DisplayName("should read GeoJson properties")
void shouldReadGeoJsonProperties() {
// make sure we can read int values as well
String json = "{\n" + //
" \"id\": \"42\",\n" + //
" \"point1\": {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12, 34]\n" + //
" },\n" + //
" \"point2\": {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [56, 78]\n" + //
" },\n" + //
" \"multiPoint1\": {\n" + //
" \"type\": \"MultiPoint\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34],\n" + //
" [56, 78.0],\n" + //
" [90, 12.0]\n" + //
" ]\n" + //
" },\n" + //
" \"multiPoint2\": {\n" + //
" \"type\": \"MultiPoint\",\n" + //
" \"coordinates\": [\n" + //
" [90, 12.0],\n" + //
" [56, 78.0],\n" + //
" [12.0, 34]\n" + //
" ]\n" + //
" },\n" + //
" \"lineString1\": {\n" + //
" \"type\": \"LineString\",\n" + //
" \"coordinates\": [\n" + //
" [12.0, 34],\n" + //
" [56, 78.0],\n" + //
" [90, 12.0]\n" + //
" ]\n" + //
" },\n" + //
" \"lineString2\": {\n" + //
" \"type\": \"LineString\",\n" + //
" \"coordinates\": [\n" + //
" [90, 12.0],\n" + //
" [56, 78.0],\n" + //
" [12.0, 34]\n" + //
" ]\n" + //
" },\n" + //
" \"multiLineString1\":{\n" + //
" \"type\": \"MultiLineString\",\n" + //
" \"coordinates\": [\n" + //
" [[12, 34.0], [56, 78.0]],\n" + //
" [[90.0, 12], [34.0, 56]]\n" + //
" ]\n" + //
" },\n" + //
" \"multiLineString2\":{\n" + //
" \"type\": \"MultiLineString\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34], [56.0, 78]],\n" + //
" [[90, 12.0], [34, 56.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"polygon1\":{\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12, 34.0],[56.0, 78],[90, 12.0],[12.0, 34]],\n" + //
" [[21.0, 43],[65, 87.0],[9.0, 21],[21, 43.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"polygon2\":{\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12, 34.0],[56.0, 78],[90, 12.0],[12.0, 34]],\n" + //
" [[21.0, 43],[65, 87.0],[9.0, 21],[21, 43.0]]\n" + //
" ]\n" + //
" },\n" + //
" \"multiPolygon1\":{\n" + //
" \"type\": \"MultiPolygon\",\n" + //
" \"coordinates\": [\n" + //
" [[[12, 34.0],[56.0, 78],[90, 12.0],[12.0, 34]]],\n" + //
" [[[21.0, 43],[65, 87.0],[9.0, 21],[21, 43.0]]]\n" + //
" ]\n" + //
" },\n" + //
" \"multiPolygon2\":{\n" + //
" \"type\": \"MultiPolygon\",\n" + //
" \"coordinates\": [\n" + //
" [[[12, 34.0],[56.0, 78],[90, 12.0],[12.0, 34]]],\n" + //
" [[[21.0, 43],[65, 87.0],[9.0, 21],[21, 43.0]]]\n" + //
" ]\n" + //
" },\n" + //
" \"geometryCollection1\": {\n" + //
" \"type\": \"GeometryCollection\",\n" + //
" \"geometries\": [\n" + //
" {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12, 34.0]\n" + //
" },\n" + //
" {\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34], [56, 78.0], [90.0, 12], [12, 34.0]]\n" + //
" ]\n" + //
" }\n" + //
" ]\n" + //
" },\n" + //
" \"geometryCollection2\": {\n" + //
" \"type\": \"GeometryCollection\",\n" + //
" \"geometries\": [\n" + //
" {\n" + //
" \"type\": \"Point\",\n" + //
" \"coordinates\": [12, 34.0]\n" + //
" },\n" + //
" {\n" + //
" \"type\": \"Polygon\",\n" + //
" \"coordinates\": [\n" + //
" [[12.0, 34], [56, 78.0], [90.0, 12], [12, 34.0]]\n" + //
" ]\n" + //
" }\n" + //
" ]\n" + //
" }\n" + //
"}\n"; //
GeoJsonEntity mapped = mappingElasticsearchConverter.read(GeoJsonEntity.class, Document.parse(json));
assertThat(entity).isEqualTo(mapped);
}
}
private String pointTemplate(String name, Point point) {
return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getY(), point.getX());
}
@ -1138,4 +1441,5 @@ public class MappingElasticsearchConverterUnitTests {
@Field(type = FieldType.Text) private String notSaved;
@Field(type = FieldType.Text, storeNullValue = true) private String saved;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.geo.Point;
/**
* this class contains each GeoJson type as explicit type and as GeoJson interface. Used by several test classes
*/
@Data
@Builder
@Document(indexName = "geojson-index")
public class GeoJsonEntity {
@Id private String id;
GeoJsonPoint point1;
GeoJson<? extends Iterable<?>> point2;
GeoJsonMultiPoint multiPoint1;
GeoJson<Iterable<Point>> multiPoint2;
GeoJsonLineString lineString1;
GeoJson<Iterable<Point>> lineString2;
GeoJsonMultiLineString multiLineString1;
GeoJson<Iterable<GeoJsonLineString>> multiLineString2;
GeoJsonPolygon polygon1;
GeoJson<Iterable<GeoJsonLineString>> polygon2;
GeoJsonMultiPolygon multiPolygon1;
GeoJson<Iterable<GeoJsonPolygon>> multiPolygon2;
GeoJsonGeometryCollection geometryCollection1;
GeoJson<Iterable<GeoJson<?>>> geometryCollection2;
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonGeometryCollectionUnitTests {
@Test // DATAES-930
@DisplayName("should accept a list of GeoJson objects")
void shouldAcceptAListOfGeoJsonObjects() {
GeoJsonPoint geoJsonPoint = GeoJsonPoint.of(12, 34);
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.of(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)));
GeoJsonGeometryCollection geoJsonGeometryCollection = GeoJsonGeometryCollection
.of(Arrays.asList(geoJsonPoint, geoJsonPolygon));
assertThat(geoJsonGeometryCollection.getGeometries()).containsExactly(geoJsonPoint, geoJsonPolygon);
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.geo.Point;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Peter-Josef Meisch
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class })
@DisplayName("GeoJson integration test with REST client")
class GeoJsonIntegrationTest {
@Autowired private ElasticsearchOperations operations;
private IndexOperations indexOps;
@BeforeEach
void setUp() {
indexOps = operations.indexOps(GeoJsonEntity.class);
indexOps.delete();
indexOps.create();
indexOps.putMapping();
}
@AfterEach
void tearDown() {
indexOps.delete();
}
@Test // DATAES-930
@DisplayName("should write and read an entity with GeoJson properties")
void shouldWriteAndReadAnEntityWithGeoJsonProperties() {
GeoJsonMultiLineString multiLineString = GeoJsonMultiLineString.of(Arrays.asList( //
GeoJsonLineString.of(new Point(12, 34), new Point(56, 78)), //
GeoJsonLineString.of(new Point(90, 12), new Point(34, 56)) //
));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34))
.withInnerRing(new Point(21, 43), new Point(65, 87), new Point(9, 21), new Point(21, 43));
GeoJsonMultiPolygon geoJsonMultiPolygon = GeoJsonMultiPolygon
.of(Arrays.asList(GeoJsonPolygon.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)),
GeoJsonPolygon.of(new Point(21, 43), new Point(65, 87), new Point(9, 21), new Point(21, 43))));
GeoJsonGeometryCollection geoJsonGeometryCollection = GeoJsonGeometryCollection
.of(Arrays.asList(GeoJsonPoint.of(12, 34), GeoJsonPolygon
.of(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(12, 34)))));
GeoJsonEntity entity = GeoJsonEntity.builder() //
.id("42") //
.point1(GeoJsonPoint.of(12, 34)) //
.point2(GeoJsonPoint.of(56, 78)) //
.multiPoint1(GeoJsonMultiPoint.of(new Point(12, 34), new Point(56, 78), new Point(90, 12))) //
.multiPoint2(GeoJsonMultiPoint.of(new Point(90, 12), new Point(56, 78), new Point(12, 34))) //
.lineString1(GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12))) //
.lineString2(GeoJsonLineString.of(new Point(90, 12), new Point(56, 78), new Point(12, 34))) //
.multiLineString1(multiLineString) //
.multiLineString2(multiLineString) //
.polygon1(geoJsonPolygon) //
.polygon2(geoJsonPolygon) //
.multiPolygon1(geoJsonMultiPolygon) //
.multiPolygon2(geoJsonMultiPolygon) //
.geometryCollection1(geoJsonGeometryCollection) //
.geometryCollection2(geoJsonGeometryCollection) //
.build(); //
operations.save(entity);
indexOps.refresh();
GeoJsonEntity result = operations.get("42", GeoJsonEntity.class);
assertThat(result).isEqualTo(entity);
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonLineStringUnitTests {
@Test // DATAES-930
@DisplayName("should accept list of Point")
void shouldAcceptListOfPoint() {
List<Point> points = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12));
GeoJsonLineString geoJsonLineString = GeoJsonLineString.of(points);
List<Point> coordinates = geoJsonLineString.getCoordinates();
assertThat(coordinates).containsExactlyElementsOf(points);
}
@Test // DATAES-930
@DisplayName("should accept array of Point")
void shouldAcceptVarargArrayOfPoint() {
Point[] points = new Point[] { new Point(12, 34), new Point(56, 78), new Point(90, 12) };
GeoJsonLineString geoJsonLineString = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12));
List<Point> coordinates = geoJsonLineString.getCoordinates();
assertThat(coordinates).containsExactly(points);
}
@Test // DATAES-930
@DisplayName("should accept list of GeoPoint")
void shouldAcceptListOfGeoPoint() {
List<Point> points = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12));
List<GeoPoint> geoPoints = points.stream().map(GeoPoint::fromPoint).collect(Collectors.toList());
GeoJsonLineString geoJsonLineString = GeoJsonLineString.ofGeoPoints(geoPoints);
List<Point> coordinates = geoJsonLineString.getCoordinates();
assertThat(coordinates).containsExactlyElementsOf(points);
}
@Test // DATAES-930
@DisplayName("should accept array of Point")
void shouldAcceptVarargArrayOfGeoPoint() {
Point[] points = new Point[] { new Point(12, 34), new Point(56, 78), new Point(90, 12) };
GeoPoint[] geoPoints = Arrays.stream(points).map(GeoPoint::fromPoint).toArray(value -> new GeoPoint[points.length]);
GeoJsonLineString geoJsonLineString = GeoJsonLineString.of(geoPoints[0], geoPoints[1], geoPoints[2]);
List<Point> coordinates = geoJsonLineString.getCoordinates();
assertThat(coordinates).containsExactly(points);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonMultiLineStringUnitTests {
@Test // DATAES-930
@DisplayName("should accept list of GeoJsonLineString")
void shouldAcceptListOfGeoJsonLineString() {
List<GeoJsonLineString> lines = Arrays.asList( //
GeoJsonLineString.of(new Point(12, 34), new Point(56, 78)), //
GeoJsonLineString.of(new Point(90, 12), new Point(34, 56)) //
);
GeoJsonMultiLineString geoJsonMultiLineString = GeoJsonMultiLineString.of(lines);
Iterable<GeoJsonLineString> coordinates = geoJsonMultiLineString.getCoordinates();
assertThat(coordinates).containsExactlyElementsOf(lines);
}
@Test // DATAES-930
@DisplayName("should accept an array of List of Point")
void shouldAcceptAnArrayOfListOfPoint() {
List<Point>[] lists = new List[] { //
Arrays.asList(new Point(12, 34), new Point(56, 78)), //
Arrays.asList(new Point(90, 12), new Point(34, 56)) //
};
List<GeoJsonLineString> lines = Arrays.stream(lists).map(GeoJsonLineString::of).collect(Collectors.toList());
GeoJsonMultiLineString geoJsonMultiLineString = GeoJsonMultiLineString.of(lists);
Iterable<GeoJsonLineString> coordinates = geoJsonMultiLineString.getCoordinates();
assertThat(coordinates).containsExactlyElementsOf(lines);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonMultiPointUnitTests {
@Test // DATAES-930
@DisplayName("should accept list of Point")
void shouldAcceptListOfPoint() {
List<Point> points = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12));
GeoJsonMultiPoint geoJsonMultiPoint = GeoJsonMultiPoint.of(points);
List<Point> coordinates = geoJsonMultiPoint.getCoordinates();
assertThat(coordinates).containsExactlyElementsOf(points);
}
@Test // DATAES-930
@DisplayName("should accept array of Point")
void shouldAcceptVarargArrayOfPoint() {
Point[] points = new Point[] { new Point(12, 34), new Point(56, 78), new Point(90, 12) };
GeoJsonMultiPoint geoJsonMultiPoint = GeoJsonMultiPoint.of(new Point(12, 34), new Point(56, 78), new Point(90, 12));
List<Point> coordinates = geoJsonMultiPoint.getCoordinates();
assertThat(coordinates).containsExactly(points);
}
@Test // DATAES-930
@DisplayName("should accept list of GeoPoint")
void shouldAcceptListOfGeoPoint() {
List<Point> points = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12));
List<GeoPoint> geoPoints = points.stream().map(GeoPoint::fromPoint).collect(Collectors.toList());
GeoJsonMultiPoint geoJsonMultiPoint = GeoJsonMultiPoint.ofGeoPoints(geoPoints);
List<Point> coordinates = geoJsonMultiPoint.getCoordinates();
assertThat(coordinates).containsExactlyElementsOf(points);
}
@Test // DATAES-930
@DisplayName("should accept array of Point")
void shouldAcceptVarargArrayOfGeoPoint() {
Point[] points = new Point[] { new Point(12, 34), new Point(56, 78), new Point(90, 12) };
GeoPoint[] geoPoints = Arrays.stream(points).map(GeoPoint::fromPoint).toArray(value -> new GeoPoint[points.length]);
GeoJsonMultiPoint geoJsonMultiPoint = GeoJsonMultiPoint.of(geoPoints[0], geoPoints[1], geoPoints[2]);
List<Point> coordinates = geoJsonMultiPoint.getCoordinates();
assertThat(coordinates).containsExactly(points);
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonMultiPolygonUnitTests {
@Test // DATAES-930
@DisplayName("should accept a list of GeoJsonPolygons")
void shouldAcceptAListOfGeoJsonPolygons() {
List<Point> pointList1 = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(34, 56));
List<Point> pointList2 = Arrays.asList(new Point(56, 78), new Point(90, 12), new Point(34, 56), new Point(12, 34));
GeoJsonPolygon geoJsonPolygon1 = GeoJsonPolygon.of(pointList1.get(0), pointList1.get(1), pointList1.get(2),
pointList1.get(3));
GeoJsonPolygon geoJsonPolygon2 = GeoJsonPolygon.of(pointList2.get(0), pointList2.get(1), pointList2.get(2),
pointList2.get(3));
GeoJsonMultiPolygon geoJsonMultiPolygon = GeoJsonMultiPolygon.of(Arrays.asList(geoJsonPolygon1, geoJsonPolygon2));
assertThat(geoJsonMultiPolygon.getCoordinates()).containsExactly(geoJsonPolygon1, geoJsonPolygon2);
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonPointUnitTests {
@Test // DATAES-930
@DisplayName("should return x and y as coordinates")
void shouldReturnXAndYAsCoordinates() {
GeoJsonPoint geoJsonPoint = GeoJsonPoint.of(12, 34);
List<Double> coordinates = geoJsonPoint.getCoordinates();
assertThat(coordinates).containsExactly(12d, 34d);
}
@Test // DATAES-930
@DisplayName("should accept a Point as parameter")
void shouldAcceptAPointAsParameter() {
GeoJsonPoint geoJsonPoint1 = GeoJsonPoint.of(12, 34);
GeoJsonPoint geoJsonPoint2 = GeoJsonPoint.of(new Point(12, 34));
assertThat(geoJsonPoint1).isEqualTo(geoJsonPoint2);
}
@Test // DATAES-930
@DisplayName("should accept a GeoPoint as parameter")
void shouldAcceptAGeoPointAsParameter() {
GeoJsonPoint geoJsonPoint1 = GeoJsonPoint.of(12, 34);
GeoJsonPoint geoJsonPoint2 = GeoJsonPoint.of(new GeoPoint(34, 12));
assertThat(geoJsonPoint1).isEqualTo(geoJsonPoint2);
}
}

View File

@ -0,0 +1,95 @@
package org.springframework.data.elasticsearch.core.geo;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.geo.Point;
/**
* @author Peter-Josef Meisch
*/
class GeoJsonPolygonUnitTests {
@Test // DATAES-930
@DisplayName("should accept a GeoJsonLineString")
void shouldAcceptAGeoJsonLineString() {
GeoJsonLineString geoJsonLineString = GeoJsonLineString.of(new Point(12, 34), new Point(56, 78), new Point(90, 12),
new Point(34, 56));
GeoJsonLineString innerRing = GeoJsonLineString.of(new Point(56, 78), new Point(90, 12), new Point(34, 56),
new Point(12, 34));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon.of(geoJsonLineString).withInnerRing(innerRing);
assertThat(geoJsonPolygon.getCoordinates()).containsExactly(geoJsonLineString, innerRing);
}
@Test // DATES-930
@DisplayName("should accept a list of Points")
void shouldAcceptAListOfPoints() {
List<Point> pointList = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(34, 56));
List<Point> innerRingPointList = Arrays.asList(new Point(56, 78), new Point(90, 12), new Point(34, 56),
new Point(12, 34));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon.of(pointList).withInnerRing(innerRingPointList);
assertThat(geoJsonPolygon.getCoordinates()).containsExactly(GeoJsonLineString.of(pointList),
GeoJsonLineString.of(innerRingPointList));
}
@Test // DATES-930
@DisplayName("should accept a list of GeoPoints")
void shouldAcceptAListOfGeoPoints() {
List<Point> pointList = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(34, 56));
List<Point> innerRingPointList = Arrays.asList(new Point(56, 78), new Point(90, 12), new Point(34, 56),
new Point(12, 34));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.ofGeoPoints(pointList.stream().map(GeoPoint::fromPoint).collect(Collectors.toList()))
.withInnerRingOfGeoPoints(innerRingPointList.stream().map(GeoPoint::fromPoint).collect(Collectors.toList()));
assertThat(geoJsonPolygon.getCoordinates()).containsExactly(GeoJsonLineString.of(pointList),
GeoJsonLineString.of(innerRingPointList));
}
@Test // DATES-930
@DisplayName("should accept an array of points")
void shouldAcceptAnArrayOfPoints() {
List<Point> pointList = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(34, 56));
List<Point> innerRingPointList = Arrays.asList(new Point(56, 78), new Point(90, 12), new Point(34, 56),
new Point(12, 34));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.of(pointList.get(0), pointList.get(1), pointList.get(2), pointList.get(3)).withInnerRing(
innerRingPointList.get(0), innerRingPointList.get(1), innerRingPointList.get(2), innerRingPointList.get(3));
assertThat(geoJsonPolygon.getCoordinates()).containsExactly(GeoJsonLineString.of(pointList),
GeoJsonLineString.of(innerRingPointList));
}
@Test // DATES-930
@DisplayName("should accept an array of GeoPoints")
void shouldAcceptAnArrayOfGeoPoints() {
List<Point> pointList = Arrays.asList(new Point(12, 34), new Point(56, 78), new Point(90, 12), new Point(34, 56));
List<Point> innerRingPointList = Arrays.asList(new Point(56, 78), new Point(90, 12), new Point(34, 56),
new Point(12, 34));
GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon
.of(GeoPoint.fromPoint(pointList.get(0)), GeoPoint.fromPoint(pointList.get(1)),
GeoPoint.fromPoint(pointList.get(2)), GeoPoint.fromPoint(pointList.get(3)))
.withInnerRing(GeoPoint.fromPoint(innerRingPointList.get(0)), GeoPoint.fromPoint(innerRingPointList.get(1)),
GeoPoint.fromPoint(innerRingPointList.get(2)), GeoPoint.fromPoint(innerRingPointList.get(3)));
assertThat(geoJsonPolygon.getCoordinates()).containsExactly(GeoJsonLineString.of(pointList),
GeoJsonLineString.of(innerRingPointList));
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.geo;
import org.junit.jupiter.api.DisplayName;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Peter-Josef Meisch
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
@DisplayName("GeoJson integration test with transport client")
public class GeoJsonTransportIntegrationTest extends GeoJsonIntegrationTest {}

View File

@ -49,6 +49,12 @@ public class ElasticsearchRestTemplateConfiguration extends AbstractElasticsearc
ClientConfiguration.TerminalClientConfigurationBuilder configurationBuilder = ClientConfiguration.builder()
.connectedTo(elasticsearchHostPort);
String proxy = System.getenv("DATAES_ELASTICSEARCH_PROXY");
if (proxy != null) {
configurationBuilder = configurationBuilder.withProxy(proxy);
}
if (clusterConnectionInfo.isUseSsl()) {
configurationBuilder = ((ClientConfiguration.MaybeSecureClientConfigurationBuilder) configurationBuilder)
.usingSsl();