Java Code Examples for org.apache.lucene.util.SloppyMath#haversinMeters()
The following examples show how to use
org.apache.lucene.util.SloppyMath#haversinMeters() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TestGeoUtils.java From lucene-solr with Apache License 2.0 | 6 votes |
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); } } } } }
Example 2
Source File: TestGeoUtils.java From lucene-solr with Apache License 2.0 | 5 votes |
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)); } } } }
Example 3
Source File: TestGeoUtils.java From lucene-solr with Apache License 2.0 | 5 votes |
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; }
Example 4
Source File: TestNearest.java From lucene-solr with Apache License 2.0 | 4 votes |
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(); }
Example 5
Source File: GeoTestUtil.java From lucene-solr with Apache License 2.0 | 4 votes |
/** 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]); }
Example 6
Source File: EarthDebugger.java From lucene-solr with Apache License 2.0 | 4 votes |
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)); }
Example 7
Source File: EarthDebugger.java From lucene-solr with Apache License 2.0 | 4 votes |
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; } }
Example 8
Source File: LatLonPointDistanceFeatureQuery.java From lucene-solr with Apache License 2.0 | 4 votes |
private double getDistanceFromEncoded(long encoded) { return SloppyMath.haversinMeters(getDistanceKeyFromEncoded(encoded)); }
Example 9
Source File: LatLonPointDistanceComparator.java From lucene-solr with Apache License 2.0 | 4 votes |
static double haversin2(double partial) { if (Double.isInfinite(partial)) { return partial; } return SloppyMath.haversinMeters(partial); }
Example 10
Source File: TestGeoUtils.java From lucene-solr with Apache License 2.0 | 4 votes |
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 } } } }
Example 11
Source File: TestLatLonPointDistanceFeatureQuery.java From lucene-solr with Apache License 2.0 | 4 votes |
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(); }
Example 12
Source File: TestLatLonPointDistanceFeatureQuery.java From lucene-solr with Apache License 2.0 | 4 votes |
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(); }
Example 13
Source File: TestLatLonPointDistanceFeatureQuery.java From lucene-solr with Apache License 2.0 | 4 votes |
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(); }
Example 14
Source File: HaversineMetersEvaluator.java From lucene-solr with Apache License 2.0 | 4 votes |
public double compute(double[] a, double[] b) throws DimensionMismatchException { return SloppyMath.haversinMeters(a[0], a[1], b[0], b[1]); }
Example 15
Source File: GeoUtils.java From crate with Apache License 2.0 | 4 votes |
/** 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); }