package org.mongodb.morphia.geo;
import org.junit.Test;
import org.mongodb.morphia.TestBase;
import org.mongodb.morphia.query.Shape;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
/**
* Although this tests the old legacy coordinate system of storing location, this set of tests shows the functionality that's available
* with
* these coordinates in later versions of the server that also support GeoJSON. In order to get full geo querying functionality, you
* should
* use GeoJSON for storing your location not legacy co-ordinates.
* <p/>
* This test requires server version 2.4 or above as it uses $geoWithin.
*/
public class LegacyCoordsWithWithinQueries extends TestBase {
@Test
public void shouldNotReturnAnyPointsIfNothingInsideCircle() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords point = new PlaceWithLegacyCoords(new double[]{1, 1}, "place");
getDs().save(point);
getDs().ensureIndexes();
// when - search with circle that does not cover the only point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.center(new Shape.Point(2, 2), 0.5))
.get();
// then
assertThat(found, is(nullValue()));
}
@Test
public void shouldNotReturnAnyValuesWhenTheQueryBoxDoesNotContainAnyPoints() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords point = new PlaceWithLegacyCoords(new double[]{1, 1}, "place");
getDs().save(point);
getDs().ensureIndexes();
// when - search with a box that does not cover the point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.box(new Shape.Point(0, 0), new Shape.Point(0.5, 0.5)))
.get();
// then
assertThat(found, is(nullValue()));
}
@Test
public void shouldNotReturnAnyValuesWhenTheQueryPolygonDoesNotContainAnyPoints() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords point = new PlaceWithLegacyCoords(new double[]{7.3, 9.2}, "place");
getDs().save(point);
getDs().ensureIndexes();
// when - search with polygon that's nowhere near the given point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.polygon(new Shape.Point(0, 0),
new Shape.Point(0, 5),
new Shape.Point(2, 3),
new Shape.Point(1, 0)))
.get();
// then
assertThat(found, is(nullValue()));
}
@Test
public void shouldReturnAPointThatIsFullyWithinQueryPolygon() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords expectedPoint = new PlaceWithLegacyCoords(new double[]{1, 1}, "place");
getDs().save(expectedPoint);
getDs().ensureIndexes();
// when - search with polygon that contains expected point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.polygon(new Shape.Point(0, 0),
new Shape.Point(0, 5),
new Shape.Point(2, 3),
new Shape.Point(1, 0)))
.get();
// then
assertThat(found, is(expectedPoint));
}
@Test
public void shouldReturnOnlyThePointsWithinTheGivenCircle() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords expectedPoint = new PlaceWithLegacyCoords(new double[]{1.1, 2.3}, "Near point");
getDs().save(expectedPoint);
final PlaceWithLegacyCoords otherPoint = new PlaceWithLegacyCoords(new double[]{3.1, 5.2}, "Further point");
getDs().save(otherPoint);
getDs().ensureIndexes();
// when
final List<PlaceWithLegacyCoords> found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.center(new Shape.Point(1, 2), 1.1))
.asList();
// then
assertThat(found.size(), is(1));
assertThat(found.get(0), is(expectedPoint));
}
@Test
public void shouldReturnPointOnBoundaryOfQueryCircle() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords expectedPoint = new PlaceWithLegacyCoords(new double[]{1, 1}, "place");
getDs().save(expectedPoint);
getDs().ensureIndexes();
// when - search with circle with an edge that exactly covers the point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.center(new Shape.Point(0, 1), 1))
.get();
// then
assertThat(found, is(expectedPoint));
}
@Test
public void shouldReturnPointOnBoundaryOfQueryCircleWithSphericalGeometry() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords expectedPoint = new PlaceWithLegacyCoords(new double[]{1, 1}, "place");
getDs().save(expectedPoint);
getDs().ensureIndexes();
// when - search with circle with an edge that exactly covers the point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.centerSphere(new Shape.Point(0, 1), 1))
.get();
// then
assertThat(found, is(expectedPoint));
}
@Test
public void shouldReturnPointThatIsFullyInsideTheQueryBox() throws Exception {
// given
checkMinServerVersion(2.4);
final PlaceWithLegacyCoords expectedPoint = new PlaceWithLegacyCoords(new double[]{1, 1}, "place");
getDs().save(expectedPoint);
getDs().ensureIndexes();
// when - search with a box that covers the whole point
final PlaceWithLegacyCoords found = getDs().find(PlaceWithLegacyCoords.class)
.field("location")
.within(Shape.box(new Shape.Point(0, 0), new Shape.Point(2, 2)))
.get();
// then
assertThat(found, is(expectedPoint));
}
}