Java源码示例:org.apache.lucene.util.SloppyMath
示例1
private void maybeUpdateBBox() {
if (setBottomCounter < 1024 || (setBottomCounter & 0x3F) == 0x3F) {
NearestHit hit = hitQueue.peek();
Rectangle box = Rectangle.fromPointDistance(pointLat, pointLon,
SloppyMath.haversinMeters(hit.distanceSortKey));
//System.out.println(" update bbox to " + box);
minLat = box.minLat;
maxLat = box.maxLat;
if (box.crossesDateline()) {
// box1
minLon = Double.NEGATIVE_INFINITY;
maxLon = box.maxLon;
// box2
minLon2 = box.minLon;
} else {
minLon = box.minLon;
maxLon = box.maxLon;
// disable box2
minLon2 = Double.POSITIVE_INFINITY;
}
}
setBottomCounter++;
}
示例2
private static double approxBestDistance(double minLat, double maxLat, double minLon, double maxLon, double pointLat, double pointLon) {
// TODO: can we make this the trueBestDistance? I.e., minimum distance between the point and ANY point on the box? we can speed things
// up if so, but not enrolling any BKD cell whose true best distance is > bottom of the current hit queue
if (pointLat >= minLat && pointLat <= maxLat && pointLon >= minLon && pointLon <= maxLon) {
// point is inside the cell!
return 0.0;
}
double d1 = SloppyMath.haversinSortKey(pointLat, pointLon, minLat, minLon);
double d2 = SloppyMath.haversinSortKey(pointLat, pointLon, minLat, maxLon);
double d3 = SloppyMath.haversinSortKey(pointLat, pointLon, maxLat, maxLon);
double d4 = SloppyMath.haversinSortKey(pointLat, pointLon, maxLat, minLon);
return Math.min(Math.min(d1, d2), Math.min(d3, d4));
}
示例3
double sortKey(int doc) throws IOException {
if (doc > currentDocs.docID()) {
currentDocs.advance(doc);
}
double minValue = Double.POSITIVE_INFINITY;
if (doc == currentDocs.docID()) {
setValues();
int numValues = currentDocs.docValueCount();
for (int i = 0; i < numValues; i++) {
long encoded = currentValues[i];
double docLatitude = decodeLatitude((int)(encoded >> 32));
double docLongitude = decodeLongitude((int)(encoded & 0xFFFFFFFF));
minValue = Math.min(minValue, SloppyMath.haversinSortKey(latitude, longitude, docLatitude, docLongitude));
}
}
return minValue;
}
示例4
public void testHaversinOpto() {
int iters = atLeast(100);
for (int i = 0; i < iters; i++) {
double lat = GeoTestUtil.nextLatitude();
double lon = GeoTestUtil.nextLongitude();
double radius = 50000000 * random().nextDouble();
Rectangle box = Rectangle.fromPointDistance(lat, lon, radius);
if (box.maxLon - lon < 90 && lon - box.minLon < 90) {
double minPartialDistance = Math.max(SloppyMath.haversinSortKey(lat, lon, lat, box.maxLon),
SloppyMath.haversinSortKey(lat, lon, box.maxLat, lon));
for (int j = 0; j < 10000; j++) {
double point[] = GeoTestUtil.nextPointNear(box);
double lat2 = point[0];
double lon2 = point[1];
// if the point is within radius, then it should be <= our sort key
if (SloppyMath.haversinMeters(lat, lon, lat2, lon2) <= radius) {
assertTrue(SloppyMath.haversinSortKey(lat, lon, lat2, lon2) <= minPartialDistance);
}
}
}
}
}
示例5
@Override
public boolean contains(double x, double y) {
if (crossesDateline) {
if (Component2D.containsPoint(x, y, rectangle.minLon, GeoUtils.MAX_LON_INCL, rectangle.minLat, rectangle.maxLat) ||
Component2D.containsPoint(x, y, GeoUtils.MIN_LON_INCL, rectangle.maxLon, rectangle.minLat, rectangle.maxLat)) {
return SloppyMath.haversinSortKey(y, x, this.centerLat, this.centerLon) <= sortKey;
}
} else {
if (Component2D.containsPoint(x, y, rectangle.minLon, rectangle.maxLon, rectangle.minLat, rectangle.maxLat)) {
return SloppyMath.haversinSortKey(y, x, this.centerLat, this.centerLon) <= sortKey;
}
}
return false;
}
示例6
/**
* Compute the relation between the provided box and distance query.
* This only works for boxes that do not cross the dateline.
*/
public static PointValues.Relation relate(
double minLat, double maxLat, double minLon, double maxLon,
double lat, double lon, double distanceSortKey, double axisLat) {
if (minLon > maxLon) {
throw new IllegalArgumentException("Box crosses the dateline");
}
if ((lon < minLon || lon > maxLon) && (axisLat + Rectangle.AXISLAT_ERROR < minLat || axisLat - Rectangle.AXISLAT_ERROR > maxLat)) {
// circle not fully inside / crossing axis
if (SloppyMath.haversinSortKey(lat, lon, minLat, minLon) > distanceSortKey &&
SloppyMath.haversinSortKey(lat, lon, minLat, maxLon) > distanceSortKey &&
SloppyMath.haversinSortKey(lat, lon, maxLat, minLon) > distanceSortKey &&
SloppyMath.haversinSortKey(lat, lon, maxLat, maxLon) > distanceSortKey) {
// no points inside
return Relation.CELL_OUTSIDE_QUERY;
}
}
if (within90LonDegrees(lon, minLon, maxLon) &&
SloppyMath.haversinSortKey(lat, lon, minLat, minLon) <= distanceSortKey &&
SloppyMath.haversinSortKey(lat, lon, minLat, maxLon) <= distanceSortKey &&
SloppyMath.haversinSortKey(lat, lon, maxLat, minLon) <= distanceSortKey &&
SloppyMath.haversinSortKey(lat, lon, maxLat, maxLon) <= distanceSortKey) {
// we are fully enclosed, collect everything within this subtree
return Relation.CELL_INSIDE_QUERY;
}
return Relation.CELL_CROSSES_QUERY;
}
示例7
private double getDistanceKeyFromEncoded(long encoded) {
int latitudeBits = (int)(encoded >> 32);
int longitudeBits = (int)(encoded & 0xFFFFFFFF);
double lat = GeoEncodingUtils.decodeLatitude(latitudeBits);
double lon = GeoEncodingUtils.decodeLongitude(longitudeBits);
return SloppyMath.haversinSortKey(originLat, originLon, lat, lon);
}
示例8
@Override
public int compareBottom(int doc) throws IOException {
if (doc > currentDocs.docID()) {
currentDocs.advance(doc);
}
if (doc < currentDocs.docID()) {
return Double.compare(bottom, Double.POSITIVE_INFINITY);
}
setValues();
int numValues = currentDocs.docValueCount();
int cmp = -1;
for (int i = 0; i < numValues; i++) {
long encoded = currentValues[i];
// test bounding box
int latitudeBits = (int)(encoded >> 32);
if (latitudeBits < minLat || latitudeBits > maxLat) {
continue;
}
int longitudeBits = (int)(encoded & 0xFFFFFFFF);
if ((longitudeBits < minLon || longitudeBits > maxLon) && (longitudeBits < minLon2)) {
continue;
}
// only compute actual distance if its inside "competitive bounding box"
double docLatitude = decodeLatitude(latitudeBits);
double docLongitude = decodeLongitude(longitudeBits);
cmp = Math.max(cmp, Double.compare(bottom, SloppyMath.haversinSortKey(latitude, longitude, docLatitude, docLongitude)));
// once we compete in the PQ, no need to continue.
if (cmp > 0) {
return cmp;
}
}
return cmp;
}
示例9
public void testBoundingBoxOpto() {
int iters = atLeast(100);
for (int i = 0; i < iters; i++) {
double lat = GeoTestUtil.nextLatitude();
double lon = GeoTestUtil.nextLongitude();
double radius = 50000000 * random().nextDouble();
Rectangle box = Rectangle.fromPointDistance(lat, lon, radius);
final Rectangle box1;
final Rectangle box2;
if (box.crossesDateline()) {
box1 = new Rectangle(box.minLat, box.maxLat, -180, box.maxLon);
box2 = new Rectangle(box.minLat, box.maxLat, box.minLon, 180);
} else {
box1 = box;
box2 = null;
}
for (int j = 0; j < 1000; j++) {
double point[] = GeoTestUtil.nextPointNear(box);
double lat2 = point[0];
double lon2 = point[1];
// if the point is within radius, then it should be in our bounding box
if (SloppyMath.haversinMeters(lat, lon, lat2, lon2) <= radius) {
assertTrue(lat >= box.minLat && lat <= box.maxLat);
assertTrue(lon >= box1.minLon && lon <= box1.maxLon || (box2 != null && lon >= box2.minLon && lon <= box2.maxLon));
}
}
}
}
示例10
static boolean isDisjoint(double centerLat, double centerLon, double radius, double axisLat, double latMin, double latMax, double lonMin, double lonMax) {
if ((centerLon < lonMin || centerLon > lonMax) && (axisLat+ Rectangle.AXISLAT_ERROR < latMin || axisLat- Rectangle.AXISLAT_ERROR > latMax)) {
// circle not fully inside / crossing axis
if (SloppyMath.haversinMeters(centerLat, centerLon, latMin, lonMin) > radius &&
SloppyMath.haversinMeters(centerLat, centerLon, latMin, lonMax) > radius &&
SloppyMath.haversinMeters(centerLat, centerLon, latMax, lonMin) > radius &&
SloppyMath.haversinMeters(centerLat, centerLon, latMax, lonMax) > radius) {
// no points inside
return true;
}
}
return false;
}
示例11
/**
* Return an approximate value of the diameter of the earth (in meters) at the given latitude (in radians).
*/
public static double earthDiameter(double latitude) {
// SloppyMath impl returns a result in kilometers
return SloppyMath.earthDiameter(latitude) * 1000;
}
示例12
public void testNearestNeighborRandom() throws Exception {
int numPoints = atLeast(1000);
Directory dir;
if (numPoints > 100000) {
dir = newFSDirectory(createTempDir(getClass().getSimpleName()));
} else {
dir = newDirectory();
}
double[] lats = new double[numPoints];
double[] lons = new double[numPoints];
IndexWriterConfig iwc = getIndexWriterConfig();
iwc.setMergePolicy(newLogMergePolicy());
iwc.setMergeScheduler(new SerialMergeScheduler());
RandomIndexWriter w = new RandomIndexWriter(random(), dir, iwc);
for(int id=0;id<numPoints;id++) {
lats[id] = quantizeLat(GeoTestUtil.nextLatitude());
lons[id] = quantizeLon(GeoTestUtil.nextLongitude());
Document doc = new Document();
doc.add(new LatLonPoint("point", lats[id], lons[id]));
doc.add(new LatLonDocValuesField("point", lats[id], lons[id]));
doc.add(new StoredField("id", id));
w.addDocument(doc);
}
if (random().nextBoolean()) {
w.forceMerge(1);
}
DirectoryReader r = w.getReader();
if (VERBOSE) {
System.out.println("TEST: reader=" + r);
}
// can't wrap because we require Lucene60PointsFormat directly but e.g. ParallelReader wraps with its own points impl:
IndexSearcher s = newSearcher(r, false);
int iters = atLeast(100);
for(int iter=0;iter<iters;iter++) {
if (VERBOSE) {
System.out.println("\nTEST: iter=" + iter);
}
double pointLat = GeoTestUtil.nextLatitude();
double pointLon = GeoTestUtil.nextLongitude();
// dumb brute force search to get the expected result:
FieldDoc[] expectedHits = new FieldDoc[lats.length];
for(int id=0;id<lats.length;id++) {
double distance = SloppyMath.haversinMeters(pointLat, pointLon, lats[id], lons[id]);
FieldDoc hit = new FieldDoc(id, 0.0f, new Object[] {Double.valueOf(distance)});
expectedHits[id] = hit;
}
Arrays.sort(expectedHits, new Comparator<FieldDoc>() {
@Override
public int compare(FieldDoc a, FieldDoc b) {
int cmp = Double.compare(((Double) a.fields[0]).doubleValue(), ((Double) b.fields[0]).doubleValue());
if (cmp != 0) {
return cmp;
}
// tie break by smaller docID:
return a.doc - b.doc;
}
});
int topN = TestUtil.nextInt(random(), 1, lats.length);
if (VERBOSE) {
System.out.println("\nhits for pointLat=" + pointLat + " pointLon=" + pointLon);
}
// Also test with MatchAllDocsQuery, sorting by distance:
TopFieldDocs fieldDocs = s.search(new MatchAllDocsQuery(), topN, new Sort(LatLonDocValuesField.newDistanceSort("point", pointLat, pointLon)));
ScoreDoc[] hits = LatLonPointPrototypeQueries.nearest(s, "point", pointLat, pointLon, topN).scoreDocs;
for(int i=0;i<topN;i++) {
FieldDoc expected = expectedHits[i];
FieldDoc expected2 = (FieldDoc) fieldDocs.scoreDocs[i];
FieldDoc actual = (FieldDoc) hits[i];
Document actualDoc = r.document(actual.doc);
if (VERBOSE) {
System.out.println("hit " + i);
System.out.println(" expected id=" + expected.doc+ " lat=" + lats[expected.doc] + " lon=" + lons[expected.doc]
+ " distance=" + ((Double) expected.fields[0]).doubleValue() + " meters");
System.out.println(" actual id=" + actualDoc.getField("id") + " distance=" + actual.fields[0] + " meters");
}
assertEquals(expected.doc, actual.doc);
assertEquals(((Double) expected.fields[0]).doubleValue(), ((Double) actual.fields[0]).doubleValue(), 0.0);
assertEquals(expected2.doc, actual.doc);
assertEquals(((Double) expected2.fields[0]).doubleValue(), ((Double) actual.fields[0]).doubleValue(), 0.0);
}
}
r.close();
w.close();
dir.close();
}
示例13
/** Makes an n-gon, centered at the provided lat/lon, and each vertex approximately
* distanceMeters away from the center.
*
* Do not invoke me across the dateline or a pole!! */
public static Polygon createRegularPolygon(double centerLat, double centerLon, double radiusMeters, int gons) {
// System.out.println("MAKE POLY: centerLat=" + centerLat + " centerLon=" + centerLon + " radiusMeters=" + radiusMeters + " gons=" + gons);
double[][] result = new double[2][];
result[0] = new double[gons+1];
result[1] = new double[gons+1];
//System.out.println("make gon=" + gons);
for(int i=0;i<gons;i++) {
double angle = 360.0-i*(360.0/gons);
//System.out.println(" angle " + angle);
double x = Math.cos(Math.toRadians(angle));
double y = Math.sin(Math.toRadians(angle));
double factor = 2.0;
double step = 1.0;
int last = 0;
//System.out.println("angle " + angle + " slope=" + slope);
// Iterate out along one spoke until we hone in on the point that's nearly exactly radiusMeters from the center:
while (true) {
// TODO: we could in fact cross a pole? Just do what surpriseMePolygon does?
double lat = centerLat + y * factor;
GeoUtils.checkLatitude(lat);
double lon = centerLon + x * factor;
GeoUtils.checkLongitude(lon);
double distanceMeters = SloppyMath.haversinMeters(centerLat, centerLon, lat, lon);
//System.out.println(" iter lat=" + lat + " lon=" + lon + " distance=" + distanceMeters + " vs " + radiusMeters);
if (Math.abs(distanceMeters - radiusMeters) < 0.1) {
// Within 10 cm: close enough!
result[0][i] = lat;
result[1][i] = lon;
break;
}
if (distanceMeters > radiusMeters) {
// too big
//System.out.println(" smaller");
factor -= step;
if (last == 1) {
//System.out.println(" half-step");
step /= 2.0;
}
last = -1;
} else if (distanceMeters < radiusMeters) {
// too small
//System.out.println(" bigger");
factor += step;
if (last == -1) {
//System.out.println(" half-step");
step /= 2.0;
}
last = 1;
}
}
}
// close poly
result[0][gons] = result[0][0];
result[1][gons] = result[1][0];
//System.out.println(" polyLats=" + Arrays.toString(result[0]));
//System.out.println(" polyLons=" + Arrays.toString(result[1]));
return new Polygon(result[0], result[1]);
}
示例14
private int getStepCount(double minLat, double maxLat, double minLon, double maxLon) {
double distanceMeters = SloppyMath.haversinMeters(minLat, minLon, maxLat, maxLon);
return Math.max(1, (int) Math.round((distanceMeters / 1000.0) / MAX_KM_PER_STEP));
}
示例15
private static void inverseHaversin(StringBuilder b, double centerLat, double centerLon, double radiusMeters) {
double angle = 0;
int steps = 100;
newAngle:
while (angle < 360) {
double x = Math.cos(Math.toRadians(angle));
double y = Math.sin(Math.toRadians(angle));
double factor = 2.0;
double step = 1.0;
int last = 0;
double lastDistanceMeters = 0.0;
//System.out.println("angle " + angle + " slope=" + slope);
while (true) {
double lat = wrapLat(centerLat + y * factor);
double lon = wrapLon(centerLon + x * factor);
double distanceMeters = SloppyMath.haversinMeters(centerLat, centerLon, lat, lon);
if (last == 1 && distanceMeters < lastDistanceMeters) {
// For large enough circles, some angles are not possible:
//System.out.println(" done: give up on angle " + angle);
angle += 360./steps;
continue newAngle;
}
if (last == -1 && distanceMeters > lastDistanceMeters) {
// For large enough circles, some angles are not possible:
//System.out.println(" done: give up on angle " + angle);
angle += 360./steps;
continue newAngle;
}
lastDistanceMeters = distanceMeters;
//System.out.println(" iter lat=" + lat + " lon=" + lon + " distance=" + distanceMeters + " vs " + radiusMeters);
if (Math.abs(distanceMeters - radiusMeters) < 0.1) {
b.append(" [").append(lat).append(", ").append(lon).append("],\n");
break;
}
if (distanceMeters > radiusMeters) {
// too big
//System.out.println(" smaller");
factor -= step;
if (last == 1) {
//System.out.println(" half-step");
step /= 2.0;
}
last = -1;
} else if (distanceMeters < radiusMeters) {
// too small
//System.out.println(" bigger");
factor += step;
if (last == -1) {
//System.out.println(" half-step");
step /= 2.0;
}
last = 1;
}
}
angle += 360./steps;
}
}
示例16
private double getDistanceFromEncoded(long encoded) {
return SloppyMath.haversinMeters(getDistanceKeyFromEncoded(encoded));
}
示例17
static double haversin2(double partial) {
if (Double.isInfinite(partial)) {
return partial;
}
return SloppyMath.haversinMeters(partial);
}
示例18
public void testRandomCircleToBBox() throws Exception {
int iters = atLeast(100);
for(int iter=0;iter<iters;iter++) {
double centerLat = GeoTestUtil.nextLatitude();
double centerLon = GeoTestUtil.nextLongitude();
final double radiusMeters;
if (random().nextBoolean()) {
// Approx 4 degrees lon at the equator:
radiusMeters = random().nextDouble() * 444000;
} else {
radiusMeters = random().nextDouble() * 50000000;
}
// TODO: randomly quantize radius too, to provoke exact math errors?
Rectangle bbox = Rectangle.fromPointDistance(centerLat, centerLon, radiusMeters);
int numPointsToTry = 1000;
for(int i=0;i<numPointsToTry;i++) {
double point[] = GeoTestUtil.nextPointNear(bbox);
double lat = point[0];
double lon = point[1];
double distanceMeters = SloppyMath.haversinMeters(centerLat, centerLon, lat, lon);
// Haversin says it's within the circle:
boolean haversinSays = distanceMeters <= radiusMeters;
// BBox says its within the box:
boolean bboxSays;
if (bbox.crossesDateline()) {
if (lat >= bbox.minLat && lat <= bbox.maxLat) {
bboxSays = lon <= bbox.maxLon || lon >= bbox.minLon;
} else {
bboxSays = false;
}
} else {
bboxSays = lat >= bbox.minLat && lat <= bbox.maxLat && lon >= bbox.minLon && lon <= bbox.maxLon;
}
if (haversinSays) {
if (bboxSays == false) {
System.out.println("centerLat=" + centerLat + " centerLon=" + centerLon + " radiusMeters=" + radiusMeters);
System.out.println(" bbox: lat=" + bbox.minLat + " to " + bbox.maxLat + " lon=" + bbox.minLon + " to " + bbox.maxLon);
System.out.println(" point: lat=" + lat + " lon=" + lon);
System.out.println(" haversin: " + distanceMeters);
fail("point was within the distance according to haversin, but the bbox doesn't contain it");
}
} else {
// it's fine if haversin said it was outside the radius and bbox said it was inside the box
}
}
}
}
示例19
public void testBasics() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
.setMergePolicy(newLogMergePolicy(random().nextBoolean())));
Document doc = new Document();
LatLonPoint point = new LatLonPoint("foo", 0.0, 0.0);
doc.add(point);
LatLonDocValuesField docValue = new LatLonDocValuesField("foo",0.0, 0.0);
doc.add(docValue);
double pivotDistance = 5000;//5k
point.setLocationValue(-7, -7);
docValue.setLocationValue(-7, -7);
w.addDocument(doc);
point.setLocationValue(9, 9);
docValue.setLocationValue(9, 9);
w.addDocument(doc);
point.setLocationValue(8, 8);
docValue.setLocationValue(8, 8);
w.addDocument(doc);
point.setLocationValue(4, 4);
docValue.setLocationValue(4, 4);
w.addDocument(doc);
point.setLocationValue(-1, -1);
docValue.setLocationValue(-1, -1);
w.addDocument(doc);
DirectoryReader reader = w.getReader();
IndexSearcher searcher = newSearcher(reader);
Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 10, 10, pivotDistance);
TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 1);
searcher.search(q, collector);
TopDocs topHits = collector.topDocs();
assertEquals(2, topHits.scoreDocs.length);
double distance1 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(9)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(9)), 10,10);
double distance2 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(8)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(8)), 10,10);
CheckHits.checkEqual(q,
new ScoreDoc[] {
new ScoreDoc(1, (float) (3f * (pivotDistance / (pivotDistance + distance1)))),
new ScoreDoc(2, (float) (3f * (pivotDistance / (pivotDistance + distance2))))
},
topHits.scoreDocs);
distance1 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(9)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(9)), 9,9);
distance2 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(8)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(8)), 9,9);
q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 9, 9, pivotDistance);
collector = TopScoreDocCollector.create(2, null, 1);
searcher.search(q, collector);
topHits = collector.topDocs();
assertEquals(2, topHits.scoreDocs.length);
CheckHits.checkExplanations(q, "", searcher);
CheckHits.checkEqual(q,
new ScoreDoc[] {
new ScoreDoc(1, (float) (3f * (pivotDistance / (pivotDistance + distance1)))),
new ScoreDoc(2, (float) (3f * (pivotDistance / (pivotDistance + distance2))))
},
topHits.scoreDocs);
reader.close();
w.close();
dir.close();
}
示例20
public void testCrossesDateLine() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
.setMergePolicy(newLogMergePolicy(random().nextBoolean())));
Document doc = new Document();
LatLonPoint point = new LatLonPoint("foo", 0.0, 0.0);
doc.add(point);
LatLonDocValuesField docValue = new LatLonDocValuesField("foo",0.0, 0.0);
doc.add(docValue);
double pivotDistance = 5000;//5k
point.setLocationValue(0, -179);
docValue.setLocationValue(0, -179);
w.addDocument(doc);
point.setLocationValue(0, 176);
docValue.setLocationValue(0, 176);
w.addDocument(doc);
point.setLocationValue(0, -150);
docValue.setLocationValue(0, -150);
w.addDocument(doc);
point.setLocationValue(0, -140);
docValue.setLocationValue(0, -140);
w.addDocument(doc);
point.setLocationValue(0, 140);
docValue.setLocationValue(01, 140);
w.addDocument(doc);
DirectoryReader reader = w.getReader();
IndexSearcher searcher = newSearcher(reader);
Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 0, 179, pivotDistance);
TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 1);
searcher.search(q, collector);
TopDocs topHits = collector.topDocs();
assertEquals(2, topHits.scoreDocs.length);
double distance1 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(0)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(-179)), 0,179);
double distance2 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(0)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(176)), 0,179);
CheckHits.checkEqual(q,
new ScoreDoc[] {
new ScoreDoc(0, (float) (3f * (pivotDistance / (pivotDistance + distance1)))),
new ScoreDoc(1, (float) (3f * (pivotDistance / (pivotDistance + distance2))))
},
topHits.scoreDocs);
reader.close();
w.close();
dir.close();
}
示例21
public void testMissingValue() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
.setMergePolicy(newLogMergePolicy(random().nextBoolean())));
Document doc = new Document();
LatLonPoint point = new LatLonPoint("foo", 0, 0);
doc.add(point);
LatLonDocValuesField docValue = new LatLonDocValuesField("foo", 0, 0);
doc.add(docValue);
point.setLocationValue(3, 3);
docValue.setLocationValue(3, 3);
w.addDocument(doc);
w.addDocument(new Document());
point.setLocationValue(7, 7);
docValue.setLocationValue(7, 7);
w.addDocument(doc);
DirectoryReader reader = w.getReader();
IndexSearcher searcher = newSearcher(reader);
Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 10, 10, 5);
TopScoreDocCollector collector = TopScoreDocCollector.create(3, null, 1);
searcher.search(q, collector);
TopDocs topHits = collector.topDocs();
assertEquals(2, topHits.scoreDocs.length);
double distance1 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(7)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(7)), 10,10);
double distance2 = SloppyMath.haversinMeters(GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(3)) , GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(3)), 10,10);
CheckHits.checkEqual(q,
new ScoreDoc[] {
new ScoreDoc(2, (float) (3f * (5. / (5. + distance1)))),
new ScoreDoc(0, (float) (3f * (5. / (5. + distance2))))
},
topHits.scoreDocs);
CheckHits.checkExplanations(q, "", searcher);
reader.close();
w.close();
dir.close();
}
示例22
public double compute(double[] a, double[] b) throws DimensionMismatchException {
return SloppyMath.haversinMeters(a[0], a[1], b[0], b[1]);
}
示例23
/** Return the distance (in meters) between 2 lat,lon geo points using the haversine method implemented by lucene */
public static double arcDistance(double lat1, double lon1, double lat2, double lon2) {
return SloppyMath.haversinMeters(lat1, lon1, lat2, lon2);
}
示例24
/**
* Return the distance (in meters) between 2 lat,lon geo points using a simple tangential plane
* this provides a faster alternative to {@link GeoUtils#arcDistance} but is inaccurate for distances greater than
* 4 decimal degrees
*/
public static double planeDistance(double lat1, double lon1, double lat2, double lon2) {
double x = (lon2 - lon1) * SloppyMath.TO_RADIANS * Math.cos((lat2 + lat1) / 2.0 * SloppyMath.TO_RADIANS);
double y = (lat2 - lat1) * SloppyMath.TO_RADIANS;
return Math.sqrt(x * x + y * y) * EARTH_MEAN_RADIUS;
}