Browse Source
We’ve added special types representing GeoJson structures. This allows to use those within both queries and domain types. GeoJson types should only be used in combination with a 2dsphere index as 2d index is not able to handle the structure. Though legacy coordinate pairs and GeoJson types can be mixed inside MongoDB, we currently do not support conversion of legacy coordinates to GeoJson types.pull/277/head
16 changed files with 2210 additions and 13 deletions
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
/** |
||||
* Interface definition for structures defined in GeoJSON ({@link http://geojson.org/}) format.
|
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
*/ |
||||
public interface GeoJson<T extends Iterable<?>> { |
||||
|
||||
/** |
||||
* String value representing the type of the {@link GeoJson} object. |
||||
* |
||||
* @return never {@literal null}. |
||||
* @see http://geojson.org/geojson-spec.html#geojson-objects
|
||||
*/ |
||||
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 never {@literal null}. |
||||
* @see http://geojson.org/geojson-spec.html#geometry-objects
|
||||
*/ |
||||
T getCoordinates(); |
||||
} |
||||
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* Defines a {@link GeoJsonGeometryCollection} that consists of a {@link List} of {@link GeoJson} objects. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
* @see http://geojson.org/geojson-spec.html#geometry-collection
|
||||
*/ |
||||
public class GeoJsonGeometryCollection implements GeoJson<Iterable<GeoJson<?>>> { |
||||
|
||||
private static final String TYPE = "GeometryCollection"; |
||||
private final List<GeoJson<?>> geometries = new ArrayList<GeoJson<?>>(); |
||||
|
||||
/** |
||||
* @param geometries |
||||
*/ |
||||
public GeoJsonGeometryCollection(List<GeoJson<?>> geometries) { |
||||
|
||||
Assert.notNull(geometries); |
||||
this.geometries.addAll(geometries); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates() |
||||
*/ |
||||
@Override |
||||
public Iterable<GeoJson<?>> getCoordinates() { |
||||
return Collections.unmodifiableList(this.geometries); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#hashCode() |
||||
*/ |
||||
@Override |
||||
public int hashCode() { |
||||
return ObjectUtils.nullSafeHashCode(this.geometries); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#equals(java.lang.Object) |
||||
*/ |
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null) { |
||||
return false; |
||||
} |
||||
if (!(obj instanceof GeoJsonGeometryCollection)) { |
||||
return false; |
||||
} |
||||
GeoJsonGeometryCollection other = (GeoJsonGeometryCollection) obj; |
||||
return ObjectUtils.nullSafeEquals(this.geometries, other.geometries); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.data.geo.Point; |
||||
|
||||
/** |
||||
* {@link GeoJsonLineString} is defined as list of at least 2 {@link Point}s. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
* @see http://geojson.org/geojson-spec.html#linestring
|
||||
*/ |
||||
public class GeoJsonLineString extends GeoJsonMultiPoint { |
||||
|
||||
private static final String TYPE = "LineString"; |
||||
|
||||
/** |
||||
* @param points must not be {@literal null} and have at least 2 entries. |
||||
*/ |
||||
public GeoJsonLineString(List<Point> points) { |
||||
super(points); |
||||
} |
||||
|
||||
/** |
||||
* @param p0 must not be {@literal null} |
||||
* @param p1 must not be {@literal null} |
||||
* @param others can be {@literal null} |
||||
*/ |
||||
public GeoJsonLineString(Point p0, Point p1, Point... others) { |
||||
super(p0, p1, others); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJsonMultiPoint#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.data.geo.Point; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* {@link GeoJsonMultiLineString} is defined as list of {@link GeoJsonLineString}s. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
* @see http://geojson.org/geojson-spec.html#multilinestring
|
||||
*/ |
||||
public class GeoJsonMultiLineString implements GeoJson<Iterable<GeoJsonLineString>> { |
||||
|
||||
private static final String TYPE = "MultiLineString"; |
||||
private List<GeoJsonLineString> coordinates = new ArrayList<GeoJsonLineString>(); |
||||
|
||||
/** |
||||
* Creates new {@link GeoJsonMultiLineString}. |
||||
* |
||||
* @param lines must not be {@literal null}. |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
public GeoJsonMultiLineString(List<Point>... lines) { |
||||
|
||||
Assert.notEmpty(lines, "Lines for MultiLineString must not be null!"); |
||||
for (List<Point> line : lines) { |
||||
this.coordinates.add(new GeoJsonLineString(line)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param lines must not be {@literal null}. |
||||
*/ |
||||
public GeoJsonMultiLineString(List<GeoJsonLineString> lines) { |
||||
|
||||
Assert.notNull(lines, "Lines for MultiLineString must not be null!"); |
||||
this.coordinates.addAll(lines); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates() |
||||
*/ |
||||
@Override |
||||
public Iterable<GeoJsonLineString> getCoordinates() { |
||||
return Collections.unmodifiableList(this.coordinates); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#hashCode() |
||||
*/ |
||||
@Override |
||||
public int hashCode() { |
||||
return ObjectUtils.nullSafeHashCode(this.coordinates); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#equals(java.lang.Object) |
||||
*/ |
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null) { |
||||
return false; |
||||
} |
||||
if (!(obj instanceof GeoJsonMultiLineString)) { |
||||
return false; |
||||
} |
||||
return ObjectUtils.nullSafeEquals(this.coordinates, ((GeoJsonMultiLineString) obj).coordinates); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.data.geo.Point; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* {@link GeoJsonMultiPoint} is defined as list of {@link Point}s. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
* @see http://geojson.org/geojson-spec.html#multipoint
|
||||
*/ |
||||
public class GeoJsonMultiPoint implements GeoJson<Iterable<Point>> { |
||||
|
||||
private static final String TYPE = "MultiPoint"; |
||||
private final List<Point> points; |
||||
|
||||
/** |
||||
* @param points points must not be {@literal null} and have at least 2 entries. |
||||
*/ |
||||
public GeoJsonMultiPoint(List<Point> points) { |
||||
|
||||
Assert.notNull(points, "Points must not be null."); |
||||
Assert.isTrue(points.size() >= 2, "Minimum of 2 Points required."); |
||||
|
||||
this.points = new ArrayList<Point>(points); |
||||
} |
||||
|
||||
public GeoJsonMultiPoint(Point p0, Point p1, Point... others) { |
||||
|
||||
this.points = new ArrayList<Point>(); |
||||
this.points.add(p0); |
||||
this.points.add(p1); |
||||
if (!ObjectUtils.isEmpty(others)) { |
||||
this.points.addAll(Arrays.asList(others)); |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates() |
||||
*/ |
||||
@Override |
||||
public List<Point> getCoordinates() { |
||||
return Collections.unmodifiableList(this.points); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#hashCode() |
||||
*/ |
||||
@Override |
||||
public int hashCode() { |
||||
return ObjectUtils.nullSafeHashCode(this.points); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#equals(java.lang.Object) |
||||
*/ |
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null) { |
||||
return false; |
||||
} |
||||
if (!(obj instanceof GeoJsonMultiPoint)) { |
||||
return false; |
||||
} |
||||
return ObjectUtils.nullSafeEquals(this.points, ((GeoJsonMultiPoint) obj).points); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* {@link GeoJsonMultiPolygon} is defined as a list of {@link GeoJsonPolygon}s. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
*/ |
||||
public class GeoJsonMultiPolygon implements GeoJson<Iterable<GeoJsonPolygon>> { |
||||
|
||||
private static final String TYPE = "MultiPolygon"; |
||||
private List<GeoJsonPolygon> coordinates = new ArrayList<GeoJsonPolygon>(); |
||||
|
||||
/** |
||||
* @param polygons must not be {@literal null}. |
||||
*/ |
||||
public GeoJsonMultiPolygon(List<GeoJsonPolygon> polygons) { |
||||
|
||||
Assert.notNull(polygons, "Polygons for MultiPolygon must not be null!"); |
||||
this.coordinates.addAll(polygons); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates() |
||||
*/ |
||||
@Override |
||||
public List<GeoJsonPolygon> getCoordinates() { |
||||
return Collections.unmodifiableList(this.coordinates); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#hashCode() |
||||
*/ |
||||
@Override |
||||
public int hashCode() { |
||||
return ObjectUtils.nullSafeHashCode(this.coordinates); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see java.lang.Object#equals(java.lang.Object) |
||||
*/ |
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null) { |
||||
return false; |
||||
} |
||||
if (!(obj instanceof GeoJsonMultiPolygon)) { |
||||
return false; |
||||
} |
||||
return ObjectUtils.nullSafeEquals(this.coordinates, ((GeoJsonMultiPolygon) obj).coordinates); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.data.geo.Point; |
||||
|
||||
/** |
||||
* {@link GeoJson} representation of {@link Point}. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
* @see http://geojson.org/geojson-spec.html#point
|
||||
*/ |
||||
public class GeoJsonPoint extends Point implements GeoJson<List<Double>> { |
||||
|
||||
private static final long serialVersionUID = -8026303425147474002L; |
||||
private static final String TYPE = "Point"; |
||||
|
||||
/** |
||||
* Creates {@link GeoJsonPoint} for given coordinates. |
||||
* |
||||
* @param x |
||||
* @param y |
||||
*/ |
||||
public GeoJsonPoint(double x, double y) { |
||||
super(x, y); |
||||
} |
||||
|
||||
/** |
||||
* Creates {@link GeoJsonPoint} for given {@link Point}. |
||||
* |
||||
* @param point must not be {@literal null}. |
||||
*/ |
||||
public GeoJsonPoint(Point point) { |
||||
super(point); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates() |
||||
*/ |
||||
@Override |
||||
public List<Double> getCoordinates() { |
||||
return Arrays.asList(Double.valueOf(getX()), Double.valueOf(getY())); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.data.geo.Point; |
||||
import org.springframework.data.geo.Polygon; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* {@link GeoJson} representation of {@link Polygon}. Unlike {@link Polygon} the {@link GeoJsonPolygon} requires a |
||||
* closed border. Which means that the first and last {@link Point} have to have same coordinate pairs. |
||||
* |
||||
* @author Christoph Strobl |
||||
* @since 1.7 |
||||
* @see http://geojson.org/geojson-spec.html#polygon
|
||||
*/ |
||||
public class GeoJsonPolygon extends Polygon implements GeoJson<List<GeoJsonLineString>> { |
||||
|
||||
private static final long serialVersionUID = 3936163018187247185L; |
||||
private static final String TYPE = "Polygon"; |
||||
private List<GeoJsonLineString> coordinates = new ArrayList<GeoJsonLineString>(); |
||||
|
||||
/** |
||||
* Creates new {@link GeoJsonPolygon}. |
||||
* |
||||
* @param p0 must not be {@literal null}. |
||||
* @param p1 must not be {@literal null}. |
||||
* @param p2 must not be {@literal null}. |
||||
* @param p3 must not be {@literal null}. |
||||
* @param others can be {@literal null}. |
||||
*/ |
||||
public GeoJsonPolygon(Point p0, Point p1, Point p2, Point p3, final Point... others) { |
||||
|
||||
this(new ArrayList<Point>(Arrays.asList(p0, p1, p2, p3)) { |
||||
private static final long serialVersionUID = 3143657022446395361L; |
||||
|
||||
{ |
||||
if (!ObjectUtils.isEmpty(others)) { |
||||
for (Point p : others) { |
||||
add(p); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Creates new {@link GeoJsonPolygon}. |
||||
* |
||||
* @param points must not be {@literal null}. |
||||
*/ |
||||
public GeoJsonPolygon(List<Point> points) { |
||||
|
||||
super(points); |
||||
this.coordinates.add(new GeoJsonLineString(points)); |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType() |
||||
*/ |
||||
@Override |
||||
public String getType() { |
||||
return TYPE; |
||||
} |
||||
|
||||
/* |
||||
* (non-Javadoc) |
||||
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates() |
||||
*/ |
||||
@Override |
||||
public List<GeoJsonLineString> getCoordinates() { |
||||
return Collections.unmodifiableList(this.coordinates); |
||||
} |
||||
} |
||||
@ -0,0 +1,450 @@
@@ -0,0 +1,450 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.convert; |
||||
|
||||
import static org.hamcrest.core.IsEqual.*; |
||||
import static org.hamcrest.core.IsNull.*; |
||||
import static org.junit.Assert.*; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
import org.junit.Rule; |
||||
import org.junit.Test; |
||||
import org.junit.rules.ExpectedException; |
||||
import org.junit.runner.RunWith; |
||||
import org.junit.runners.Suite; |
||||
import org.junit.runners.Suite.SuiteClasses; |
||||
import org.springframework.data.geo.Point; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToGeoJsonLineStringConverter; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToGeoJsonMultiLineStringConverter; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToGeoJsonMultiPointConverter; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToGeoJsonMultiPolygonConverter; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToGeoJsonPointConverter; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToGeoJsonPolygonConverter; |
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.GeoJsonToDbObjectConverter; |
||||
import org.springframework.data.mongodb.core.geo.GeoJson; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonGeometryCollection; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonLineString; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonMultiLineString; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonMultiPoint; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonMultiPolygon; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonPoint; |
||||
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; |
||||
import org.springframework.data.mongodb.test.util.BasicDbListBuilder; |
||||
|
||||
import com.mongodb.BasicDBList; |
||||
import com.mongodb.BasicDBObject; |
||||
import com.mongodb.BasicDBObjectBuilder; |
||||
import com.mongodb.DBObject; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
@RunWith(Suite.class) |
||||
@SuiteClasses({ GeoJsonConverterUnitTests.GeoJsonToDbObjectConverterUnitTests.class, |
||||
GeoJsonConverterUnitTests.DbObjectToGeoJsonPointConverterUnitTests.class, |
||||
GeoJsonConverterUnitTests.DbObjectToGeoJsonPolygonConverterUnitTests.class, |
||||
GeoJsonConverterUnitTests.DbObjectToGeoJsonLineStringConverterUnitTests.class, |
||||
GeoJsonConverterUnitTests.DbObjectToGeoJsonMultiPolygonConverterUnitTests.class, |
||||
GeoJsonConverterUnitTests.DbObjectToGeoJsonMultiLineStringConverterUnitTests.class, |
||||
GeoJsonConverterUnitTests.DbObjectToGeoJsonMultiPointConverterUnitTests.class }) |
||||
public class GeoJsonConverterUnitTests { |
||||
|
||||
/* |
||||
* --- GeoJson |
||||
*/ |
||||
static final GeoJsonPoint SINGLE_POINT = new GeoJsonPoint(100, 50); |
||||
|
||||
static final Point POINT_0 = new Point(0, 0); |
||||
static final Point POINT_1 = new Point(100, 0); |
||||
static final Point POINT_2 = new Point(100, 100); |
||||
static final Point POINT_3 = new Point(0, 100); |
||||
|
||||
static final GeoJsonMultiPoint MULTI_POINT = new GeoJsonMultiPoint(POINT_0, POINT_2, POINT_3); |
||||
static final GeoJsonLineString LINE_STRING = new GeoJsonLineString(POINT_0, POINT_1, POINT_2); |
||||
@SuppressWarnings("unchecked") static final GeoJsonMultiLineString MULTI_LINE_STRING = new GeoJsonMultiLineString( |
||||
Arrays.asList(POINT_0, POINT_1, POINT_2), Arrays.asList(POINT_3, POINT_0)); |
||||
static final GeoJsonPolygon POLYGON = new GeoJsonPolygon(POINT_0, POINT_1, POINT_2, POINT_3, POINT_0); |
||||
static final GeoJsonMultiPolygon MULTI_POLYGON = new GeoJsonMultiPolygon(Arrays.asList(POLYGON)); |
||||
static final GeoJsonGeometryCollection GEOMETRY_COLLECTION = new GeoJsonGeometryCollection( |
||||
Arrays.<GeoJson<?>> asList(SINGLE_POINT, POLYGON)); |
||||
/* |
||||
* -- GeoJson DBObjects |
||||
*/ |
||||
|
||||
// Point
|
||||
static final BasicDBList SINGE_POINT_CORDS = new BasicDbListBuilder() //
|
||||
.add(SINGLE_POINT.getX()) //
|
||||
.add(SINGLE_POINT.getY()) //
|
||||
.get(); //
|
||||
static final DBObject SINGLE_POINT_DBO = new BasicDBObjectBuilder() //
|
||||
.add("type", "Point") //
|
||||
.add("coordinates", SINGE_POINT_CORDS)//
|
||||
.get(); |
||||
|
||||
// MultiPoint
|
||||
static final BasicDBList MULTI_POINT_CORDS = new BasicDbListBuilder() //
|
||||
.add(new BasicDbListBuilder().add(POINT_0.getX()).add(POINT_0.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_2.getX()).add(POINT_2.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_3.getX()).add(POINT_3.getY()).get()) //
|
||||
.get(); |
||||
static final DBObject MULTI_POINT_DBO = new BasicDBObjectBuilder() //
|
||||
.add("type", "MultiPoint")//
|
||||
.add("coordinates", MULTI_POINT_CORDS)//
|
||||
.get(); |
||||
|
||||
// Polygon
|
||||
static final BasicDBList POLYGON_OUTER_CORDS = new BasicDbListBuilder() //
|
||||
.add(new BasicDbListBuilder().add(POINT_0.getX()).add(POINT_0.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_1.getX()).add(POINT_1.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_2.getX()).add(POINT_2.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_3.getX()).add(POINT_3.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_0.getX()).add(POINT_0.getY()).get()) //
|
||||
.get(); |
||||
static final BasicDBList POLYGON_CORDS = new BasicDbListBuilder().add(POLYGON_OUTER_CORDS).get(); |
||||
static final DBObject POLYGON_DBO = new BasicDBObjectBuilder() //
|
||||
.add("type", "Polygon") //
|
||||
.add("coordinates", POLYGON_CORDS) //
|
||||
.get(); |
||||
|
||||
// LineString
|
||||
static final BasicDBList LINE_STRING_CORDS_0 = new BasicDbListBuilder() //
|
||||
.add(new BasicDbListBuilder().add(POINT_0.getX()).add(POINT_0.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_1.getX()).add(POINT_1.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_2.getX()).add(POINT_2.getY()).get()) //
|
||||
.get(); |
||||
static final BasicDBList LINE_STRING_CORDS_1 = new BasicDbListBuilder() //
|
||||
.add(new BasicDbListBuilder().add(POINT_3.getX()).add(POINT_3.getY()).get()) //
|
||||
.add(new BasicDbListBuilder().add(POINT_0.getX()).add(POINT_0.getY()).get()) //
|
||||
.get(); |
||||
static final DBObject LINE_STRING_DBO = new BasicDBObjectBuilder().add("type", "LineString") |
||||
.add("coordinates", LINE_STRING_CORDS_0).get(); |
||||
|
||||
// MultiLineString
|
||||
static final BasicDBList MUILT_LINE_STRING_CORDS = new BasicDbListBuilder() //
|
||||
.add(LINE_STRING_CORDS_0) //
|
||||
.add(LINE_STRING_CORDS_1) //
|
||||
.get(); |
||||
static final DBObject MULTI_LINE_STRING_DBO = new BasicDBObjectBuilder().add("type", "MultiLineString") |
||||
.add("coordinates", MUILT_LINE_STRING_CORDS).get(); |
||||
|
||||
// MultiPolygoin
|
||||
static final BasicDBList MULTI_POLYGON_CORDS = new BasicDbListBuilder().add(POLYGON_CORDS).get(); |
||||
static final DBObject MULTI_POLYGON_DBO = new BasicDBObjectBuilder().add("type", "MultiPolygon") |
||||
.add("coordinates", MULTI_POLYGON_CORDS).get(); |
||||
|
||||
// GeometryCollection
|
||||
static final BasicDBList GEOMETRY_COLLECTION_GEOMETRIES = new BasicDbListBuilder() //
|
||||
.add(SINGLE_POINT_DBO)//
|
||||
.add(POLYGON_DBO)//
|
||||
.get(); |
||||
static final DBObject GEOMETRY_COLLECTION_DBO = new BasicDBObjectBuilder().add("type", "GeometryCollection") |
||||
.add("geometries", GEOMETRY_COLLECTION_GEOMETRIES).get(); |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class DbObjectToGeoJsonPolygonConverterUnitTests { |
||||
|
||||
DbObjectToGeoJsonPolygonConverter converter = DbObjectToGeoJsonPolygonConverter.INSTANCE; |
||||
public @Rule ExpectedException expectedException = ExpectedException.none(); |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertDboCorrectly() { |
||||
assertThat(converter.convert(POLYGON_DBO), equalTo(POLYGON)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldReturnNullWhenConvertIsGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldThrowExceptionWhenTypeDoesNotMatchPolygon() { |
||||
|
||||
expectedException.expect(IllegalArgumentException.class); |
||||
expectedException.expectMessage("'YouDontKonwMe' to Polygon"); |
||||
|
||||
converter.convert(new BasicDBObject("type", "YouDontKonwMe")); |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class DbObjectToGeoJsonPointConverterUnitTests { |
||||
|
||||
DbObjectToGeoJsonPointConverter converter = DbObjectToGeoJsonPointConverter.INSTANCE; |
||||
public @Rule ExpectedException expectedException = ExpectedException.none(); |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertDboCorrectly() { |
||||
assertThat(converter.convert(SINGLE_POINT_DBO), equalTo(SINGLE_POINT)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldReturnNullWhenConvertIsGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldThrowExceptionWhenTypeDoesNotMatchPoint() { |
||||
|
||||
expectedException.expect(IllegalArgumentException.class); |
||||
expectedException.expectMessage("'YouDontKonwMe' to Point"); |
||||
|
||||
converter.convert(new BasicDBObject("type", "YouDontKonwMe")); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class DbObjectToGeoJsonLineStringConverterUnitTests { |
||||
|
||||
DbObjectToGeoJsonLineStringConverter converter = DbObjectToGeoJsonLineStringConverter.INSTANCE; |
||||
public @Rule ExpectedException expectedException = ExpectedException.none(); |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertDboCorrectly() { |
||||
assertThat(converter.convert(LINE_STRING_DBO), equalTo(LINE_STRING)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldReturnNullWhenConvertIsGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldThrowExceptionWhenTypeDoesNotMatchPoint() { |
||||
|
||||
expectedException.expect(IllegalArgumentException.class); |
||||
expectedException.expectMessage("'YouDontKonwMe' to LineString"); |
||||
|
||||
converter.convert(new BasicDBObject("type", "YouDontKonwMe")); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class DbObjectToGeoJsonMultiLineStringConverterUnitTests { |
||||
|
||||
DbObjectToGeoJsonMultiLineStringConverter converter = DbObjectToGeoJsonMultiLineStringConverter.INSTANCE; |
||||
public @Rule ExpectedException expectedException = ExpectedException.none(); |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertDboCorrectly() { |
||||
assertThat(converter.convert(MULTI_LINE_STRING_DBO), equalTo(MULTI_LINE_STRING)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldReturnNullWhenConvertIsGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldThrowExceptionWhenTypeDoesNotMatchPoint() { |
||||
|
||||
expectedException.expect(IllegalArgumentException.class); |
||||
expectedException.expectMessage("'YouDontKonwMe' to MultiLineString"); |
||||
|
||||
converter.convert(new BasicDBObject("type", "YouDontKonwMe")); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class DbObjectToGeoJsonMultiPointConverterUnitTests { |
||||
|
||||
DbObjectToGeoJsonMultiPointConverter converter = DbObjectToGeoJsonMultiPointConverter.INSTANCE; |
||||
public @Rule ExpectedException expectedException = ExpectedException.none(); |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertDboCorrectly() { |
||||
assertThat(converter.convert(MULTI_POINT_DBO), equalTo(MULTI_POINT)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldReturnNullWhenConvertIsGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldThrowExceptionWhenTypeDoesNotMatchPoint() { |
||||
|
||||
expectedException.expect(IllegalArgumentException.class); |
||||
expectedException.expectMessage("'YouDontKonwMe' to MultiPoint"); |
||||
|
||||
converter.convert(new BasicDBObject("type", "YouDontKonwMe")); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class DbObjectToGeoJsonMultiPolygonConverterUnitTests { |
||||
|
||||
DbObjectToGeoJsonMultiPolygonConverter converter = DbObjectToGeoJsonMultiPolygonConverter.INSTANCE; |
||||
public @Rule ExpectedException expectedException = ExpectedException.none(); |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertDboCorrectly() { |
||||
assertThat(converter.convert(MULTI_POLYGON_DBO), equalTo(MULTI_POLYGON)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldReturnNullWhenConvertIsGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldThrowExceptionWhenTypeDoesNotMatchPoint() { |
||||
|
||||
expectedException.expect(IllegalArgumentException.class); |
||||
expectedException.expectMessage("'YouDontKonwMe' to MultiPolygon"); |
||||
|
||||
converter.convert(new BasicDBObject("type", "YouDontKonwMe")); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public static class GeoJsonToDbObjectConverterUnitTests { |
||||
|
||||
GeoJsonToDbObjectConverter converter = GeoJsonToDbObjectConverter.INSTANCE; |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
public void convertShouldReturnNullWhenGivenNull() { |
||||
assertThat(converter.convert(null), nullValue()); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeoJsonPointCorrectly() { |
||||
assertThat(converter.convert(SINGLE_POINT), equalTo(SINGLE_POINT_DBO)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeoJsonPolygonCorrectly() { |
||||
assertThat(converter.convert(POLYGON), equalTo(POLYGON_DBO)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeoJsonLineStringCorrectly() { |
||||
assertThat(converter.convert(LINE_STRING), equalTo(LINE_STRING_DBO)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeoJsonMultiLineStringCorrectly() { |
||||
assertThat(converter.convert(MULTI_LINE_STRING), equalTo(MULTI_LINE_STRING_DBO)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeoJsonMultiPointCorrectly() { |
||||
assertThat(converter.convert(MULTI_POINT), equalTo(MULTI_POINT_DBO)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeoJsonMultiPolygonCorrectly() { |
||||
assertThat(converter.convert(MULTI_POLYGON), equalTo(MULTI_POLYGON_DBO)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouldConvertGeometryCollectionCorrectly() { |
||||
assertThat(converter.convert(GEOMETRY_COLLECTION), equalTo(GEOMETRY_COLLECTION_DBO)); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,360 @@
@@ -0,0 +1,360 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.geo; |
||||
|
||||
import static org.hamcrest.Matchers.*; |
||||
import static org.junit.Assert.*; |
||||
import static org.springframework.data.mongodb.core.query.Criteria.*; |
||||
import static org.springframework.data.mongodb.core.query.Query.*; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.data.annotation.Id; |
||||
import org.springframework.data.annotation.PersistenceConstructor; |
||||
import org.springframework.data.geo.GeoResults; |
||||
import org.springframework.data.geo.Metric; |
||||
import org.springframework.data.geo.Metrics; |
||||
import org.springframework.data.geo.Point; |
||||
import org.springframework.data.mongodb.config.AbstractMongoConfiguration; |
||||
import org.springframework.data.mongodb.core.MongoTemplate; |
||||
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; |
||||
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; |
||||
import org.springframework.data.mongodb.core.index.GeospatialIndex; |
||||
import org.springframework.data.mongodb.core.mapping.Document; |
||||
import org.springframework.data.mongodb.core.query.NearQuery; |
||||
import org.springframework.data.mongodb.core.query.Query; |
||||
import org.springframework.test.context.ContextConfiguration; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
|
||||
import com.mongodb.Mongo; |
||||
import com.mongodb.MongoClient; |
||||
import com.mongodb.WriteConcern; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@ContextConfiguration |
||||
public class GeoJsonTests { |
||||
|
||||
@Configuration |
||||
static class TestConfig extends AbstractMongoConfiguration { |
||||
|
||||
@Override |
||||
protected String getDatabaseName() { |
||||
return "database"; |
||||
} |
||||
|
||||
@Override |
||||
public Mongo mongo() throws Exception { |
||||
return new MongoClient(); |
||||
} |
||||
} |
||||
|
||||
@Autowired MongoTemplate template; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE); |
||||
|
||||
createIndex(); |
||||
addVenues(); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() { |
||||
|
||||
dropIndex(); |
||||
removeCollections(); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
@Test |
||||
public void geoNear() { |
||||
|
||||
NearQuery geoNear = NearQuery.near(new GeoJsonPoint(-73, 40), Metrics.KILOMETERS).num(10).maxDistance(150); |
||||
|
||||
GeoResults<Venue2DSphere> result = template.geoNear(geoNear, Venue2DSphere.class); |
||||
|
||||
assertThat(result.getContent().size(), is(not(0))); |
||||
assertThat(result.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
@Test |
||||
public void withinPolygon() { |
||||
|
||||
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); |
||||
|
||||
List<Venue2DSphere> venues = template.find(query(where("location").within(polygon)), Venue2DSphere.class); |
||||
assertThat(venues.size(), is(4)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
@Test |
||||
public void nearPoint() { |
||||
|
||||
GeoJsonPoint point = new GeoJsonPoint(-73.99171, 40.738868); |
||||
|
||||
Query query = query(where("location").near(point).maxDistance(0.01)); |
||||
List<Venue2DSphere> venues = template.find(query, Venue2DSphere.class); |
||||
assertThat(venues.size(), is(1)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1135 |
||||
*/ |
||||
@Test |
||||
public void nearSphere() { |
||||
|
||||
GeoJsonPoint point = new GeoJsonPoint(-73.99171, 40.738868); |
||||
|
||||
Query query = query(where("location").nearSphere(point).maxDistance(0.003712240453784)); |
||||
List<Venue2DSphere> venues = template.find(query, Venue2DSphere.class); |
||||
|
||||
assertThat(venues.size(), is(1)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonPointTypeCorrectly() { |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType(); |
||||
obj.id = "geoJsonPoint"; |
||||
obj.geoJsonPoint = new GeoJsonPoint(100, 50); |
||||
|
||||
template.save(obj); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonPoint, equalTo(obj.geoJsonPoint)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonPolygonTypeCorrectly() { |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType(); |
||||
obj.id = "geoJsonPolygon"; |
||||
obj.geoJsonPolygon = 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); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonPolygon, equalTo(obj.geoJsonPolygon)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonLineStringTypeCorrectly() { |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType(); |
||||
obj.id = "geoJsonLineString"; |
||||
obj.geoJsonLineString = new GeoJsonLineString(new Point(0, 0), new Point(0, 1), new Point(1, 1)); |
||||
|
||||
template.save(obj); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonLineString, equalTo(obj.geoJsonLineString)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonMultiLineStringTypeCorrectly() { |
||||
|
||||
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)))); |
||||
|
||||
template.save(obj); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonMultiLineString, equalTo(obj.geoJsonMultiLineString)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonMultiPointTypeCorrectly() { |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType obj = new DocumentWithPropertyUsingGeoJsonType(); |
||||
obj.id = "geoJsonMultiPoint"; |
||||
obj.geoJsonMultiPoint = new GeoJsonMultiPoint(Arrays.asList(new Point(0, 0), new Point(0, 1), new Point(1, 1))); |
||||
|
||||
template.save(obj); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonMultiPoint, equalTo(obj.geoJsonMultiPoint)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonMultiPolygonTypeCorrectly() { |
||||
|
||||
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)))); |
||||
|
||||
template.save(obj); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonMultiPolygon, equalTo(obj.geoJsonMultiPolygon)); |
||||
} |
||||
|
||||
/** |
||||
* @see DATAMONGO-1137 |
||||
*/ |
||||
@Test |
||||
public void shouleSaveAndRetrieveDocumentWithGeoJsonGeometryCollectionTypeCorrectly() { |
||||
|
||||
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)))); |
||||
|
||||
template.save(obj); |
||||
|
||||
DocumentWithPropertyUsingGeoJsonType result = template.findOne(query(where("id").is(obj.id)), |
||||
DocumentWithPropertyUsingGeoJsonType.class); |
||||
|
||||
assertThat(result.geoJsonGeometryCollection, equalTo(obj.geoJsonGeometryCollection)); |
||||
} |
||||
|
||||
private void addVenues() { |
||||
|
||||
template.insert(new Venue2DSphere("Penn Station", -73.99408, 40.75057)); |
||||
template.insert(new Venue2DSphere("10gen Office", -73.99171, 40.738868)); |
||||
template.insert(new Venue2DSphere("Flatiron Building", -73.988135, 40.741404)); |
||||
template.insert(new Venue2DSphere("Players Club", -73.997812, 40.739128)); |
||||
template.insert(new Venue2DSphere("City Bakery ", -73.992491, 40.738673)); |
||||
template.insert(new Venue2DSphere("Splash Bar", -73.992491, 40.738673)); |
||||
template.insert(new Venue2DSphere("Momofuku Milk Bar", -73.985839, 40.731698)); |
||||
template.insert(new Venue2DSphere("Shake Shack", -73.98820, 40.74164)); |
||||
template.insert(new Venue2DSphere("Penn Station", -73.99408, 40.75057)); |
||||
template.insert(new Venue2DSphere("Empire State Building", -73.98602, 40.74894)); |
||||
template.insert(new Venue2DSphere("Ulaanbaatar, Mongolia", 106.9154, 47.9245)); |
||||
template.insert(new Venue2DSphere("Maplewood, NJ", -74.2713, 40.73137)); |
||||
} |
||||
|
||||
protected void createIndex() { |
||||
dropIndex(); |
||||
template.indexOps(Venue2DSphere.class).ensureIndex( |
||||
new GeospatialIndex("location").typed(GeoSpatialIndexType.GEO_2DSPHERE)); |
||||
} |
||||
|
||||
protected void dropIndex() { |
||||
try { |
||||
template.indexOps(Venue2DSphere.class).dropIndex("location"); |
||||
} catch (Exception e) { |
||||
|
||||
} |
||||
} |
||||
|
||||
protected void removeCollections() { |
||||
template.dropCollection(Venue2DSphere.class); |
||||
template.dropCollection(DocumentWithPropertyUsingGeoJsonType.class); |
||||
} |
||||
|
||||
@Document(collection = "venue2dsphere") |
||||
static class Venue2DSphere { |
||||
|
||||
@Id private String id; |
||||
private String name; |
||||
private @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) double[] location; |
||||
|
||||
@PersistenceConstructor |
||||
public Venue2DSphere(String name, double[] location) { |
||||
this.name = name; |
||||
this.location = location; |
||||
} |
||||
|
||||
public Venue2DSphere(String name, double x, double y) { |
||||
this.name = name; |
||||
this.location = new double[] { x, y }; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public double[] getLocation() { |
||||
return location; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "Venue2DSphere [id=" + id + ", name=" + name + ", location=" + Arrays.toString(location) + "]"; |
||||
} |
||||
} |
||||
|
||||
static class DocumentWithPropertyUsingGeoJsonType { |
||||
|
||||
String id; |
||||
GeoJsonPoint geoJsonPoint; |
||||
GeoJsonPolygon geoJsonPolygon; |
||||
GeoJsonLineString geoJsonLineString; |
||||
GeoJsonMultiLineString geoJsonMultiLineString; |
||||
GeoJsonMultiPoint geoJsonMultiPoint; |
||||
GeoJsonMultiPolygon geoJsonMultiPolygon; |
||||
GeoJsonGeometryCollection geoJsonGeometryCollection; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.test.util; |
||||
|
||||
import com.mongodb.BasicDBList; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
public class BasicDbListBuilder { |
||||
|
||||
private final BasicDBList dbl; |
||||
|
||||
public BasicDbListBuilder() { |
||||
this.dbl = new BasicDBList(); |
||||
} |
||||
|
||||
public BasicDbListBuilder add(Object value) { |
||||
|
||||
this.dbl.add(value); |
||||
return this; |
||||
} |
||||
|
||||
public BasicDBList get() { |
||||
return this.dbl; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,189 @@
@@ -0,0 +1,189 @@
|
||||
/* |
||||
* Copyright 2015 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 |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.test.util; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.NoSuchElementException; |
||||
|
||||
import org.bson.BSONObject; |
||||
import org.hamcrest.Description; |
||||
import org.hamcrest.TypeSafeMatcher; |
||||
import org.hamcrest.core.IsEqual; |
||||
import org.springframework.data.mongodb.core.query.SerializationUtils; |
||||
import org.springframework.util.ClassUtils; |
||||
|
||||
import com.mongodb.DBObject; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @param <T> |
||||
*/ |
||||
public class IsBsonObject<T extends BSONObject> extends TypeSafeMatcher<T> { |
||||
|
||||
private List<ExpectedBsonContent> expectations = new ArrayList<ExpectedBsonContent>();; |
||||
|
||||
public static <T extends BSONObject> IsBsonObject<T> isBsonObject() { |
||||
return new IsBsonObject<T>(); |
||||
} |
||||
|
||||
@Override |
||||
protected void describeMismatchSafely(T item, Description mismatchDescription) { |
||||
mismatchDescription.appendText("was ").appendValue(SerializationUtils.serializeToJsonSafely(item)); |
||||
} |
||||
|
||||
@Override |
||||
public void describeTo(Description description) { |
||||
|
||||
for (ExpectedBsonContent expectation : expectations) { |
||||
|
||||
if (expectation.not) { |
||||
description.appendText(String.format("Path %s should not be present.", expectation.path)); |
||||
} else if (expectation.value == null) { |
||||
description.appendText(String.format("Expected to find path %s.", expectation.path)); |
||||
} else { |
||||
description.appendText(String.format("Expected to find %s for path %s.", expectation.value, expectation.path)); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
@Override |
||||
protected boolean matchesSafely(T item) { |
||||
|
||||
if (expectations.isEmpty()) { |
||||
return true; |
||||
} |
||||
|
||||
for (ExpectedBsonContent expectation : expectations) { |
||||
|
||||
Object o = getValue(item, expectation.path); |
||||
|
||||
if (o == null && expectation.not) { |
||||
return true; |
||||
} |
||||
|
||||
if (o == null) { |
||||
return false; |
||||
} |
||||
|
||||
if (expectation.type != null && !ClassUtils.isAssignable(expectation.type, o.getClass())) { |
||||
return false; |
||||
} |
||||
|
||||
if (expectation.value != null && !new IsEqual<Object>(expectation.value).matches(o)) { |
||||
return false; |
||||
} |
||||
|
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public IsBsonObject<T> containing(String key) { |
||||
|
||||
ExpectedBsonContent expected = new ExpectedBsonContent(); |
||||
expected.path = key; |
||||
|
||||
this.expectations.add(expected); |
||||
return this; |
||||
} |
||||
|
||||
public IsBsonObject<T> containing(String key, Class<?> type) { |
||||
|
||||
ExpectedBsonContent expected = new ExpectedBsonContent(); |
||||
expected.path = key; |
||||
expected.type = type; |
||||
|
||||
this.expectations.add(expected); |
||||
return this; |
||||
} |
||||
|
||||
public IsBsonObject<T> containing(String key, Object value) { |
||||
|
||||
if (value == null) { |
||||
return notContaining(key); |
||||
} |
||||
|
||||
ExpectedBsonContent expected = new ExpectedBsonContent(); |
||||
expected.path = key; |
||||
expected.type = ClassUtils.getUserClass(value); |
||||
expected.value = value; |
||||
|
||||
this.expectations.add(expected); |
||||
return this; |
||||
} |
||||
|
||||
public IsBsonObject<T> notContaining(String key) { |
||||
|
||||
ExpectedBsonContent expected = new ExpectedBsonContent(); |
||||
expected.path = key; |
||||
expected.not = true; |
||||
|
||||
this.expectations.add(expected); |
||||
return this; |
||||
} |
||||
|
||||
static class ExpectedBsonContent { |
||||
String path; |
||||
Class<?> type; |
||||
Object value; |
||||
boolean not = false; |
||||
} |
||||
|
||||
Object getValue(BSONObject source, String path) { |
||||
|
||||
String[] fragments = path.split("\\."); |
||||
if (fragments.length == 1) { |
||||
return source.get(path); |
||||
} |
||||
|
||||
Iterator<String> it = Arrays.asList(fragments).iterator(); |
||||
|
||||
Object current = source; |
||||
while (it.hasNext()) { |
||||
|
||||
String key = it.next(); |
||||
|
||||
if (!(current instanceof BSONObject) && !key.startsWith("[")) { |
||||
return null; |
||||
} |
||||
|
||||
if (key.startsWith("[")) { |
||||
String indexNumber = key.substring(1, key.indexOf("]")); |
||||
if (current instanceof List) { |
||||
current = ((List) current).get(Integer.valueOf(indexNumber)); |
||||
} |
||||
if (!it.hasNext()) { |
||||
return current; |
||||
} |
||||
} else { |
||||
|
||||
if (current instanceof DBObject) { |
||||
current = ((DBObject) current).get(key); |
||||
} |
||||
|
||||
if (!it.hasNext()) { |
||||
return current; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
throw new NoSuchElementException(String.format("Unable to find '%s' in %s.", path, source)); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue