package org.mongodb.morphia.query; import org.junit.Before; import org.junit.Test; 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.Point; 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 GeoIntersectsQueriesWithPointTest 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 shouldFindAPointThatExactlyMatchesTheQueryPoint() { // given Point coordsOfManchester = point(53.4722454, -2.2235922); City manchester = new City("Manchester", coordsOfManchester); getDs().save(manchester); City london = new City("London", point(51.5286416, -0.1015987)); getDs().save(london); City sevilla = new City("Sevilla", point(37.3753708, -5.9550582)); getDs().save(sevilla); getDs().ensureIndexes(); // when List<City> matchingCity = getDs().find(City.class) .field("location") .intersects(coordsOfManchester) .asList(); // then assertThat(matchingCity.size(), is(1)); assertThat(matchingCity.get(0), is(manchester)); } @Test public void shouldFindAreasWhereTheGivenPointIsOnTheBoundary() { // 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> areaContainingPoint = getDs().find(Area.class) .field("area") .intersects(point(51.507780365645885, -0.21786745637655258)) .asList(); // then assertThat(areaContainingPoint.size(), is(1)); assertThat(areaContainingPoint.get(0), is(london)); } @Test public void shouldFindGeometryCollectionsWhereTheGivenPointIntersectsWithOneOfTheEntities() { 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> everythingInTheUK = getDs().find(AllTheThings.class) .field("everything") .intersects(point(51.50802478194237, -0.21474729292094707)) .asList(); // then assertThat(everythingInTheUK.size(), is(1)); assertThat(everythingInTheUK.get(0), is(london)); } @Test public void shouldFindRegionsWhereTheGivenPointIsOnABoundary() { 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> regionsInTheUK = getDs().find(Regions.class) .field("regions") .intersects(point(51.498216362670064, 0.0074849557131528854)) .asList(); // then assertThat(regionsInTheUK.size(), is(1)); assertThat(regionsInTheUK.get(0), is(london)); } @Test public void shouldFindRoutesThatAGivenPointIsOn() { // 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); Route londonToParis = new Route("London To Paris", lineString(pointBuilder().latitude(51.5286416) .longitude(-0.1015987).build(), pointBuilder().latitude(48.858859).longitude(2.3470599).build())); getDs().save(londonToParis); getDs().ensureIndexes(); // when List<Route> routeContainingPoint = getDs().find(Route.class) .field("route") .intersects(point(37.40759155713022, -5.964911067858338)) .asList(); // then assertThat(routeContainingPoint.size(), is(1)); assertThat(routeContainingPoint.get(0), is(sevilla)); } }