mirror of https://github.com/apache/lucene.git
geo tests: simplify random generation
This commit is contained in:
parent
67ca5499a3
commit
1b3a3c113e
|
@ -82,41 +82,11 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
|
||||||
|
|
||||||
private static double originLat;
|
private static double originLat;
|
||||||
private static double originLon;
|
private static double originLon;
|
||||||
private static double lonRange;
|
|
||||||
private static double latRange;
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClassBase() throws Exception {
|
public static void beforeClassBase() throws Exception {
|
||||||
// Between 1.0 and 3.0:
|
originLon = GeoTestUtil.nextLongitude();
|
||||||
lonRange = 2 * (random().nextDouble() + 0.5);
|
originLat = GeoTestUtil.nextLatitude();
|
||||||
latRange = 2 * (random().nextDouble() + 0.5);
|
|
||||||
|
|
||||||
originLon = normalizeLon(GeoUtils.MIN_LON_INCL + lonRange + (GeoUtils.MAX_LON_INCL - GeoUtils.MIN_LON_INCL - 2 * lonRange) * random().nextDouble());
|
|
||||||
originLat = normalizeLat(GeoUtils.MIN_LAT_INCL + latRange + (GeoUtils.MAX_LAT_INCL - GeoUtils.MIN_LAT_INCL - 2 * latRange) * random().nextDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Puts longitude in range of -180 to +180. */
|
|
||||||
public static double normalizeLon(double lon_deg) {
|
|
||||||
if (lon_deg >= -180 && lon_deg <= 180) {
|
|
||||||
return lon_deg; //common case, and avoids slight double precision shifting
|
|
||||||
}
|
|
||||||
double off = (lon_deg + 180) % 360;
|
|
||||||
if (off < 0) {
|
|
||||||
return 180 + off;
|
|
||||||
} else if (off == 0 && lon_deg > 0) {
|
|
||||||
return 180;
|
|
||||||
} else {
|
|
||||||
return -180 + off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Puts latitude in range of -90 to 90. */
|
|
||||||
public static double normalizeLat(double lat_deg) {
|
|
||||||
if (lat_deg >= -90 && lat_deg <= 90) {
|
|
||||||
return lat_deg; //common case, and avoids slight double precision shifting
|
|
||||||
}
|
|
||||||
double off = Math.abs((lat_deg + 90) % 360);
|
|
||||||
return (off <= 180 ? off : 360-off) - 90;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Valid values that should not cause exception */
|
/** Valid values that should not cause exception */
|
||||||
|
@ -621,9 +591,9 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
|
||||||
public double randomLat(boolean small) {
|
public double randomLat(boolean small) {
|
||||||
double result;
|
double result;
|
||||||
if (small) {
|
if (small) {
|
||||||
result = normalizeLat(originLat + latRange * (random().nextDouble() - 0.5));
|
result = GeoTestUtil.nextLatitudeNear(originLat);
|
||||||
} else {
|
} else {
|
||||||
result = -90 + 180.0 * random().nextDouble();
|
result = GeoTestUtil.nextLatitude();
|
||||||
}
|
}
|
||||||
return quantizeLat(result);
|
return quantizeLat(result);
|
||||||
}
|
}
|
||||||
|
@ -631,9 +601,9 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
|
||||||
public double randomLon(boolean small) {
|
public double randomLon(boolean small) {
|
||||||
double result;
|
double result;
|
||||||
if (small) {
|
if (small) {
|
||||||
result = normalizeLon(originLon + lonRange * (random().nextDouble() - 0.5));
|
result = GeoTestUtil.nextLongitudeNear(originLon);
|
||||||
} else {
|
} else {
|
||||||
result = -180 + 360.0 * random().nextDouble();
|
result = GeoTestUtil.nextLongitude();
|
||||||
}
|
}
|
||||||
return quantizeLon(result);
|
return quantizeLon(result);
|
||||||
}
|
}
|
||||||
|
@ -1107,8 +1077,8 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
|
||||||
RandomIndexWriter writer = new RandomIndexWriter(random(), dir, iwc);
|
RandomIndexWriter writer = new RandomIndexWriter(random(), dir, iwc);
|
||||||
|
|
||||||
for (int i = 0; i < numDocs; i++) {
|
for (int i = 0; i < numDocs; i++) {
|
||||||
double latRaw = -90 + 180.0 * random().nextDouble();
|
double latRaw = GeoTestUtil.nextLatitude();
|
||||||
double lonRaw = -180 + 360.0 * random().nextDouble();
|
double lonRaw = GeoTestUtil.nextLongitude();
|
||||||
// pre-normalize up front, so we can just use quantized value for testing and do simple exact comparisons
|
// pre-normalize up front, so we can just use quantized value for testing and do simple exact comparisons
|
||||||
double lat = quantizeLat(latRaw);
|
double lat = quantizeLat(latRaw);
|
||||||
double lon = quantizeLon(lonRaw);
|
double lon = quantizeLon(lonRaw);
|
||||||
|
@ -1122,8 +1092,8 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
|
||||||
IndexSearcher searcher = newSearcher(reader);
|
IndexSearcher searcher = newSearcher(reader);
|
||||||
|
|
||||||
for (int i = 0; i < numQueries; i++) {
|
for (int i = 0; i < numQueries; i++) {
|
||||||
double lat = -90 + 180.0 * random().nextDouble();
|
double lat = GeoTestUtil.nextLatitude();
|
||||||
double lon = -180 + 360.0 * random().nextDouble();
|
double lon = GeoTestUtil.nextLongitude();
|
||||||
double radius = 50000000D * random().nextDouble();
|
double radius = 50000000D * random().nextDouble();
|
||||||
|
|
||||||
BitSet expected = new BitSet();
|
BitSet expected = new BitSet();
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.lucene.spatial.util;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.carrotsearch.randomizedtesting.RandomizedContext;
|
||||||
|
|
||||||
|
/** static methods for testing geo */
|
||||||
|
public class GeoTestUtil {
|
||||||
|
|
||||||
|
/** returns next pseudorandom latitude (anywhere) */
|
||||||
|
public static double nextLatitude() {
|
||||||
|
return -90 + 180.0 * random().nextDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** returns next pseudorandom longitude (anywhere) */
|
||||||
|
public static double nextLongitude() {
|
||||||
|
return -180 + 360.0 * random().nextDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns next pseudorandom latitude, kinda close to {@code otherLatitude} */
|
||||||
|
public static double nextLatitudeNear(double otherLatitude) {
|
||||||
|
GeoUtils.checkLatitude(otherLatitude);
|
||||||
|
return normalizeLatitude(otherLatitude + random().nextDouble() - 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns next pseudorandom longitude, kinda close to {@code otherLongitude} */
|
||||||
|
public static double nextLongitudeNear(double otherLongitude) {
|
||||||
|
GeoUtils.checkLongitude(otherLongitude);
|
||||||
|
return normalizeLongitude(otherLongitude + random().nextDouble() - 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns next pseudorandom latitude, kinda close to {@code minLatitude/maxLatitude}
|
||||||
|
* <b>NOTE:</b>minLatitude/maxLatitude are merely guidelines. the returned value is sometimes
|
||||||
|
* outside of that range! this is to facilitate edge testing.
|
||||||
|
*/
|
||||||
|
public static double nextLatitudeAround(double minLatitude, double maxLatitude) {
|
||||||
|
GeoUtils.checkLatitude(minLatitude);
|
||||||
|
GeoUtils.checkLatitude(maxLatitude);
|
||||||
|
return normalizeLatitude(randomRangeMaybeSlightlyOutside(minLatitude, maxLatitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns next pseudorandom longitude, kinda close to {@code minLongitude/maxLongitude}
|
||||||
|
* <b>NOTE:</b>minLongitude/maxLongitude are merely guidelines. the returned value is sometimes
|
||||||
|
* outside of that range! this is to facilitate edge testing.
|
||||||
|
*/
|
||||||
|
public static double nextLongitudeAround(double minLongitude, double maxLongitude) {
|
||||||
|
GeoUtils.checkLongitude(minLongitude);
|
||||||
|
GeoUtils.checkLongitude(maxLongitude);
|
||||||
|
return normalizeLongitude(randomRangeMaybeSlightlyOutside(minLongitude, maxLongitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns random double min to max or up to 1% outside of that range */
|
||||||
|
private static double randomRangeMaybeSlightlyOutside(double min, double max) {
|
||||||
|
return min + (random().nextDouble() + (0.5 - random().nextDouble()) * .02) * (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Puts latitude in range of -90 to 90. */
|
||||||
|
private static double normalizeLatitude(double latitude) {
|
||||||
|
if (latitude >= -90 && latitude <= 90) {
|
||||||
|
return latitude; //common case, and avoids slight double precision shifting
|
||||||
|
}
|
||||||
|
double off = Math.abs((latitude + 90) % 360);
|
||||||
|
return (off <= 180 ? off : 360-off) - 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Puts longitude in range of -180 to +180. */
|
||||||
|
private static double normalizeLongitude(double longitude) {
|
||||||
|
if (longitude >= -180 && longitude <= 180) {
|
||||||
|
return longitude; //common case, and avoids slight double precision shifting
|
||||||
|
}
|
||||||
|
double off = (longitude + 180) % 360;
|
||||||
|
if (off < 0) {
|
||||||
|
return 180 + off;
|
||||||
|
} else if (off == 0 && longitude > 0) {
|
||||||
|
return 180;
|
||||||
|
} else {
|
||||||
|
return -180 + off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Keep it simple, we don't need to take arbitrary Random for geo tests */
|
||||||
|
private static Random random() {
|
||||||
|
return RandomizedContext.current().getRandom();
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,24 +34,11 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
// Global bounding box we will "cover" in the random test; we have to make this "smallish" else the queries take very long:
|
// Global bounding box we will "cover" in the random test; we have to make this "smallish" else the queries take very long:
|
||||||
private static double originLat;
|
private static double originLat;
|
||||||
private static double originLon;
|
private static double originLon;
|
||||||
// private static double range;
|
|
||||||
private static double lonRange;
|
|
||||||
private static double latRange;
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() throws Exception {
|
public static void beforeClass() throws Exception {
|
||||||
// Between 1.0 and 3.0:
|
originLon = GeoTestUtil.nextLongitude();
|
||||||
lonRange = 2 * (random().nextDouble() + 0.5);
|
originLat = GeoTestUtil.nextLatitude();
|
||||||
latRange = 2 * (random().nextDouble() + 0.5);
|
|
||||||
|
|
||||||
originLon = GeoUtils.MIN_LON_INCL + lonRange + (GeoUtils.MAX_LON_INCL - GeoUtils.MIN_LON_INCL - 2 * lonRange) * random().nextDouble();
|
|
||||||
originLon = BaseGeoPointTestCase.normalizeLon(originLon);
|
|
||||||
originLat = GeoUtils.MIN_LAT_INCL + latRange + (GeoUtils.MAX_LAT_INCL - GeoUtils.MIN_LAT_INCL - 2 * latRange) * random().nextDouble();
|
|
||||||
originLat = BaseGeoPointTestCase.normalizeLat(originLat);
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.println("TEST: originLon=" + originLon + " lonRange= " + lonRange + " originLat=" + originLat + " latRange=" + latRange);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long scaleLon(final double val) {
|
public long scaleLon(final double val) {
|
||||||
|
@ -73,9 +60,9 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
public double randomLat(boolean small) {
|
public double randomLat(boolean small) {
|
||||||
double result;
|
double result;
|
||||||
if (small) {
|
if (small) {
|
||||||
result = BaseGeoPointTestCase.normalizeLat(originLat + latRange * (random().nextDouble() - 0.5));
|
result = GeoTestUtil.nextLatitudeNear(originLat);
|
||||||
} else {
|
} else {
|
||||||
result = -90 + 180.0 * random().nextDouble();
|
result = GeoTestUtil.nextLatitude();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -83,9 +70,9 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
public double randomLon(boolean small) {
|
public double randomLon(boolean small) {
|
||||||
double result;
|
double result;
|
||||||
if (small) {
|
if (small) {
|
||||||
result = BaseGeoPointTestCase.normalizeLon(originLon + lonRange * (random().nextDouble() - 0.5));
|
result = GeoTestUtil.nextLongitudeNear(originLon);
|
||||||
} else {
|
} else {
|
||||||
result = -180 + 360.0 * random().nextDouble();
|
result = GeoTestUtil.nextLongitude();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -149,11 +136,6 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns random double min to max or up to 1% outside of that range */
|
|
||||||
private double randomRangeMaybeSlightlyOutside(double min, double max) {
|
|
||||||
return min + (random().nextDouble() + (0.5 - random().nextDouble()) * .02) * (max - min);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We rely heavily on GeoUtils.circleToBBox so we test it here:
|
// We rely heavily on GeoUtils.circleToBBox so we test it here:
|
||||||
public void testRandomCircleToBBox() throws Exception {
|
public void testRandomCircleToBBox() throws Exception {
|
||||||
int iters = atLeast(1000);
|
int iters = atLeast(1000);
|
||||||
|
@ -188,15 +170,15 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
lon = randomLon(useSmallRanges);
|
lon = randomLon(useSmallRanges);
|
||||||
} else {
|
} else {
|
||||||
// pick a lat/lon within the bbox or "slightly" outside it to try to improve test efficiency
|
// pick a lat/lon within the bbox or "slightly" outside it to try to improve test efficiency
|
||||||
lat = BaseGeoPointTestCase.normalizeLat(randomRangeMaybeSlightlyOutside(bbox.minLat, bbox.maxLat));
|
lat = GeoTestUtil.nextLatitudeAround(bbox.minLat, bbox.maxLat);
|
||||||
if (bbox.crossesDateline()) {
|
if (bbox.crossesDateline()) {
|
||||||
if (random().nextBoolean()) {
|
if (random().nextBoolean()) {
|
||||||
lon = BaseGeoPointTestCase.normalizeLon(randomRangeMaybeSlightlyOutside(bbox.maxLon, -180));
|
lon = GeoTestUtil.nextLongitudeAround(bbox.maxLon, -180);
|
||||||
} else {
|
} else {
|
||||||
lon = BaseGeoPointTestCase.normalizeLon(randomRangeMaybeSlightlyOutside(0, bbox.minLon));
|
lon = GeoTestUtil.nextLongitudeAround(0, bbox.minLon);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lon = BaseGeoPointTestCase.normalizeLon(randomRangeMaybeSlightlyOutside(bbox.minLon, bbox.maxLon));
|
lon = GeoTestUtil.nextLongitudeAround(bbox.minLon, bbox.maxLon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,8 +217,8 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
// similar to testRandomCircleToBBox, but different, less evil, maybe simpler
|
// similar to testRandomCircleToBBox, but different, less evil, maybe simpler
|
||||||
public void testBoundingBoxOpto() {
|
public void testBoundingBoxOpto() {
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
double lat = -90 + 180.0 * random().nextDouble();
|
double lat = GeoTestUtil.nextLatitude();
|
||||||
double lon = -180 + 360.0 * random().nextDouble();
|
double lon = GeoTestUtil.nextLongitude();
|
||||||
double radius = 50000000 * random().nextDouble();
|
double radius = 50000000 * random().nextDouble();
|
||||||
GeoRect box = GeoUtils.circleToBBox(lat, lon, radius);
|
GeoRect box = GeoUtils.circleToBBox(lat, lon, radius);
|
||||||
final GeoRect box1;
|
final GeoRect box1;
|
||||||
|
@ -250,8 +232,8 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 10000; j++) {
|
for (int j = 0; j < 10000; j++) {
|
||||||
double lat2 = -90 + 180.0 * random().nextDouble();
|
double lat2 = GeoTestUtil.nextLatitude();
|
||||||
double lon2 = -180 + 360.0 * random().nextDouble();
|
double lon2 = GeoTestUtil.nextLongitude();
|
||||||
// if the point is within radius, then it should be in our bounding box
|
// if the point is within radius, then it should be in our bounding box
|
||||||
if (SloppyMath.haversinMeters(lat, lon, lat2, lon2) <= radius) {
|
if (SloppyMath.haversinMeters(lat, lon, lat2, lon2) <= radius) {
|
||||||
assertTrue(lat >= box.minLat && lat <= box.maxLat);
|
assertTrue(lat >= box.minLat && lat <= box.maxLat);
|
||||||
|
@ -264,8 +246,8 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
// test we can use haversinSortKey() for distance queries.
|
// test we can use haversinSortKey() for distance queries.
|
||||||
public void testHaversinOpto() {
|
public void testHaversinOpto() {
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
double lat = -90 + 180.0 * random().nextDouble();
|
double lat = GeoTestUtil.nextLatitude();
|
||||||
double lon = -180 + 360.0 * random().nextDouble();
|
double lon = GeoTestUtil.nextLongitude();
|
||||||
double radius = 50000000 * random().nextDouble();
|
double radius = 50000000 * random().nextDouble();
|
||||||
GeoRect box = GeoUtils.circleToBBox(lat, lon, radius);
|
GeoRect box = GeoUtils.circleToBBox(lat, lon, radius);
|
||||||
|
|
||||||
|
@ -274,8 +256,8 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
SloppyMath.haversinSortKey(lat, lon, box.maxLat, lon));
|
SloppyMath.haversinSortKey(lat, lon, box.maxLat, lon));
|
||||||
|
|
||||||
for (int j = 0; j < 10000; j++) {
|
for (int j = 0; j < 10000; j++) {
|
||||||
double lat2 = -90 + 180.0 * random().nextDouble();
|
double lat2 = GeoTestUtil.nextLatitude();
|
||||||
double lon2 = -180 + 360.0 * random().nextDouble();
|
double lon2 = GeoTestUtil.nextLongitude();
|
||||||
// if the point is within radius, then it should be <= our sort key
|
// if the point is within radius, then it should be <= our sort key
|
||||||
if (SloppyMath.haversinMeters(lat, lon, lat2, lon2) <= radius) {
|
if (SloppyMath.haversinMeters(lat, lon, lat2, lon2) <= radius) {
|
||||||
assertTrue(SloppyMath.haversinSortKey(lat, lon, lat2, lon2) <= minPartialDistance);
|
assertTrue(SloppyMath.haversinSortKey(lat, lon, lat2, lon2) <= minPartialDistance);
|
||||||
|
@ -288,8 +270,8 @@ public class TestGeoUtils extends LuceneTestCase {
|
||||||
/** Test infinite radius covers whole earth */
|
/** Test infinite radius covers whole earth */
|
||||||
public void testInfiniteRect() {
|
public void testInfiniteRect() {
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
double centerLat = -90 + 180.0 * random().nextDouble();
|
double centerLat = GeoTestUtil.nextLatitude();
|
||||||
double centerLon = -180 + 360.0 * random().nextDouble();
|
double centerLon = GeoTestUtil.nextLongitude();
|
||||||
GeoRect rect = GeoUtils.circleToBBox(centerLat, centerLon, Double.POSITIVE_INFINITY);
|
GeoRect rect = GeoUtils.circleToBBox(centerLat, centerLon, Double.POSITIVE_INFINITY);
|
||||||
assertEquals(-180.0, rect.minLon, 0.0D);
|
assertEquals(-180.0, rect.minLon, 0.0D);
|
||||||
assertEquals(180.0, rect.maxLon, 0.0D);
|
assertEquals(180.0, rect.maxLon, 0.0D);
|
||||||
|
|
Loading…
Reference in New Issue