Example usage for org.apache.lucene.util SloppyMath haversinMeters

List of usage examples for org.apache.lucene.util SloppyMath haversinMeters

Introduction

In this page you can find the example usage for org.apache.lucene.util SloppyMath haversinMeters.

Prototype

public static double haversinMeters(double lat1, double lon1, double lat2, double lon2) 

Source Link

Document

Returns the Haversine distance in meters between two points specified in decimal degrees (latitude/longitude).

Usage

From source file:org.codelibs.elasticsearch.common.geo.GeoUtils.java

License:Apache License

/** Returns the maximum distance/radius (in meters) from the point 'center' before overlapping */
public static double maxRadialDistanceMeters(final double centerLat, final double centerLon) {
    if (Math.abs(centerLat) == MAX_LAT) {
        return SloppyMath.haversinMeters(centerLat, centerLon, 0, centerLon);
    }/*  w w w .j  a v  a 2 s . co m*/
    return SloppyMath.haversinMeters(centerLat, centerLon, centerLat, (MAX_LON + centerLon) % 360);
}

From source file:org.codelibs.elasticsearch.common.geo.GeoUtils.java

License:Apache License

/** 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);
}

From source file:perf.IndexAndSearchOpenStreetMaps.java

License:Apache License

private static void queryIndex(String queryClass, int gons, int nearestTopN, String polyFile,
        boolean preBuildQueries, Double filterPercent, boolean doDistanceSort) throws IOException {
    IndexSearcher[] searchers = new IndexSearcher[NUM_PARTS];
    Directory[] dirs = new Directory[NUM_PARTS];
    long sizeOnDisk = 0;
    for (int part = 0; part < NUM_PARTS; part++) {
        dirs[part] = FSDirectory.open(Paths.get(getName(part, doDistanceSort)));
        searchers[part] = new IndexSearcher(DirectoryReader.open(dirs[part]));
        searchers[part].setQueryCache(null);
        for (String name : dirs[part].listAll()) {
            sizeOnDisk += dirs[part].fileLength(name);
        }/*from  ww  w .  ja  va 2 s. c o  m*/
    }
    //plotBKD(searchers[0].getIndexReader());
    System.out.println("INDEX SIZE: " + (sizeOnDisk / 1024. / 1024. / 1024.) + " GB");
    long bytes = 0;
    long maxDoc = 0;
    for (IndexSearcher s : searchers) {
        IndexReader r = s.getIndexReader();
        maxDoc += r.maxDoc();
        for (LeafReaderContext ctx : r.leaves()) {
            CodecReader cr = (CodecReader) ctx.reader();
            /*
            for(Accountable acc : cr.getChildResources()) {
              System.out.println("  " + Accountables.toString(acc));
            }
            */
            bytes += cr.ramBytesUsed();
        }
    }
    System.out.println("READER MB: " + (bytes / 1024. / 1024.));
    System.out.println("maxDoc=" + maxDoc);

    double bestQPS = Double.NEGATIVE_INFINITY;

    // million hits per second:
    double bestMHPS = Double.NEGATIVE_INFINITY;

    if (queryClass.equals("polyFile")) {

        // TODO: only load the double[][] here, so that we includ the cost of making Polygon and Query in each iteration!!
        List<Polygon[]> polygons = readPolygons(polyFile);

        // Uncomment to find the lost points!!

        /*
        BooleanQuery.Builder b = new BooleanQuery.Builder();
        b.add(new MatchAllDocsQuery(), BooleanClause.Occur.MUST);
        for(Query q : queries) {
          b.add(q, BooleanClause.Occur.MUST_NOT);
        }
        searchers[0].search(b.build(), new SimpleCollector() {
            private int markerCount;
            private SortedNumericDocValues docValues;
                
            @Override
            protected void doSetNextReader(LeafReaderContext context) throws IOException {
              docValues = context.reader().getSortedNumericDocValues("point");
            }
                
            @Override
            public boolean needsScores() {
              return false;
            }
                
            @Override
            public void collect(int doc) {
              docValues.setDocument(doc);
              int count = docValues.count();
              for (int i = 0; i < count; i++) {
                long encoded = docValues.valueAt(i);
                double docLatitude = LatLonPoint.decodeLatitude((int)(encoded >> 32));
                double docLongitude = LatLonPoint.decodeLongitude((int)(encoded & 0xFFFFFFFF));
                System.out.println("        WE.marker([" + docLatitude + ", " + docLongitude + "]).addTo(earth);");
              }
            }
          });
        */

        /*
        {
          Query q = LatLonPoint.newBoxQuery("point", minLat, maxLat, minLon, maxLon);
          int totHits = 0;
                           
          for(IndexSearcher s : searchers) {
            int hitCount = s.count(q);
            totHits += hitCount;
          }
                
          System.out.println("Poly file bbox total hits: " + totHits);
        }
        */

        if (preBuildQueries) {
            System.out.println("\nUsing pre-built polygon queries, loaded from file " + polyFile);
            List<Query> queries = new ArrayList<>();
            for (Polygon[] multiPolygon : polygons) {
                Query q = null;
                if (useLatLonPoint) {
                    q = LatLonPoint.newPolygonQuery("point", multiPolygon);
                } else if (useGeoPoint) {
                    q = new GeoPointInPolygonQuery("point", multiPolygon);
                } else if (useGeo3DLarge) {
                    q = Geo3DPoint.newLargePolygonQuery("point", multiPolygon);
                } else if (useGeo3D) {
                    q = Geo3DPoint.newPolygonQuery("point", multiPolygon);
                }
                queries.add(q);
            }

            double[] result = runQueries(searchers, queries);
            bestQPS = result[0];
            bestMHPS = result[1];

        } else {

            System.out.println("\nUsing on-the-fly polygon queries, loaded from file " + polyFile);

            for (int iter = 0; iter < ITERS; iter++) {
                long tStart = System.nanoTime();
                long totHits = 0;
                int queryCount = 0;
                for (Polygon[] multiPolygon : polygons) {

                    // We do this to keep the benchmark honest, so any construction cost of a polygon is included in our run time measure:
                    multiPolygon = clonePolygon(multiPolygon);

                    Query q;
                    if (useLatLonPoint) {
                        q = LatLonPoint.newPolygonQuery("point", multiPolygon);
                    } else if (useGeoPoint) {
                        q = new GeoPointInPolygonQuery("point", multiPolygon);
                    } else {
                        q = Geo3DPoint.newLargePolygonQuery("point", multiPolygon);
                    }

                    for (IndexSearcher s : searchers) {
                        int hitCount = s.count(q);
                        totHits += hitCount;
                    }
                    queryCount++;
                }

                long tEnd = System.nanoTime();
                double elapsedSec = (tEnd - tStart) / 1000000000.0;
                double qps = queryCount / elapsedSec;
                double mhps = (totHits / 1000000.0) / elapsedSec;
                System.out.println(String.format(Locale.ROOT,
                        "ITER %d: %.2f M hits/sec, %.2f QPS (%.2f sec for %d queries), totHits=%d", iter, mhps,
                        qps, elapsedSec, queryCount, totHits));
                if (qps > bestQPS) {
                    System.out.println("  ***");
                    bestQPS = qps;
                    bestMHPS = mhps;
                }
            }
        }

    } else if (preBuildQueries) {
        System.out.println("\nUsing pre-built queries");

        double[] result = runQueries(searchers, makeQueries(queryClass, gons));
        bestQPS = result[0];
        bestMHPS = result[1];

    } else {
        System.out.println("\nUsing on-the-fly queries");

        // Create regularly spaced shapes in a grid around London, UK:
        int STEPS = 5;
        double MIN_LAT = 51.0919106;
        double MAX_LAT = 51.6542719;
        double MIN_LON = -0.3867282;
        double MAX_LON = 0.8492337;

        // makeRegularPoly has insanely slow math, so make the double[]'s here.
        // we still form the query inside the benchmark loop (e.g. to account for preprocessing)
        ArrayList<double[][]> polys = new ArrayList<double[][]>(225);
        if ("poly".equals(queryClass)) {
            for (int latStep = 0; latStep < STEPS; latStep++) {
                double lat = MIN_LAT + latStep * (MAX_LAT - MIN_LAT) / STEPS;
                for (int lonStep = 0; lonStep < STEPS; lonStep++) {
                    double lon = MIN_LON + lonStep * (MAX_LON - MIN_LON) / STEPS;
                    for (int latStepEnd = latStep + 1; latStepEnd <= STEPS; latStepEnd++) {
                        double latEnd = MIN_LAT + latStepEnd * (MAX_LAT - MIN_LAT) / STEPS;
                        for (int lonStepEnd = lonStep + 1; lonStepEnd <= STEPS; lonStepEnd++) {
                            double lonEnd = MIN_LON + lonStepEnd * (MAX_LON - MIN_LON) / STEPS;
                            double distanceMeters = SloppyMath.haversinMeters(lat, lon, latEnd, lonEnd) / 2.0;
                            double centerLat = (lat + latEnd) / 2.0;
                            double centerLon = (lon + lonEnd) / 2.0;
                            polys.add(makeRegularPoly(centerLat, centerLon, distanceMeters, gons));
                        }
                    }
                }
            }
        }

        for (int iter = 0; iter < ITERS; iter++) {
            long tStart = System.nanoTime();
            long totHits = 0;
            double totNearestDistance = 0.0;
            int queryCount = 0;

            for (int latStep = 0; latStep < STEPS; latStep++) {
                double lat = MIN_LAT + latStep * (MAX_LAT - MIN_LAT) / STEPS;
                for (int lonStep = 0; lonStep < STEPS; lonStep++) {
                    double lon = MIN_LON + lonStep * (MAX_LON - MIN_LON) / STEPS;
                    for (int latStepEnd = latStep + 1; latStepEnd <= STEPS; latStepEnd++) {
                        double latEnd = MIN_LAT + latStepEnd * (MAX_LAT - MIN_LAT) / STEPS;
                        for (int lonStepEnd = lonStep + 1; lonStepEnd <= STEPS; lonStepEnd++) {
                            double lonEnd = MIN_LON + lonStepEnd * (MAX_LON - MIN_LON) / STEPS;

                            double distanceMeters = SloppyMath.haversinMeters(lat, lon, latEnd, lonEnd) / 2.0;
                            double centerLat = (lat + latEnd) / 2.0;
                            double centerLon = (lon + lonEnd) / 2.0;
                            ScoreDoc[] nearestHits = null;
                            Query q = null;

                            switch (queryClass) {
                            case "distance":
                                if (useGeo3D || useGeo3DLarge) {
                                    q = Geo3DPoint.newDistanceQuery("point", centerLat, centerLon,
                                            distanceMeters);
                                } else if (useLatLonPoint) {
                                    q = LatLonPoint.newDistanceQuery("point", centerLat, centerLon,
                                            distanceMeters);
                                } else if (useGeoPoint) {
                                    q = new GeoPointDistanceQuery("point", centerLat, centerLon,
                                            distanceMeters);
                                } else {
                                    throw new AssertionError();
                                }
                                break;
                            case "poly":
                                double[][] poly = polys.get(queryCount);
                                //System.out.println("poly lats: " + Arrays.toString(poly[0]));
                                //System.out.println("poly lons: " + Arrays.toString(poly[1]));
                                if (useGeo3DLarge) {
                                    //System.out.println("POLY:\n  lats=" + Arrays.toString(poly[0]) + "\n  lons=" + Arrays.toString(poly[1]));
                                    q = Geo3DPoint.newLargePolygonQuery("point", new Polygon(poly[0], poly[1]));
                                } else if (useGeo3D) {
                                    q = Geo3DPoint.newPolygonQuery("point", new Polygon(poly[0], poly[1]));
                                } else if (useLatLonPoint) {
                                    q = LatLonPoint.newPolygonQuery("point", new Polygon(poly[0], poly[1]));
                                } else if (useGeoPoint) {
                                    q = new GeoPointInPolygonQuery("point", new Polygon(poly[0], poly[1]));
                                } else {
                                    throw new AssertionError();
                                }
                                break;
                            case "box":
                                if (useGeo3D || useGeo3DLarge) {
                                    q = Geo3DPoint.newBoxQuery("point", lat, latEnd, lon, lonEnd);
                                } else if (useLatLonPoint) {
                                    q = LatLonPoint.newBoxQuery("point", lat, latEnd, lon, lonEnd);
                                } else if (useGeoPoint) {
                                    q = new GeoPointInBBoxQuery("point", lat, latEnd, lon, lonEnd);
                                } else {
                                    throw new AssertionError();
                                }
                                break;
                            case "nearest":
                                if (useLatLonPoint) {
                                    if (searchers.length != 1) {
                                        // TODO
                                        throw new AssertionError();
                                    }
                                    nearestHits = LatLonPoint.nearest(searchers[0], "point",
                                            (lat + latEnd) / 2.0, (lon + lonEnd) / 2.0, nearestTopN).scoreDocs;
                                    if (false && iter == 0) {
                                        System.out.println("\n" + nearestHits.length + " nearest:");
                                        for (ScoreDoc hit : nearestHits) {
                                            System.out.println("  " + ((FieldDoc) hit).fields[0]);
                                        }
                                    }
                                    for (ScoreDoc hit : nearestHits) {
                                        totNearestDistance += (Double) ((FieldDoc) hit).fields[0];
                                    }
                                } else {
                                    throw new AssertionError();
                                }
                                break;
                            default:
                                throw new AssertionError("unknown queryClass " + queryClass);
                            }

                            // TODO: do this somewhere else?
                            if (filterPercent != null) {
                                BooleanQuery.Builder builder = new BooleanQuery.Builder();
                                builder.add(q, BooleanClause.Occur.MUST);
                                builder.add(new RandomQuery(filterPercent), BooleanClause.Occur.FILTER);
                                q = builder.build();
                            }

                            if (q != null) {
                                if (doDistanceSort) {
                                    Sort sort = new Sort(LatLonDocValuesField.newDistanceSort("point",
                                            centerLat, centerLon));
                                    for (IndexSearcher s : searchers) {
                                        TopFieldDocs hits = s.search(q, 10, sort);
                                        totHits += hits.totalHits;
                                    }
                                } else {
                                    //System.out.println("\nRUN QUERY " + q);
                                    //long t0 = System.nanoTime();
                                    for (IndexSearcher s : searchers) {
                                        int hitCount = s.count(q);
                                        totHits += hitCount;
                                        if (false && iter == 0) {
                                            System.out.println("q=" + q + " lat=" + centerLat + " lon="
                                                    + centerLon + " distanceMeters=" + distanceMeters
                                                    + " hits: " + hitCount);
                                        }
                                    }
                                }
                            } else {
                                assert nearestHits != null;
                                totHits += nearestHits.length;
                            }
                            queryCount++;
                            //throw new RuntimeException("now stop");
                        }
                    }
                }
            }

            long tEnd = System.nanoTime();
            double elapsedSec = (tEnd - tStart) / 1000000000.0;
            double qps = queryCount / elapsedSec;
            double mhps = (totHits / 1000000.0) / elapsedSec;
            if (queryClass.equals("nearest")) {
                System.out.println(String.format(Locale.ROOT,
                        "ITER %d: %.2f QPS (%.2f sec for %d queries), totNearestDistance=%.10f, totHits=%d",
                        iter, qps, elapsedSec, queryCount, totNearestDistance, maxDoc));
            } else {
                System.out.println(String.format(Locale.ROOT,
                        "ITER %d: %.2f M hits/sec, %.2f QPS (%.2f sec for %d queries), totHits=%d", iter, mhps,
                        qps, elapsedSec, queryCount, totHits));
            }
            if (qps > bestQPS) {
                System.out.println("  ***");
                bestQPS = qps;
                bestMHPS = mhps;
            }
        }
    }
    System.out.println("BEST M hits/sec: " + bestMHPS);
    System.out.println("BEST QPS: " + bestQPS);

    for (IndexSearcher s : searchers) {
        s.getIndexReader().close();
    }
    IOUtils.close(dirs);
}

From source file:perf.IndexAndSearchOpenStreetMaps.java

License:Apache License

private static List<Query> makeQueries(String queryClass, int gons) {
    List<Query> queries = new ArrayList<>();
    // Create regularly spaced shapes in a grid around London, UK:
    int STEPS = 5;
    double MIN_LAT = 51.0919106;
    double MAX_LAT = 51.6542719;
    double MIN_LON = -0.3867282;
    double MAX_LON = 0.8492337;
    for (int latStep = 0; latStep < STEPS; latStep++) {
        double lat = MIN_LAT + latStep * (MAX_LAT - MIN_LAT) / STEPS;
        for (int lonStep = 0; lonStep < STEPS; lonStep++) {
            double lon = MIN_LON + lonStep * (MAX_LON - MIN_LON) / STEPS;
            for (int latStepEnd = latStep + 1; latStepEnd <= STEPS; latStepEnd++) {
                double latEnd = MIN_LAT + latStepEnd * (MAX_LAT - MIN_LAT) / STEPS;
                for (int lonStepEnd = lonStep + 1; lonStepEnd <= STEPS; lonStepEnd++) {
                    double lonEnd = MIN_LON + lonStepEnd * (MAX_LON - MIN_LON) / STEPS;

                    double distanceMeters = SloppyMath.haversinMeters(lat, lon, latEnd, lonEnd) / 2.0;
                    double centerLat = (lat + latEnd) / 2.0;
                    double centerLon = (lon + lonEnd) / 2.0;

                    Query q = null;

                    switch (queryClass) {
                    case "distance":
                        if (useGeo3D || useGeo3DLarge) {
                            q = Geo3DPoint.newDistanceQuery("point", centerLat, centerLon, distanceMeters);
                        } else if (useLatLonPoint) {
                            q = LatLonPoint.newDistanceQuery("point", centerLat, centerLon, distanceMeters);
                        } else if (useGeoPoint) {
                            q = new GeoPointDistanceQuery("point", centerLat, centerLon, distanceMeters);
                        } else {
                            throw new AssertionError();
                        }//from  ww w. j av  a  2  s . com
                        break;
                    case "poly":
                        double[][] poly = makeRegularPoly(centerLat, centerLon, distanceMeters, gons);
                        //System.out.println("poly lats: " + Arrays.toString(poly[0]));
                        //System.out.println("poly lons: " + Arrays.toString(poly[1]));
                        if (useGeo3DLarge) {
                            q = Geo3DPoint.newLargePolygonQuery("point", new Polygon(poly[0], poly[1]));
                            //GeoPoint point = new GeoPoint(PlanetModel.WGS84, Math.toRadians(centerLat), Math.toRadians(centerLon));
                            //System.out.println("WITHIN?: " + ((PointInGeo3DShapeQuery) q).getShape().isWithin(point));
                            //System.out.println(" --> QUERY: " + q);
                        } else if (useGeo3D) {
                            q = Geo3DPoint.newPolygonQuery("point", new Polygon(poly[0], poly[1]));
                        } else if (useLatLonPoint) {
                            q = LatLonPoint.newPolygonQuery("point", new Polygon(poly[0], poly[1]));
                        } else if (useGeoPoint) {
                            q = new GeoPointInPolygonQuery("point", new Polygon(poly[0], poly[1]));
                        } else {
                            throw new AssertionError();
                        }
                        break;
                    case "box":
                        if (useGeo3D || useGeo3DLarge) {
                            q = Geo3DPoint.newBoxQuery("point", lat, latEnd, lon, lonEnd);
                        } else if (useLatLonPoint) {
                            q = LatLonPoint.newBoxQuery("point", lat, latEnd, lon, lonEnd);
                        } else if (useGeoPoint) {
                            q = new GeoPointInBBoxQuery("point", lat, latEnd, lon, lonEnd);
                        } else {
                            throw new AssertionError();
                        }
                        break;
                    default:
                        throw new AssertionError();
                    }

                    queries.add(q);
                }
            }
        }
    }

    return queries;
}

From source file:perf.IndexAndSearchOpenStreetMaps.java

License:Apache License

/** 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!! */
private static double[][] makeRegularPoly(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) {
            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;/*from w ww. ja va2  s. c  o m*/
                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 result;
}