LUCENE-7160: LatLonPoint quantization should use the same rounding mode as GeoPointField

This commit is contained in:
Robert Muir 2016-04-01 08:32:16 -04:00
parent cf7967cc46
commit c071a3a8b5
4 changed files with 38 additions and 10 deletions

View File

@ -143,7 +143,7 @@ public class LatLonPoint extends Field {
if (latitude == 90.0D) {
latitude = Math.nextDown(latitude);
}
return Math.toIntExact((long) (latitude * LATITUDE_ENCODE));
return (int) Math.floor(latitude * LATITUDE_ENCODE);
}
/**
@ -158,7 +158,7 @@ public class LatLonPoint extends Field {
if (longitude == 180.0D) {
longitude = Math.nextDown(longitude);
}
return Math.toIntExact((long) (longitude * LONGITUDE_ENCODE));
return (int) Math.floor(longitude * LONGITUDE_ENCODE);
}
/**

View File

@ -23,10 +23,10 @@ public class TestLatLonPoint extends LuceneTestCase {
public void testToString() throws Exception {
// looks crazy due to lossiness
assertEquals("LatLonPoint <field:18.313693958334625,-65.22744392976165>",(new LatLonPoint("field", 18.313694, -65.227444)).toString());
assertEquals("LatLonPoint <field:18.313693958334625,-65.22744401358068>",(new LatLonPoint("field", 18.313694, -65.227444)).toString());
// looks crazy due to lossiness
assertEquals("field:[17.99999997485429 TO 18.999999999068677],[-65.9999999217689 TO -64.99999998137355]", LatLonPoint.newBoxQuery("field", 18, 19, -66, -65).toString());
assertEquals("field:[17.99999997485429 TO 18.999999999068677],[-66.00000000558794 TO -65.00000006519258]", LatLonPoint.newBoxQuery("field", 18, 19, -66, -65).toString());
// distance query does not quantize inputs
assertEquals("field:18.0,19.0 +/- 25.0 meters", LatLonPoint.newDistanceQuery("field", 18, 19, 25).toString());
@ -84,5 +84,18 @@ public class TestLatLonPoint extends LuceneTestCase {
assertEquals(latEnc, latEnc2, 0.0);
assertEquals(lonEnc, lonEnc2, 0.0);
}
}
}
/** make sure values always go down: this is important for edge case consistency */
public void testEncodeDecodeRoundsDown() throws Exception {
int iters = atLeast(1000);
for(int iter=0;iter<iters;iter++) {
double lat = -90 + 180.0 * random().nextDouble();
double lon = -180 + 360.0 * random().nextDouble();
double latEnc = LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(lat));
double lonEnc = LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(lon));
assertTrue(latEnc <= lat);
assertTrue(lonEnc <= lon);
}
}
}

View File

@ -62,13 +62,13 @@ public class TestLatLonPointDistanceSort extends LuceneTestCase {
TopDocs td = searcher.search(new MatchAllDocsQuery(), 3, sort);
FieldDoc d = (FieldDoc) td.scoreDocs[0];
assertEquals(462.1004647449412, (Double)d.fields[0], 0.0D);
assertEquals(462.1028401330432, (Double)d.fields[0], 0.0D);
d = (FieldDoc) td.scoreDocs[1];
assertEquals(1054.9826700985088, (Double)d.fields[0], 0.0D);
assertEquals(1054.9842850974826, (Double)d.fields[0], 0.0D);
d = (FieldDoc) td.scoreDocs[2];
assertEquals(5285.883948830351, (Double)d.fields[0], 0.0D);
assertEquals(5285.881528419706, (Double)d.fields[0], 0.0D);
reader.close();
dir.close();
@ -99,10 +99,10 @@ public class TestLatLonPointDistanceSort extends LuceneTestCase {
TopDocs td = searcher.search(new MatchAllDocsQuery(), 3, sort);
FieldDoc d = (FieldDoc) td.scoreDocs[0];
assertEquals(462.1004647449412D, (Double)d.fields[0], 0.0D);
assertEquals(462.1028401330432D, (Double)d.fields[0], 0.0D);
d = (FieldDoc) td.scoreDocs[1];
assertEquals(1054.9826700985088, (Double)d.fields[0], 0.0D);
assertEquals(1054.9842850974826, (Double)d.fields[0], 0.0D);
d = (FieldDoc) td.scoreDocs[2];
assertEquals(Double.POSITIVE_INFINITY, (Double)d.fields[0], 0.0D);

View File

@ -99,6 +99,21 @@ public class TestGeoUtils extends LuceneTestCase {
assertEquals("lon=" + lon + " lonEnc=" + lonEnc + " diff=" + (lon - lonEnc), lon, lonEnc, GeoEncodingUtils.TOLERANCE);
}
}
/** make sure values always go down: this is important for edge case consistency */
public void testEncodeDecodeRoundsDown() throws Exception {
int iters = atLeast(1000);
for(int iter=0;iter<iters;iter++) {
double lat = -90 + 180.0 * random().nextDouble();
double lon = -180 + 360.0 * random().nextDouble();
long enc = GeoEncodingUtils.mortonHash(lat, lon);
double latEnc = GeoEncodingUtils.mortonUnhashLat(enc);
double lonEnc = GeoEncodingUtils.mortonUnhashLon(enc);
assertTrue(latEnc <= lat);
assertTrue(lonEnc <= lon);
}
}
public void testScaleUnscaleIsStable() throws Exception {
int iters = atLeast(1000);