DATAMONGO-1466 - Add embedded typeinformation-based reading GeoJSON converter.
Original pull request: #561.
This commit is contained in:
committed by
Mark Paluch
parent
f56bb16a12
commit
5217e7a7e0
@@ -50,7 +50,7 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Wrapper class to contain useful geo structure converters for the usage with Mongo.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
@@ -66,7 +66,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Returns the geo converters to be registered.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -92,12 +92,13 @@ abstract class GeoConverters {
|
||||
, DbObjectToGeoJsonMultiLineStringConverter.INSTANCE //
|
||||
, DbObjectToGeoJsonMultiPointConverter.INSTANCE //
|
||||
, DbObjectToGeoJsonMultiPolygonConverter.INSTANCE //
|
||||
, DbObjectToGeoJsonGeometryCollectionConverter.INSTANCE);
|
||||
, DbObjectToGeoJsonGeometryCollectionConverter.INSTANCE //
|
||||
, DbObjectToGeoJsonConverter.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link List} of {@link Double}s into a {@link Point}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -129,7 +130,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link Point} into a {@link List} of {@link Double}s.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -149,7 +150,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link Box} into a {@link BasicDBList}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -178,7 +179,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link Box}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -207,7 +208,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link Circle} into a {@link BasicDBList}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -236,7 +237,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link DBObject} into a {@link Circle}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -278,7 +279,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link Sphere} into a {@link BasicDBList}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -307,7 +308,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link Sphere}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -349,7 +350,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link Polygon} into a {@link BasicDBList}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -383,7 +384,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link Polygon}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -419,7 +420,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a {@link Sphere} into a {@link BasicDBList}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@@ -757,7 +758,7 @@ abstract class GeoConverters {
|
||||
* @author Christoph Strobl
|
||||
* @since 1.7
|
||||
*/
|
||||
static enum DbObjectToGeoJsonGeometryCollectionConverter implements Converter<DBObject, GeoJsonGeometryCollection> {
|
||||
enum DbObjectToGeoJsonGeometryCollectionConverter implements Converter<DBObject, GeoJsonGeometryCollection> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@@ -778,8 +779,9 @@ abstract class GeoConverters {
|
||||
|
||||
List<GeoJson<?>> geometries = new ArrayList<GeoJson<?>>();
|
||||
for (Object o : (List) source.get("geometries")) {
|
||||
geometries.add(convertGeometries((DBObject) o));
|
||||
geometries.add(toGenericGeoJson((DBObject) o));
|
||||
}
|
||||
|
||||
return new GeoJsonGeometryCollection(geometries);
|
||||
|
||||
}
|
||||
@@ -820,7 +822,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a coordinate pairs nested in in {@link BasicDBList} into {@link GeoJsonPoint}s.
|
||||
*
|
||||
*
|
||||
* @param listOfCoordinatePairs
|
||||
* @return
|
||||
* @since 1.7
|
||||
@@ -844,7 +846,7 @@ abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Converts a coordinate pairs nested in in {@link BasicDBList} into {@link GeoJsonPolygon}.
|
||||
*
|
||||
*
|
||||
* @param dbList
|
||||
* @return
|
||||
* @since 1.7
|
||||
@@ -853,6 +855,63 @@ abstract class GeoConverters {
|
||||
return new GeoJsonPolygon(toListOfPoint((BasicDBList) dbList.get(0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converter implementation transforming a {@link DbObject} into a concrete {@link GeoJson} based on the embedded
|
||||
* {@literal type} information.
|
||||
*
|
||||
* @since 2.1
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@ReadingConverter
|
||||
enum DbObjectToGeoJsonConverter implements Converter<DBObject, GeoJson> {
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public GeoJson convert(DBObject source) {
|
||||
return toGenericGeoJson(source);
|
||||
}
|
||||
}
|
||||
|
||||
private static GeoJson<?> toGenericGeoJson(DBObject source) {
|
||||
|
||||
String type = String.class.cast(source.get("type"));
|
||||
|
||||
if ("point".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonPointConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
if ("multipoint".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonMultiPointConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
if ("linestring".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonLineStringConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
if ("multilinestring".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonMultiLineStringConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
if ("polygon".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonPolygonConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
if ("multipolygon".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonMultiPolygonConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
if ("geometrycollection".equalsIgnoreCase(type)) {
|
||||
return DbObjectToGeoJsonGeometryCollectionConverter.INSTANCE.convert(source);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
String.format("No converter found capable of converting GeoJson type %s.", type));
|
||||
}
|
||||
|
||||
private static double toPrimitiveDoubleValue(Object value) {
|
||||
|
||||
Assert.isInstanceOf(Number.class, value, "Argument must be a Number.");
|
||||
|
||||
@@ -20,6 +20,8 @@ import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -192,8 +194,9 @@ public class GeoJsonTests {
|
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType();
|
||||
obj.id = "geoJsonMultiLineString";
|
||||
obj.geoJsonMultiLineString = new GeoJsonMultiLineString(Arrays.asList(new GeoJsonLineString(new Point(0, 0),
|
||||
new Point(0, 1), new Point(1, 1)), new GeoJsonLineString(new Point(199, 0), new Point(2, 3))));
|
||||
obj.geoJsonMultiLineString = new GeoJsonMultiLineString(
|
||||
Arrays.asList(new GeoJsonLineString(new Point(0, 0), new Point(0, 1), new Point(1, 1)),
|
||||
new GeoJsonLineString(new Point(199, 0), new Point(2, 3))));
|
||||
|
||||
template.save(obj);
|
||||
|
||||
@@ -223,8 +226,8 @@ public class GeoJsonTests {
|
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType();
|
||||
obj.id = "geoJsonMultiPolygon";
|
||||
obj.geoJsonMultiPolygon = new GeoJsonMultiPolygon(Arrays.asList(new GeoJsonPolygon(new Point(0, 0),
|
||||
new Point(0, 1), new Point(1, 1), new Point(0, 0))));
|
||||
obj.geoJsonMultiPolygon = new GeoJsonMultiPolygon(
|
||||
Arrays.asList(new GeoJsonPolygon(new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(0, 0))));
|
||||
|
||||
template.save(obj);
|
||||
|
||||
@@ -239,9 +242,8 @@ public class GeoJsonTests {
|
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType();
|
||||
obj.id = "geoJsonGeometryCollection";
|
||||
obj.geoJsonGeometryCollection = new GeoJsonGeometryCollection(Arrays.<GeoJson<?>> asList(
|
||||
new GeoJsonPoint(100, 200), new GeoJsonPolygon(new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1,
|
||||
0), new Point(0, 0))));
|
||||
obj.geoJsonGeometryCollection = new GeoJsonGeometryCollection(Arrays.<GeoJson<?>> asList(new GeoJsonPoint(100, 200),
|
||||
new GeoJsonPolygon(new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 0), new Point(0, 0))));
|
||||
|
||||
template.save(obj);
|
||||
|
||||
@@ -288,7 +290,8 @@ public class GeoJsonTests {
|
||||
new CollectionCallback<Object>() {
|
||||
|
||||
@Override
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
public Object doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
|
||||
BasicDBObject pointRepresentation = new BasicDBObject();
|
||||
pointRepresentation.put("type", "Point");
|
||||
@@ -313,7 +316,8 @@ public class GeoJsonTests {
|
||||
new CollectionCallback<Object>() {
|
||||
|
||||
@Override
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
public Object doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
|
||||
BasicDBObject lineStringRepresentation = new BasicDBObject();
|
||||
lineStringRepresentation.put("type", "LineString");
|
||||
@@ -335,6 +339,27 @@ public class GeoJsonTests {
|
||||
is(equalTo(new GeoJsonLineString(new Point(0D, 0D), new Point(1, 1)))));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1466
|
||||
public void readGeoJsonBasedOnEmbeddedTypeInformation() {
|
||||
|
||||
Point first = new Point(-73.99756, 40.73083);
|
||||
Point second = new Point(-73.99756, 40.741404);
|
||||
Point third = new Point(-73.988135, 40.741404);
|
||||
Point fourth = new Point(-73.988135, 40.73083);
|
||||
|
||||
GeoJsonPolygon polygon = new GeoJsonPolygon(first, second, third, fourth, first);
|
||||
|
||||
ConcreteGeoJson source = new ConcreteGeoJson();
|
||||
source.shape = polygon;
|
||||
source.id = "id-1";
|
||||
|
||||
template.save(source);
|
||||
|
||||
OpenGeoJson target = template.findOne(query(where("id").is(source.id)), OpenGeoJson.class);
|
||||
|
||||
assertThat(target.shape, is(equalTo((GeoJson) source.shape)));
|
||||
}
|
||||
|
||||
private void addVenues() {
|
||||
|
||||
template.insert(new Venue2DSphere("Penn Station", -73.99408, 40.75057));
|
||||
@@ -353,8 +378,8 @@ public class GeoJsonTests {
|
||||
|
||||
protected void createIndex() {
|
||||
dropIndex();
|
||||
template.indexOps(Venue2DSphere.class).ensureIndex(
|
||||
new GeospatialIndex("location").typed(GeoSpatialIndexType.GEO_2DSPHERE));
|
||||
template.indexOps(Venue2DSphere.class)
|
||||
.ensureIndex(new GeospatialIndex("location").typed(GeoSpatialIndexType.GEO_2DSPHERE));
|
||||
}
|
||||
|
||||
protected void dropIndex() {
|
||||
@@ -414,4 +439,18 @@ public class GeoJsonTests {
|
||||
GeoJsonGeometryCollection geoJsonGeometryCollection;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Document(collection = "geo-json-shapes")
|
||||
static class ConcreteGeoJson {
|
||||
String id;
|
||||
GeoJsonPolygon shape;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Document(collection = "geo-json-shapes")
|
||||
static class OpenGeoJson {
|
||||
String id;
|
||||
GeoJson shape;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user