package org.mongodb.morphia.query;
import org.junit.Before;
import org.junit.Test;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.TestBase;
import org.mongodb.morphia.geo.AllTheThings;
import org.mongodb.morphia.geo.Area;
import org.mongodb.morphia.geo.City;
import org.mongodb.morphia.geo.GeoJson;
import org.mongodb.morphia.geo.Regions;
import org.mongodb.morphia.geo.Route;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mongodb.morphia.geo.GeoJson.geometryCollection;
import static org.mongodb.morphia.geo.GeoJson.lineString;
import static org.mongodb.morphia.geo.GeoJson.multiPoint;
import static org.mongodb.morphia.geo.GeoJson.multiPolygon;
import static org.mongodb.morphia.geo.GeoJson.point;
import static org.mongodb.morphia.geo.GeoJson.polygon;
import static org.mongodb.morphia.geo.PointBuilder.pointBuilder;
public class GeoNearQueriesTest extends TestBase {
@Override
@Before
public void setUp() {
// this whole test class is designed for "modern" geo queries
checkMinServerVersion(2.4);
super.setUp();
}
@Test
public void shouldFindAreasCloseToAGivenPointWithinARadiusOfMeters() {
// given
Area sevilla = new Area("Spain", polygon(pointBuilder().latitude(37.40759155713022).longitude(-5.964911067858338).build(),
pointBuilder().latitude(37.40341208875179).longitude(-5.9643941558897495).build(),
pointBuilder().latitude(37.40297396667302).longitude(-5.970452763140202).build(),
pointBuilder().latitude(37.40759155713022).longitude(-5.964911067858338).build())
);
getDs().save(sevilla);
Area newYork = new Area("New York", polygon(pointBuilder().latitude(40.75981395319104).longitude(-73.98302106186748).build(),
pointBuilder().latitude(40.7636824529618).longitude(-73.98049869574606).build(),
pointBuilder().latitude(40.76962974853814).longitude(-73.97964206524193).build(),
pointBuilder().latitude(40.75981395319104).longitude(-73.98302106186748).build()));
getDs().save(newYork);
Area london = new Area("London", polygon(pointBuilder().latitude(51.507780365645885).longitude(-0.21786745637655258).build(),
pointBuilder().latitude(51.50802478194237).longitude(-0.21474729292094707).build(),
pointBuilder().latitude(51.5086863655597).longitude(-0.20895397290587425).build(),
pointBuilder().latitude(51.507780365645885).longitude(-0.21786745637655258).build()));
getDs().save(london);
getDs().ensureIndexes();
// when
List<Area> routesOrderedByDistanceFromLondon = getDs().find(Area.class)
.field("area")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build(), 20000)
.asList();
// then
assertThat(routesOrderedByDistanceFromLondon.size(), is(1));
assertThat(routesOrderedByDistanceFromLondon.get(0), is(london));
}
@Test
public void shouldFindAreasOrderedByDistanceFromAGivenPoint() {
// given
Area sevilla = new Area("Spain", polygon(pointBuilder().latitude(37.40759155713022).longitude(-5.964911067858338).build(),
pointBuilder().latitude(37.40341208875179).longitude(-5.9643941558897495).build(),
pointBuilder().latitude(37.40297396667302).longitude(-5.970452763140202).build(),
pointBuilder().latitude(37.40759155713022).longitude(-5.964911067858338).build())
);
getDs().save(sevilla);
Area newYork = new Area("New York", polygon(pointBuilder().latitude(40.75981395319104).longitude(-73.98302106186748).build(),
pointBuilder().latitude(40.7636824529618).longitude(-73.98049869574606).build(),
pointBuilder().latitude(40.76962974853814).longitude(-73.97964206524193).build(),
pointBuilder().latitude(40.75981395319104).longitude(-73.98302106186748).build()));
getDs().save(newYork);
Area london = new Area("London", polygon(pointBuilder().latitude(51.507780365645885).longitude(-0.21786745637655258).build(),
pointBuilder().latitude(51.50802478194237).longitude(-0.21474729292094707).build(),
pointBuilder().latitude(51.5086863655597).longitude(-0.20895397290587425).build(),
pointBuilder().latitude(51.507780365645885).longitude(-0.21786745637655258).build()));
getDs().save(london);
getDs().ensureIndexes();
// when
List<Area> routesOrderedByDistanceFromLondon = getDs().find(Area.class)
.field("area")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build())
.asList();
// then
assertThat(routesOrderedByDistanceFromLondon.size(), is(3));
assertThat(routesOrderedByDistanceFromLondon.get(0), is(london));
assertThat(routesOrderedByDistanceFromLondon.get(1), is(sevilla));
assertThat(routesOrderedByDistanceFromLondon.get(2), is(newYork));
}
@Test
public void shouldFindCitiesCloseToAGivenPointWithinARadiusOfMeters() {
// given
double latitude = 51.5286416;
double longitude = -0.1015987;
Datastore datastore = getDs();
City london = new City("London", point(latitude, longitude));
datastore.save(london);
City manchester = new City("Manchester", point(53.4722454, -2.2235922));
datastore.save(manchester);
City sevilla = new City("Sevilla", point(37.3753708, -5.9550582));
datastore.save(sevilla);
getDs().ensureIndexes();
// when
List<City> citiesOrderedByDistanceFromLondon = datastore.find(City.class)
.field("location")
.near(GeoJson.point(latitude, longitude), 200000)
.asList();
// then
assertThat(citiesOrderedByDistanceFromLondon.size(), is(1));
assertThat(citiesOrderedByDistanceFromLondon.get(0), is(london));
}
@Test
public void shouldFindCitiesOrderedByDistanceFromAGivenPoint() {
// given
double latitudeLondon = 51.5286416;
double longitudeLondon = -0.1015987;
City manchester = new City("Manchester", point(53.4722454, -2.2235922));
getDs().save(manchester);
City london = new City("London", point(latitudeLondon, longitudeLondon));
getDs().save(london);
City sevilla = new City("Sevilla", point(37.3753708, -5.9550582));
getDs().save(sevilla);
getDs().ensureIndexes();
// when
List<City> citiesOrderedByDistanceFromLondon;
citiesOrderedByDistanceFromLondon = getDs().find(City.class)
.field("location")
.near(pointBuilder()
.latitude(latitudeLondon)
.longitude(longitudeLondon).build())
.asList();
// then
assertThat(citiesOrderedByDistanceFromLondon.size(), is(3));
assertThat(citiesOrderedByDistanceFromLondon.get(0), is(london));
assertThat(citiesOrderedByDistanceFromLondon.get(1), is(manchester));
assertThat(citiesOrderedByDistanceFromLondon.get(2), is(sevilla));
}
@Test
public void shouldFindGeometryCollectionsCloseToAGivenPointWithinARadiusOfMeters() {
checkMinServerVersion(2.6);
// given
AllTheThings sevilla = new AllTheThings("Spain", geometryCollection(multiPoint(point(37.40759155713022, -5.964911067858338),
point(37.40341208875179, -5.9643941558897495),
point(37.40297396667302, -5.970452763140202)),
polygon(point(37.40759155713022, -5.964911067858338),
point(37.40341208875179, -5.9643941558897495),
point(37.40297396667302, -5.970452763140202),
point(37.40759155713022, -5.964911067858338)),
polygon(point(37.38744598813355, -6.001141928136349),
point(37.385990973562, -6.002588979899883),
point(37.386126928031445, -6.002463921904564),
point(37.38744598813355, -6.001141928136349))));
getDs().save(sevilla);
// insert something that's not a geocollection
Regions usa = new Regions("US", multiPolygon(polygon(point(40.75981395319104, -73.98302106186748),
point(40.7636824529618, -73.98049869574606),
point(40.76962974853814, -73.97964206524193),
point(40.75981395319104, -73.98302106186748)),
polygon(point(28.326568258926272, -81.60542246885598),
point(28.327541397884488, -81.6022228449583),
point(28.32950334995985, -81.60564735531807),
point(28.326568258926272, -81.60542246885598))));
getDs().save(usa);
AllTheThings london = new AllTheThings("London", geometryCollection(point(53.4722454, -2.2235922),
lineString(point(51.507780365645885, -0.21786745637655258),
point(51.50802478194237, -0.21474729292094707),
point(51.5086863655597, -0.20895397290587425)),
polygon(point(51.498216362670064, 0.0074849557131528854),
point(51.49176875129342, 0.01821178011596203),
point(51.492886897176504, 0.05523204803466797),
point(51.49393044412136, 0.06663135252892971),
point(51.498216362670064, 0.0074849557131528854))));
getDs().save(london);
getDs().ensureIndexes();
// when
List<AllTheThings> resultsOrderedByDistanceFromSeville = getDs().find(AllTheThings.class)
.field("everything")
.near(pointBuilder()
.latitude(37.3753707)
.longitude(-5.9550583).build(), 20000)
.asList();
// then
assertThat(resultsOrderedByDistanceFromSeville.size(), is(1));
assertThat(resultsOrderedByDistanceFromSeville.get(0), is(sevilla));
}
@Test
public void shouldFindGeometryCollectionsOrderedByDistanceFromAGivenPoint() {
checkMinServerVersion(2.6);
// given
AllTheThings sevilla = new AllTheThings("Spain", geometryCollection(multiPoint(point(37.40759155713022, -5.964911067858338),
point(37.40341208875179, -5.9643941558897495),
point(37.40297396667302, -5.970452763140202)),
polygon(point(37.40759155713022, -5.964911067858338),
point(37.40341208875179, -5.9643941558897495),
point(37.40297396667302, -5.970452763140202),
point(37.40759155713022, -5.964911067858338)),
polygon(point(37.38744598813355, -6.001141928136349),
point(37.385990973562, -6.002588979899883),
point(37.386126928031445, -6.002463921904564),
point(37.38744598813355, -6.001141928136349))));
getDs().save(sevilla);
// insert something that's not a geocollection
Regions usa = new Regions("US", multiPolygon(polygon(point(40.75981395319104, -73.98302106186748),
point(40.7636824529618, -73.98049869574606),
point(40.76962974853814, -73.97964206524193),
point(40.75981395319104, -73.98302106186748)),
polygon(point(28.326568258926272, -81.60542246885598),
point(28.327541397884488, -81.6022228449583),
point(28.32950334995985, -81.60564735531807),
point(28.326568258926272, -81.60542246885598))));
getDs().save(usa);
AllTheThings london = new AllTheThings("London", geometryCollection(point(53.4722454, -2.2235922),
lineString(point(51.507780365645885, -0.21786745637655258),
point(51.50802478194237, -0.21474729292094707),
point(51.5086863655597, -0.20895397290587425)),
polygon(point(51.498216362670064, 0.0074849557131528854),
point(51.49176875129342, 0.01821178011596203),
point(51.492886897176504, 0.05523204803466797),
point(51.49393044412136, 0.06663135252892971),
point(51.498216362670064, 0.0074849557131528854))));
getDs().save(london);
getDs().ensureIndexes();
// when
List<AllTheThings> resultsOrderedByDistanceFromLondon = getDs().find(AllTheThings.class)
.field("everything")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build())
.asList();
// then
assertThat(resultsOrderedByDistanceFromLondon.size(), is(2));
assertThat(resultsOrderedByDistanceFromLondon.get(0), is(london));
assertThat(resultsOrderedByDistanceFromLondon.get(1), is(sevilla));
}
@Test
public void shouldFindRegionsCloseToAGivenPointWithinARadiusOfMeters() {
checkMinServerVersion(2.6);
// given
Regions sevilla = new Regions("Spain", multiPolygon(polygon(point(37.40759155713022, -5.964911067858338),
point(37.40341208875179, -5.9643941558897495),
point(37.40297396667302, -5.970452763140202),
point(37.40759155713022, -5.964911067858338)),
polygon(point(37.38744598813355, -6.001141928136349),
point(37.385990973562, -6.002588979899883),
point(37.386126928031445, -6.002463921904564),
point(37.38744598813355, -6.001141928136349))));
getDs().save(sevilla);
Regions usa = new Regions("US", multiPolygon(polygon(point(40.75981395319104, -73.98302106186748),
point(40.7636824529618, -73.98049869574606),
point(40.76962974853814, -73.97964206524193),
point(40.75981395319104, -73.98302106186748)),
polygon(point(28.326568258926272, -81.60542246885598),
point(28.327541397884488, -81.6022228449583),
point(28.32950334995985, -81.60564735531807),
point(28.326568258926272, -81.60542246885598))));
getDs().save(usa);
Regions london = new Regions("London", multiPolygon(polygon(point(51.507780365645885, -0.21786745637655258),
point(51.50802478194237, -0.21474729292094707),
point(51.5086863655597, -0.20895397290587425),
point(51.507780365645885, -0.21786745637655258)),
polygon(point(51.498216362670064, 0.0074849557131528854),
point(51.49176875129342, 0.01821178011596203),
point(51.492886897176504, 0.05523204803466797),
point(51.49393044412136, 0.06663135252892971),
point(51.498216362670064, 0.0074849557131528854))));
getDs().save(london);
getDs().ensureIndexes();
// when
List<Regions> regionsOrderedByDistanceFromLondon = getDs().find(Regions.class)
.field("regions")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build(), 20000)
.asList();
// then
assertThat(regionsOrderedByDistanceFromLondon.size(), is(1));
assertThat(regionsOrderedByDistanceFromLondon.get(0), is(london));
}
@Test
public void shouldFindRegionsOrderedByDistanceFromAGivenPoint() {
checkMinServerVersion(2.6);
// given
Regions sevilla = new Regions("Spain", multiPolygon(polygon(point(37.40759155713022, -5.964911067858338),
point(37.40341208875179, -5.9643941558897495),
point(37.40297396667302, -5.970452763140202),
point(37.40759155713022, -5.964911067858338)),
polygon(point(37.38744598813355, -6.001141928136349),
point(37.385990973562, -6.002588979899883),
point(37.386126928031445, -6.002463921904564),
point(37.38744598813355, -6.001141928136349))));
getDs().save(sevilla);
Regions usa = new Regions("US", multiPolygon(polygon(point(40.75981395319104, -73.98302106186748),
point(40.7636824529618, -73.98049869574606),
point(40.76962974853814, -73.97964206524193),
point(40.75981395319104, -73.98302106186748)),
polygon(point(28.326568258926272, -81.60542246885598),
point(28.327541397884488, -81.6022228449583),
point(28.32950334995985, -81.60564735531807),
point(28.326568258926272, -81.60542246885598))));
getDs().save(usa);
Regions london = new Regions("London", multiPolygon(polygon(point(51.507780365645885, -0.21786745637655258),
point(51.50802478194237, -0.21474729292094707),
point(51.5086863655597, -0.20895397290587425),
point(51.507780365645885, -0.21786745637655258)),
polygon(point(51.498216362670064, 0.0074849557131528854),
point(51.49176875129342, 0.01821178011596203),
point(51.492886897176504, 0.05523204803466797),
point(51.49393044412136, 0.06663135252892971),
point(51.498216362670064, 0.0074849557131528854))));
getDs().save(london);
getDs().ensureIndexes();
// when
List<Regions> regionsOrderedByDistanceFromLondon = getDs().find(Regions.class)
.field("regions")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build())
.asList();
// then
assertThat(regionsOrderedByDistanceFromLondon.size(), is(3));
assertThat(regionsOrderedByDistanceFromLondon.get(0), is(london));
assertThat(regionsOrderedByDistanceFromLondon.get(1), is(sevilla));
assertThat(regionsOrderedByDistanceFromLondon.get(2), is(usa));
}
@Test
public void shouldFindRoutesCloseToAGivenPointWithinARadiusOfMeters() {
// given
Route sevilla = new Route("Spain", lineString(pointBuilder().latitude(37.40759155713022).longitude(-5.964911067858338).build(),
pointBuilder().latitude(37.40341208875179).longitude(-5.9643941558897495).build(),
pointBuilder().latitude(37.40297396667302).longitude(-5.970452763140202).build()));
getDs().save(sevilla);
Route newYork = new Route("New York", lineString(pointBuilder().latitude(40.75981395319104).longitude(-73.98302106186748).build(),
pointBuilder().latitude(40.7636824529618).longitude(-73.98049869574606).build(),
pointBuilder().latitude(40.76962974853814).longitude(-73.97964206524193).build()));
getDs().save(newYork);
Route london = new Route("London", lineString(pointBuilder().latitude(51.507780365645885).longitude(-0.21786745637655258).build(),
pointBuilder().latitude(51.50802478194237).longitude(-0.21474729292094707).build(),
pointBuilder().latitude(51.5086863655597).longitude(-0.20895397290587425).build()));
getDs().save(london);
getDs().ensureIndexes();
// when
List<Route> routesOrderedByDistanceFromLondon = getDs().find(Route.class)
.field("route")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build(), 20000)
.asList();
// then
assertThat(routesOrderedByDistanceFromLondon.size(), is(1));
assertThat(routesOrderedByDistanceFromLondon.get(0), is(london));
}
@Test
public void shouldFindRoutesOrderedByDistanceFromAGivenPoint() {
// given
Route sevilla = new Route("Spain", lineString(pointBuilder().latitude(37.40759155713022).longitude(-5.964911067858338).build(),
pointBuilder().latitude(37.40341208875179).longitude(-5.9643941558897495).build(),
pointBuilder().latitude(37.40297396667302).longitude(-5.970452763140202).build()));
getDs().save(sevilla);
Route newYork = new Route("New York", lineString(pointBuilder().latitude(40.75981395319104).longitude(-73.98302106186748).build(),
pointBuilder().latitude(40.7636824529618).longitude(-73.98049869574606).build(),
pointBuilder().latitude(40.76962974853814).longitude(-73.97964206524193).build()));
getDs().save(newYork);
Route london = new Route("London", lineString(pointBuilder().latitude(51.507780365645885).longitude(-0.21786745637655258).build(),
pointBuilder().latitude(51.50802478194237).longitude(-0.21474729292094707).build(),
pointBuilder().latitude(51.5086863655597).longitude(-0.20895397290587425).build()));
getDs().save(london);
getDs().ensureIndexes();
// when
List<Route> routesOrderedByDistanceFromLondon = getDs().find(Route.class)
.field("route")
.near(pointBuilder()
.latitude(51.5286416)
.longitude(-0.1015987).build())
.asList();
// then
assertThat(routesOrderedByDistanceFromLondon.size(), is(3));
assertThat(routesOrderedByDistanceFromLondon.get(0), is(london));
assertThat(routesOrderedByDistanceFromLondon.get(1), is(sevilla));
assertThat(routesOrderedByDistanceFromLondon.get(2), is(newYork));
}
}