LUCENE-6710: use full 64 bits precision for GeoPointField

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1693796 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2015-08-02 09:27:15 +00:00
parent 85347285f8
commit 2e077c1516
4 changed files with 23 additions and 6 deletions

View File

@ -147,9 +147,12 @@ New Features
filtering. Range trees can also handle values larger than 64 bits. filtering. Range trees can also handle values larger than 64 bits.
(Adrien Grand, Mike McCandless) (Adrien Grand, Mike McCandless)
* LUCENE-6647: Add GeoHash string utility APIs (Nick Knize, Mike * LUCENE-6647: Add GeoHash string utility APIs (Nick Knize via Mike
McCandless). McCandless).
* LUCENE-6710: GeoPointField now uses full 64 bits (up from 62) to encode
lat/lon (Nick Knize via Mike McCandless).
API Changes API Changes
* LUCENE-6508: Simplify Lock api, there is now just * LUCENE-6508: Simplify Lock api, there is now just

View File

@ -17,6 +17,7 @@ package org.apache.lucene.search;
* limitations under the License. * limitations under the License.
*/ */
import java.math.BigInteger;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -67,7 +68,13 @@ class GeoPointTermsEnum extends FilteredTermsEnum {
*/ */
private final void computeRange(long term, final short shift) { private final void computeRange(long term, final short shift) {
final long split = term | (0x1L<<shift); final long split = term | (0x1L<<shift);
final long upperMax = term | ((0x1L<<(shift+1))-1); assert shift < 64;
final long upperMax;
if (shift < 63) {
upperMax = term | ((1L << (shift+1))-1);
} else {
upperMax = 0xffffffffffffffffL;
}
final long lowerMax = split-1; final long lowerMax = split-1;
relateAndRecurse(term, lowerMax, shift); relateAndRecurse(term, lowerMax, shift);
@ -88,7 +95,7 @@ class GeoPointTermsEnum extends FilteredTermsEnum {
final double maxLon = GeoUtils.mortonUnhashLon(end); final double maxLon = GeoUtils.mortonUnhashLon(end);
final double maxLat = GeoUtils.mortonUnhashLat(end); final double maxLat = GeoUtils.mortonUnhashLat(end);
final short level = (short)(62-res>>>1); final short level = (short)((GeoUtils.BITS<<1)-res>>>1);
// if cell is within and a factor of the precision step, or it crosses the edge of the shape add the range // if cell is within and a factor of the precision step, or it crosses the edge of the shape add the range
final boolean within = res % GeoPointField.PRECISION_STEP == 0 && cellWithin(minLon, minLat, maxLon, maxLat); final boolean within = res % GeoPointField.PRECISION_STEP == 0 && cellWithin(minLon, minLat, maxLon, maxLat);

View File

@ -27,9 +27,9 @@ import java.util.ArrayList;
public final class GeoUtils { public final class GeoUtils {
private static final short MIN_LON = -180; private static final short MIN_LON = -180;
private static final short MIN_LAT = -90; private static final short MIN_LAT = -90;
public static final short BITS = 31; public static final short BITS = 32;
private static final double LON_SCALE = (0x1L<<BITS)/360.0D; private static final double LON_SCALE = ((0x1L<<BITS)-1)/360.0D;
private static final double LAT_SCALE = (0x1L<<BITS)/180.0D; private static final double LAT_SCALE = ((0x1L<<BITS)-1)/180.0D;
public static final double TOLERANCE = 1E-6; public static final double TOLERANCE = 1E-6;
/** Minimum longitude value. */ /** Minimum longitude value. */

View File

@ -239,6 +239,13 @@ public class TestGeoPointQuery extends LuceneTestCase {
doTestRandom(10000); doTestRandom(10000);
} }
@Test
public void testMortonEncoding() throws Exception {
long hash = GeoUtils.mortonHash(180, 90);
assertEquals(180.0, GeoUtils.mortonUnhashLon(hash), 0);
assertEquals(90.0, GeoUtils.mortonUnhashLat(hash), 0);
}
@Nightly @Nightly
public void testRandomBig() throws Exception { public void testRandomBig() throws Exception {
doTestRandom(200000); doTestRandom(200000);