Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HSEARCH-1918 Fix 180 meridian crossing issue #870

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -163,7 +163,7 @@ public static List<String> getSpatialHashCellsIds(Coordinates center, double rad
getSpatialHashCellsIds(
Point.fromDegreesInclusive(
lowerLeftLatitude,
GeometricConstants.LONGITUDE_DEGREE_RANGE / 2
-GeometricConstants.LONGITUDE_DEGREE_RANGE / 2
), Point.fromDegreesInclusive( upperRightLatitude, upperRightLongitude ), spatialHashLevel
)
);
Expand Down
Expand Up @@ -9,12 +9,15 @@
import java.util.List;

import org.apache.lucene.search.Sort;

import org.hibernate.search.annotations.Spatial;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
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.spatial.DoubleIndexedPOI;
import org.hibernate.search.test.spatial.POI;
import org.junit.Assert;
import org.junit.Test;
Expand Down Expand Up @@ -260,8 +263,88 @@ public void testDistanceSortWithMaxResult() throws Exception {
em.close();
}

@Test
public void testDoubleIndexedDistanceProjection() throws Exception {
DoubleIndexedPOI poi = new DoubleIndexedPOI( 1, "Distance to 24,32 : 0", 24.0d, 32.0d, "" );
DoubleIndexedPOI poi2 = new DoubleIndexedPOI( 2, "Distance to 24,32 : 10.16", 24.0d, 31.9d, "" );
DoubleIndexedPOI poi3 = new DoubleIndexedPOI( 3, "Distance to 24,32 : 11.12", 23.9d, 32.0d, "" );
DoubleIndexedPOI poi4 = new DoubleIndexedPOI( 4, "Distance to 24,32 : 15.06", 23.9d, 32.1d, "" );
DoubleIndexedPOI poi5 = new DoubleIndexedPOI( 5, "Distance to 24,32 : 22.24", 24.2d, 32.0d, "" );
DoubleIndexedPOI poi6 = new DoubleIndexedPOI( 6, "Distance to 24,32 : 24.45", 24.2d, 31.9d, "" );

FullTextEntityManager em = Search.getFullTextEntityManager( factory.createEntityManager() );

em.getTransaction().begin();
em.persist( poi );
em.persist( poi2 );
em.persist( poi3 );
em.getTransaction().commit();
em.clear();
em.getTransaction().begin();
em.persist( poi4 );
em.persist( poi5 );
em.persist( poi6 );
em.getTransaction().commit();

em.getTransaction().begin();
double centerLatitude = 24.0d;
double centerLongitude = 32.0d;

final QueryBuilder builder = em.getSearchFactory().buildQueryBuilder().forEntity( DoubleIndexedPOI.class ).get();

//Tests with FieldBridge
org.apache.lucene.search.Query luceneQuery = builder.spatial().onField( "location" )
.within( 100, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery();

FullTextQuery hibQuery = em.createFullTextQuery( luceneQuery, DoubleIndexedPOI.class );
hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE );
hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" );
List results = hibQuery.getResultList();
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.0001 );
Assert.assertEquals( (Double) thirdResult[1], 11.1195, 0.0001 );
Assert.assertEquals( (Double) fourthResult[1], 15.0636, 0.0001 );
Assert.assertEquals( (Double) fifthResult[1], 22.239, 0.001 );
Assert.assertEquals( (Double) sixthResult[1], 24.446, 0.001 );

//Tests with @Latitude+@Longitude
luceneQuery = builder.spatial()
.within( 100, Unit.KM ).ofLatitude( centerLatitude ).andLongitude( centerLongitude ).createQuery();

hibQuery = em.createFullTextQuery( luceneQuery, DoubleIndexedPOI.class );
hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE );
hibQuery.setSpatialParameters( centerLatitude, centerLongitude, Spatial.COORDINATES_DEFAULT_FIELD );
results = hibQuery.getResultList();
firstResult = (Object[]) results.get( 0 );
secondResult = (Object[]) results.get( 1 );
thirdResult = (Object[]) results.get( 2 );
fourthResult = (Object[]) results.get( 3 );
fifthResult = (Object[]) results.get( 4 );
sixthResult = (Object[]) results.get( 5 );
Assert.assertEquals( (Double) firstResult[1], 0.0, 0.0001 );
Assert.assertEquals( (Double) secondResult[1], 10.1582, 0.0001 );
Assert.assertEquals( (Double) thirdResult[1], 11.1195, 0.0001 );
Assert.assertEquals( (Double) fourthResult[1], 15.0636, 0.0001 );
Assert.assertEquals( (Double) fifthResult[1], 22.239, 0.001 );
Assert.assertEquals( (Double) sixthResult[1], 24.446, 0.001 );


List<?> pois = em.createQuery( "from " + DoubleIndexedPOI.class.getName() ).getResultList();
for ( Object entity : pois ) {
em.remove( entity );
}
em.getTransaction().commit();
em.close();
}

@Override
public Class[] getAnnotatedClasses() {
return new Class<?>[] { POI.class };
return new Class<?>[] { POI.class, DoubleIndexedPOI.class };
}
}
@@ -0,0 +1,100 @@
/*
* 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 org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.FieldBridge;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Latitude;
import org.hibernate.search.annotations.Longitude;
import org.hibernate.search.annotations.Spatial;
import org.hibernate.search.annotations.Store;
import org.hibernate.search.spatial.SpatialFieldBridgeByHash;
import org.hibernate.search.spatial.Coordinates;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;

/**
* Hibernate Search spatial : Double indexed Point Of Interest test entity for
* cheching behavior between @Latitude+@Longitude and @FieldBridge
*
* @author Nicolas Helleringer <nicolas@hibernate.org>
*/
@Entity
@Indexed
@Spatial
public class DoubleIndexedPOI {
@Id
Integer id;

@Field(store = Store.YES)
String name;

@Field(store = Store.YES, index = Index.YES)
String type;

@Latitude
@Field(store = Store.YES, index = Index.YES)
double latitude;

@Longitude
@Field(store = Store.YES, index = Index.YES)
double longitude;

@Field(store = Store.YES, index = Index.YES, analyze = Analyze.NO)
@FieldBridge(impl = SpatialFieldBridgeByHash.class)
@Embedded
public Coordinates getLocation() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi just curious why are you intentionally using the explicit bridge, rather than the Spatial annotation?

@spatial(spatialMode = SpatialMode.HASH)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the same way the infinispan code did it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks!
On 20 Jul 2015 17:42, "Nicolas Helleringer" notifications@github.com
wrote:

In
orm/src/test/java/org/hibernate/search/test/spatial/DoubleIndexedPOI.java
#870 (comment)
:

  • @field(store = Store.YES, index = Index.YES)
  • String type;
  • @field(store = Store.YES, index = Index.YES, analyze = Analyze.NO)
  • @FieldBridge(impl = SpatialFieldBridgeByHash.class)
  • @Embedded
  • public Coordinates getLocation() {

I did the same way the infinispan code did it.


Reply to this email directly or view it on GitHub
https://github.com/hibernate/hibernate-search/pull/870/files#r35001529.

return new Coordinates() {
@Override
public Double getLatitude() {
return latitude;
}

@Override
public Double getLongitude() {
return longitude;
}
};
}

public DoubleIndexedPOI(Integer id, String name, double latitude, double longitude, String type) {
this.id = id;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
this.type = type;
}

public DoubleIndexedPOI() {
}

public Integer getId() {
return id;
}

public String getName() {
return name;
}

public double getLatitude() {
return latitude;
}

public double getLongitude() {
return longitude;
}

public String getType() {
return type;
}

}
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down Expand Up @@ -99,6 +100,10 @@ public void createAndIndexTestData() throws Exception {
// 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();
}

Expand Down Expand Up @@ -490,6 +495,43 @@ public void testSpatialLatLongOnGetters() throws Exception {
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" );
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.0001 );
Assert.assertEquals( 4132.8166d, (Double) secondResult[1], 0.0001 );

//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 );
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.0001 );
Assert.assertEquals( 4132.8166d, (Double) secondResult[1], 0.0001 );
}

@Override
public Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Expand All @@ -504,7 +546,8 @@ public Class<?>[] getAnnotatedClasses() {
Restaurant.class,
NonGeoPOI.class,
GetterUser.class,
MissingSpatialPOI.class
MissingSpatialPOI.class,
DoubleIndexedPOI.class
};
}

Expand Down