/* * Hibernate Search, full-text search for your domain model * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.test.spatial; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import org.apache.lucene.search.Sort; import org.hibernate.Transaction; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.Search; import org.hibernate.search.annotations.Spatial; import org.hibernate.search.exception.SearchException; import org.hibernate.search.query.dsl.QueryBuilder; import org.hibernate.search.query.dsl.Unit; import org.hibernate.search.spatial.DistanceSortField; import org.hibernate.search.test.SearchTestBase; import org.hibernate.search.testsupport.TestForIssue; import org.hibernate.search.testsupport.junit.SkipOnElasticsearch; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; /** * Hibernate Search spatial : unit tests on indexing POIs in with Grid and Grid+Distance * * @author Nicolas Helleringer * @author Hardy Ferentschik */ public class SpatialIndexingTest extends SearchTestBase { private FullTextSession fullTextSession; @Before public void createAndIndexTestData() throws Exception { fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); // POI fullTextSession.save( new POI( 1, "Distance to 24,32 : 0", 24.0d, 32.0d, "" ) ); fullTextSession.save( new POI( 2, "Distance to 24,32 : 10.16", 24.0d, 31.9d, "" ) ); fullTextSession.save( new POI( 3, "Distance to 24,32 : 11.12", 23.9d, 32.0d, "" ) ); fullTextSession.save( new POI( 4, "Distance to 24,32 : 15.06", 23.9d, 32.1d, "" ) ); fullTextSession.save( new POI( 5, "Distance to 24,32 : 22.24", 24.2d, 32.0d, "" ) ); fullTextSession.save( new POI( 6, "Distance to 24,32 : 24.45", 24.2d, 31.9d, "" ) ); // NonGeoPOI fullTextSession.save( new NonGeoPOI( 1, "Distance to 24,32 : 0", 24.0d, null, "" ) ); fullTextSession.save( new NonGeoPOI( 2, "Distance to 24,32 : 24.45", 24.2d, 31.9d, "" ) ); fullTextSession.save( new NonGeoPOI( 3, "Distance to 24,32 : 10.16", 24.0d, 31.9d, "" ) ); fullTextSession.save( new NonGeoPOI( 4, "Distance to 24,32 : 15.06", 23.9d, 32.1d, "" ) ); fullTextSession.save( new NonGeoPOI( 5, "Distance to 24,32 : 11.12", 23.9d, 32.0d, "" ) ); fullTextSession.save( new NonGeoPOI( 6, "Distance to 24,32 : 22.24", 24.2d, 32.0d, "" ) ); // MissingSpatialPOI fullTextSession.save( new MissingSpatialPOI( 1, "Distance to 24,32 : 0", 24.0d, 32.0d, "" ) ); // Event SimpleDateFormat dateFormat = new SimpleDateFormat( "d M yyyy", Locale.ROOT ); Date date = dateFormat.parse( "10 9 1976" ); fullTextSession.save( new Event( 1, "Test", 24.0d, 32.0d, date ) ); // User fullTextSession.save( new User( 1, 24.0d, 32.0d ) ); // UserRange fullTextSession.save( new UserRange( 1, 24.0d, 32.0d ) ); // UserEx fullTextSession.save( new UserEx( 1, 24.0d, 32.0d, 11.9d, 27.4d ) ); // RangeEvent dateFormat = new SimpleDateFormat( "d M yyyy", Locale.ROOT ); date = dateFormat.parse( "10 9 1976" ); fullTextSession.save( new RangeEvent( 1, "Test", 24.0d, 32.0d, date ) ); // Hotel fullTextSession.save( new Hotel( 1, "Plazza Athénée", 24.0d, 32.0d, "Luxurious" ) ); // RangeHotel fullTextSession.save( new RangeHotel( 1, "Plazza Athénée", 24.0d, 32.0d, "Luxurious" ) ); fullTextSession.save( new RangeHotel( 2, "End of the world Hotel - Left", 0.0d, 179.0d, "Roots" ) ); fullTextSession.save( new RangeHotel( 3, "End of the world Hotel - Right", 0.0d, -179.0d, "Cosy" ) ); // Restaurant fullTextSession.save( new Restaurant( 1, "Al's kitchen", "42, space avenue CA8596 BYOB Street", 24.0d, 32.0d ) ); // GetterUser fullTextSession.save( new GetterUser( 1, 24.0d, 32.0d ) ); //DoubleIndexedPOIs fullTextSession.save( new DoubleIndexedPOI( 1, "Davide D'Alto", 37.780392d, -122.513898d, "Hibernate team member" ) ); fullTextSession.save( new DoubleIndexedPOI( 2, "Peter O'Tall", 40.723165d, -73.987439d, "" ) ); tx.commit(); } @Test @Category(SkipOnElasticsearch.class) // Elasticsearch does not support a radius of 0 (starting from 2.2.0) public void testIndexingRadius0() throws Exception { double centerLatitude = 24; double centerLongitude = 32; assertNumberOfPointsOfInterestWithinRadius( centerLatitude, centerLongitude, 0, 1 ); } @Test public void testIndexing() throws Exception { double centerLatitude = 24; double centerLongitude = 32; assertNumberOfPointsOfInterestWithinRadius( centerLatitude, centerLongitude, 10, 1 ); assertNumberOfPointsOfInterestWithinRadius( centerLatitude, centerLongitude, 20, 4 ); assertNumberOfPointsOfInterestWithinRadius( centerLatitude, centerLongitude, 30, 6 ); } @Test public void testDistanceProjection() throws Exception { double centerLatitude = 24.0d; double centerLongitude = 32.0d; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( POI.class ).get(); org.apache.lucene.search.Query luceneQuery = builder .spatial() .onField( "location" ) .within( 100, Unit.KM ) .ofLatitude( centerLatitude ) .andLongitude( centerLongitude ) .createQuery(); FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, POI.class ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" ); hibQuery.setSort( builder.sort().byDistance().onField( "location" ).fromLatitude( centerLatitude ).andLongitude( centerLongitude ).createSort() ); List results = hibQuery.list(); Object[] firstResult = (Object[]) results.get( 0 ); Object[] secondResult = (Object[]) results.get( 1 ); Object[] thirdResult = (Object[]) results.get( 2 ); Object[] fourthResult = (Object[]) results.get( 3 ); Object[] fifthResult = (Object[]) results.get( 4 ); Object[] sixthResult = (Object[]) results.get( 5 ); Assert.assertEquals( ( (Double) firstResult[1] ), 0.0, 0.0001 ); Assert.assertEquals( ( (Double) secondResult[1] ), 10.1582, 0.01 ); Assert.assertEquals( ( (Double) thirdResult[1] ), 11.1195, 0.01 ); Assert.assertEquals( ( (Double) fourthResult[1] ), 15.0636, 0.01 ); Assert.assertEquals( ( (Double) fifthResult[1] ), 22.239, 0.02 ); Assert.assertEquals( ( (Double) sixthResult[1] ), 24.446, 0.02 ); } @Test public void testDistanceSort() throws Exception { double centerLatitude = 24.0d; double centerLongitude = 32.0d; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( POI.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "location" ) .within( 100, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, POI.class ); Sort distanceSort = new Sort( new DistanceSortField( centerLatitude, centerLongitude, "location" ) ); hibQuery.setSort( distanceSort ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" ); List<Object[]> results = hibQuery.list(); Double previousDistance = (Double) results.get( 0 )[1]; for ( int i = 1; i < results.size(); i++ ) { Object[] projectionEntry = results.get( i ); Double currentDistance = (Double) projectionEntry[1]; assertTrue( previousDistance + " should be < " + currentDistance, previousDistance < currentDistance ); previousDistance = currentDistance; } } @Test @TestForIssue(jiraKey = "HSEARCH-1708") public void testNonGeoDistanceSortOnNonSpatialField() throws Exception { double centerLatitude = 24.0d; double centerLongitude = 32.0d; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( NonGeoPOI.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.all().createQuery(); FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, NonGeoPOI.class ); Sort distanceSort = new Sort( new DistanceSortField( centerLatitude, centerLongitude, "name" ) ); hibQuery.setSort( distanceSort ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" ); try { hibQuery.list(); fail( "Sorting on a field that it is not a coordinate should fail" ); } catch (SearchException e) { assertTrue( "Wrong error message: " + e.getMessage(), e.getMessage().startsWith( "HSEARCH000282: " ) ); } } @Test @TestForIssue(jiraKey = "HSEARCH-1708") public void testNonGeoDistanceSortOnMissingField() throws Exception { double centerLatitude = 24.0d; double centerLongitude = 32.0d; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( NonGeoPOI.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.all().createQuery(); FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, NonGeoPOI.class ); Sort distanceSort = new Sort( new DistanceSortField( centerLatitude, centerLongitude, "location" ) ); hibQuery.setSort( distanceSort ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" ); try { hibQuery.list(); fail( "Sorting on a field not indexed should fail" ); } catch (SearchException e) { assertTrue( "Wrong error message: " + e.getMessage(), e.getMessage().startsWith( "HSEARCH000283: " ) ); } } @Test @TestForIssue(jiraKey = "HSEARCH-1470") public void testSpatialQueryOnNonSpatialConfiguredEntityThrowsException() throws Exception { final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( MissingSpatialPOI.class ).get(); try { builder.spatial() .within( 1, Unit.KM ) .ofLatitude( 0d ) .andLongitude( 0d ) .createQuery(); fail( "Building an invalid spatial query should fail" ); } catch (SearchException e) { assertTrue( "Wrong error message: " + e.getMessage(), e.getMessage().startsWith( "HSEARCH000131" ) ); } } @Test @TestForIssue(jiraKey = "HSEARCH-1470") public void testSpatialQueryOnWrongFieldThrowsException() throws Exception { final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( POI.class ).get(); try { builder.spatial() .onField( "foo" ) .within( 1, Unit.KM ) .ofLatitude( 0d ) .andLongitude( 0d ) .createQuery(); fail( "Building an invalid spatial query should fail" ); } catch (SearchException e) { assertTrue( "Wrong error message " + e.getMessage(), e.getMessage().startsWith( "HSEARCH000131" ) ); } } @Test public void testSpatialAnnotationOnFieldLevel() throws Exception { //Point center = Point.fromDegrees( 24, 31.5 ); // 50.79 km fromBoundingCircle 24.32 double centerLatitude = 24; double centerLongitude = 31.5; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( Event.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "location" ) .within( 50, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, Event.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "location" ) .within( 51, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, Event.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialAnnotationWithSubAnnotationsLevel() throws Exception { //Point center = Point.fromDegrees( 24, 31.5 ); // 50.79 km fromBoundingCircle 24.32 double centerLatitude = 24; double centerLongitude = 31.5; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( User.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "home" ) .within( 50, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, User.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "home" ) .within( 51, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, User.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialAnnotationWithSubAnnotationsLevelRangeMode() throws Exception { //Point center = Point.fromDegrees( 24, 31.5 ); // 50.79 km fromBoundingCircle 24.32 double centerLatitude = 24; double centerLongitude = 31.5; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( UserRange.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial() .within( 50, Unit.KM ) .ofLatitude( centerLatitude ) .andLongitude( centerLongitude ) .createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, UserRange.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial() .within( 51, Unit.KM ) .ofLatitude( centerLatitude ) .andLongitude( centerLongitude ) .createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, UserRange.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialsAnnotation() throws Exception { final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( UserEx.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial() .within( 100.0d, Unit.KM ) .ofLatitude( 24.0d ) .andLongitude( 31.5d ) .createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, UserEx.class ); List results = hibQuery.list(); Assert.assertEquals( 1, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "work" ) .within( 100.0d, Unit.KM ).ofLatitude( 12.0d ).andLongitude( 27.5d ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, UserEx.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialAnnotationOnFieldLevelRangeMode() throws Exception { final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( RangeEvent.class ).get(); double centerLatitude = 24; double centerLongitude = 31.5; org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "location" ) .within( 50, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, RangeEvent.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "location" ) .within( 51, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, RangeEvent.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialAnnotationOnClassLevel() throws Exception { //Point center = Point.fromDegrees( 24, 31.5 ); // 50.79 km fromBoundingCircle 24.32 double centerLatitude = 24; double centerLongitude = 31.5; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( Hotel.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "hotel_location" ) .within( 50, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, Hotel.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "hotel_location" ) .within( 51, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, Hotel.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialAnnotationOnClassLevelRangeMode() throws Exception { //Point center = Point.fromDegrees( 24, 31.5 ); // 50.79 km fromBoundingCircle 24.32 double centerLatitude = 24; double centerLongitude = 31.5; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( RangeHotel.class ).get(); org.apache.lucene.search.Query luceneQuery = builder .spatial() .within( 50, Unit.KM ) .ofLatitude( centerLatitude ) .andLongitude( centerLongitude ) .createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, RangeHotel.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder .spatial() .within( 51, Unit.KM ) .ofLatitude( centerLatitude ) .andLongitude( centerLongitude ) .createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, RangeHotel.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); double endOfTheWorldLatitude = 0.0d; double endOfTheWorldLongitude = 180.0d; org.apache.lucene.search.Query luceneQuery3 = builder .spatial() .within( 112, Unit.KM ) .ofLatitude( endOfTheWorldLatitude ) .andLongitude( endOfTheWorldLongitude ) .createQuery(); org.hibernate.Query hibQuery3 = fullTextSession.createFullTextQuery( luceneQuery3, RangeHotel.class ); List results3 = hibQuery3.list(); Assert.assertEquals( 2, results3.size() ); org.apache.lucene.search.Query luceneQuery4 = builder .spatial() .within( 100000, Unit.KM ) .ofLatitude( endOfTheWorldLatitude ) .andLongitude( endOfTheWorldLongitude ) .createQuery(); org.hibernate.Query hibQuery4 = fullTextSession.createFullTextQuery( luceneQuery4, RangeHotel.class ); List results4 = hibQuery4.list(); Assert.assertEquals( 3, results4.size() ); } @Test public void testSpatialAnnotationOnEmbeddableFieldLevel() throws Exception { final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( Restaurant.class ).get(); double centerLatitude = 24; double centerLongitude = 31.5; org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "position.location" ) .within( 50, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, Restaurant.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "position.location" ) .within( 51, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, Restaurant.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void testSpatialLatLongOnGetters() throws Exception { //Point center = Point.fromDegrees( 24, 31.5 ); // 50.79 km fromBoundingCircle 24.32 double centerLatitude = 24; double centerLongitude = 31.5; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( GetterUser.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "home" ) .within( 50, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, GetterUser.class ); List results = hibQuery.list(); Assert.assertEquals( 0, results.size() ); org.apache.lucene.search.Query luceneQuery2 = builder.spatial().onField( "home" ) .within( 51, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery2 = fullTextSession.createFullTextQuery( luceneQuery2, GetterUser.class ); List results2 = hibQuery2.list(); Assert.assertEquals( 1, results2.size() ); } @Test public void test180MeridianCross() throws Exception { double centerLatitude = 37.769645d; double centerLongitude = -122.446428d; final QueryBuilder builder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( DoubleIndexedPOI.class ).get(); //Tests with FieldBridge org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "location" ) .within( 5000, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, DoubleIndexedPOI.class ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" ); hibQuery.setSort( builder.sort().byDistance().onField( "location" ).fromLatitude( centerLatitude ).andLongitude( centerLongitude ).createSort() ); List results = hibQuery.list(); Assert.assertEquals( 2, results.size() ); Object[] firstResult = (Object[]) results.get( 0 ); Object[] secondResult = (Object[]) results.get( 1 ); Assert.assertEquals( 6.0492d, (Double) firstResult[1], 0.001 ); Assert.assertEquals( 4132.8166d, (Double) secondResult[1], 1 ); //Tests with @Longitude+@Latitude luceneQuery = builder.spatial() .within( 5000, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); hibQuery = fullTextSession.createFullTextQuery( luceneQuery, DoubleIndexedPOI.class ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, Spatial.COORDINATES_DEFAULT_FIELD ); hibQuery.setSort( builder.sort().byDistance().onField( "location" ).fromLatitude( centerLatitude ).andLongitude( centerLongitude ).createSort() ); results = hibQuery.list(); Assert.assertEquals( 2, results.size() ); firstResult = (Object[]) results.get( 0 ); secondResult = (Object[]) results.get( 1 ); Assert.assertEquals( 6.0492d, (Double) firstResult[1], 0.001 ); Assert.assertEquals( 4132.8166d, (Double) secondResult[1], 1 ); } @Override public Class<?>[] getAnnotatedClasses() { return new Class<?>[] { POI.class, Event.class, Hotel.class, User.class, UserRange.class, UserEx.class, RangeHotel.class, RangeEvent.class, Restaurant.class, NonGeoPOI.class, GetterUser.class, MissingSpatialPOI.class, DoubleIndexedPOI.class }; } private void assertNumberOfPointsOfInterestWithinRadius(double centerLatitude, double centerLongitude, double radius, int expectedPoiCount) { final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( POI.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "location" ) .within( radius, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery(); org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( luceneQuery, POI.class ); List results = hibQuery.list(); Assert.assertEquals( "Unexpected number of POIs within radius", expectedPoiCount, results.size() ); } }