Search in sources :

Example 11 with GeoPoint

use of org.apache.lucene.spatial3d.geom.GeoPoint in project lucene-solr by apache.

the class Geo3DUtil method fromPath.

/**
   * Convert input parameters to a path.
   * @param pathLatitudes latitude values for points of the path: must be within standard +/-90 coordinate bounds.
   * @param pathLongitudes longitude values for points of the path: must be within standard +/-180 coordinate bounds.
   * @param pathWidthMeters width of the path in meters.
   * @return the path.
   */
static GeoPath fromPath(final double[] pathLatitudes, final double[] pathLongitudes, final double pathWidthMeters) {
    if (pathLatitudes.length != pathLongitudes.length) {
        throw new IllegalArgumentException("same number of latitudes and longitudes required");
    }
    final GeoPoint[] points = new GeoPoint[pathLatitudes.length];
    for (int i = 0; i < pathLatitudes.length; i++) {
        final double latitude = pathLatitudes[i];
        final double longitude = pathLongitudes[i];
        GeoUtils.checkLatitude(latitude);
        GeoUtils.checkLongitude(longitude);
        points[i] = new GeoPoint(PlanetModel.WGS84, fromDegrees(latitude), fromDegrees(longitude));
    }
    return GeoPathFactory.makeGeoPath(PlanetModel.WGS84, fromMeters(pathWidthMeters), points);
}
Also used : GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint)

Example 12 with GeoPoint

use of org.apache.lucene.spatial3d.geom.GeoPoint in project lucene-solr by apache.

the class TestGeo3DPoint method testComplexPolygons.

public void testComplexPolygons() {
    final PlanetModel pm = PlanetModel.WGS84;
    // Pick a random pole
    final GeoPoint randomPole = new GeoPoint(pm, toRadians(GeoTestUtil.nextLatitude()), toRadians(GeoTestUtil.nextLongitude()));
    int iters = atLeast(100);
    for (int i = 0; i < iters; i++) {
        // Create a polygon that's less than 180 degrees
        final Polygon clockWise = makePoly(pm, randomPole, true, true);
    }
    iters = atLeast(100);
    for (int i = 0; i < iters; i++) {
        // Create a polygon that's greater than 180 degrees
        final Polygon counterClockWise = makePoly(pm, randomPole, false, true);
    }
}
Also used : GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) PlanetModel(org.apache.lucene.spatial3d.geom.PlanetModel) GeoPolygon(org.apache.lucene.spatial3d.geom.GeoPolygon) Polygon(org.apache.lucene.geo.Polygon) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint)

Example 13 with GeoPoint

use of org.apache.lucene.spatial3d.geom.GeoPoint in project lucene-solr by apache.

the class TestGeo3DPoint method testGeo3DRelations.

/** Tests consistency of GeoArea.getRelationship vs GeoShape.isWithin */
public void testGeo3DRelations() throws Exception {
    int numDocs = atLeast(1000);
    if (VERBOSE) {
        System.out.println("TEST: " + numDocs + " docs");
    }
    GeoPoint[] docs = new GeoPoint[numDocs];
    GeoPoint[] unquantizedDocs = new GeoPoint[numDocs];
    for (int docID = 0; docID < numDocs; docID++) {
        unquantizedDocs[docID] = new GeoPoint(PlanetModel.WGS84, toRadians(GeoTestUtil.nextLatitude()), toRadians(GeoTestUtil.nextLongitude()));
        docs[docID] = quantize(unquantizedDocs[docID]);
        if (VERBOSE) {
            System.out.println("  doc=" + docID + ": " + docs[docID] + "; unquantized: " + unquantizedDocs[docID]);
        }
    }
    int iters = atLeast(10);
    int recurseDepth = RandomNumbers.randomIntBetween(random(), 5, 15);
    iters = atLeast(50);
    for (int iter = 0; iter < iters; iter++) {
        GeoShape shape = randomShape();
        StringWriter sw = new StringWriter();
        PrintWriter log = new PrintWriter(sw, true);
        if (VERBOSE) {
            log.println("TEST: iter=" + iter + " shape=" + shape);
        }
        XYZBounds bounds = new XYZBounds();
        shape.getBounds(bounds);
        // Start with the root cell that fully contains the shape:
        Cell root = new Cell(null, encodeValueLenient(bounds.getMinimumX()), encodeValueLenient(bounds.getMaximumX()), encodeValueLenient(bounds.getMinimumY()), encodeValueLenient(bounds.getMaximumY()), encodeValueLenient(bounds.getMinimumZ()), encodeValueLenient(bounds.getMaximumZ()), 0);
        if (VERBOSE) {
            log.println("  root cell: " + root);
        }
        // make sure the root cell (XYZBounds) does in fact contain all points that the shape contains
        {
            boolean fail = false;
            for (int docID = 0; docID < numDocs; docID++) {
                if (root.contains(docs[docID]) == false) {
                    boolean expected = shape.isWithin(unquantizedDocs[docID]);
                    if (expected) {
                        log.println("    doc=" + docID + " is contained by shape but is outside the returned XYZBounds");
                        log.println("      unquantized=" + unquantizedDocs[docID]);
                        log.println("      quantized=" + docs[docID]);
                        fail = true;
                    }
                }
            }
            if (fail) {
                log.println("  shape=" + shape);
                log.println("  bounds=" + bounds);
                System.out.print(sw.toString());
                fail("invalid bounds for shape=" + shape);
            }
        }
        List<Cell> queue = new ArrayList<>();
        queue.add(root);
        Set<Integer> hits = new HashSet<>();
        while (queue.size() > 0) {
            Cell cell = queue.get(queue.size() - 1);
            queue.remove(queue.size() - 1);
            if (VERBOSE) {
                log.println("  cycle: " + cell + " queue.size()=" + queue.size());
            }
            if (random().nextInt(10) == 7 || cell.splitCount > recurseDepth) {
                if (VERBOSE) {
                    log.println("    leaf");
                }
                // Leaf cell: brute force check all docs that fall within this cell:
                for (int docID = 0; docID < numDocs; docID++) {
                    GeoPoint point = docs[docID];
                    GeoPoint mappedPoint = unquantizedDocs[docID];
                    boolean pointWithinShape = shape.isWithin(point);
                    boolean mappedPointWithinShape = shape.isWithin(mappedPoint);
                    if (cell.contains(point)) {
                        if (mappedPointWithinShape) {
                            if (VERBOSE) {
                                log.println("    check doc=" + docID + ": match!  Actual quantized point within: " + pointWithinShape);
                            }
                            hits.add(docID);
                        } else {
                            if (VERBOSE) {
                                log.println("    check doc=" + docID + ": no match.  Quantized point within: " + pointWithinShape);
                            }
                        }
                    }
                }
            } else {
                GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, Geo3DUtil.decodeValueFloor(cell.xMinEnc), Geo3DUtil.decodeValueCeil(cell.xMaxEnc), Geo3DUtil.decodeValueFloor(cell.yMinEnc), Geo3DUtil.decodeValueCeil(cell.yMaxEnc), Geo3DUtil.decodeValueFloor(cell.zMinEnc), Geo3DUtil.decodeValueCeil(cell.zMaxEnc));
                if (VERBOSE) {
                    log.println("    minx=" + Geo3DUtil.decodeValueFloor(cell.xMinEnc) + " maxx=" + Geo3DUtil.decodeValueCeil(cell.xMaxEnc) + " miny=" + Geo3DUtil.decodeValueFloor(cell.yMinEnc) + " maxy=" + Geo3DUtil.decodeValueCeil(cell.yMaxEnc) + " minz=" + Geo3DUtil.decodeValueFloor(cell.zMinEnc) + " maxz=" + Geo3DUtil.decodeValueCeil(cell.zMaxEnc));
                }
                switch(xyzSolid.getRelationship(shape)) {
                    case GeoArea.CONTAINS:
                        // Shape fully contains the cell: blindly add all docs in this cell:
                        if (VERBOSE) {
                            log.println("    GeoArea.CONTAINS: now addAll");
                        }
                        for (int docID = 0; docID < numDocs; docID++) {
                            if (cell.contains(docs[docID])) {
                                if (VERBOSE) {
                                    log.println("    addAll doc=" + docID);
                                }
                                hits.add(docID);
                            }
                        }
                        continue;
                    case GeoArea.OVERLAPS:
                        if (VERBOSE) {
                            log.println("    GeoArea.OVERLAPS: keep splitting");
                        }
                        //log.println("    crosses1");
                        break;
                    case GeoArea.WITHIN:
                        if (VERBOSE) {
                            log.println("    GeoArea.WITHIN: keep splitting");
                        }
                        //log.println("    crosses2");
                        break;
                    case GeoArea.DISJOINT:
                        //log.println("    outside");
                        if (VERBOSE) {
                            log.println("    GeoArea.DISJOINT: drop this cell");
                            for (int docID = 0; docID < numDocs; docID++) {
                                if (cell.contains(docs[docID])) {
                                    log.println("    skip doc=" + docID);
                                }
                            }
                        }
                        continue;
                    default:
                        assert false;
                }
                // Randomly split:
                switch(random().nextInt(3)) {
                    case 0:
                        // Split on X:
                        {
                            int splitValue = RandomNumbers.randomIntBetween(random(), cell.xMinEnc, cell.xMaxEnc);
                            if (VERBOSE) {
                                log.println("    now split on x=" + splitValue);
                            }
                            Cell cell1 = new Cell(cell, cell.xMinEnc, splitValue, cell.yMinEnc, cell.yMaxEnc, cell.zMinEnc, cell.zMaxEnc, cell.splitCount + 1);
                            Cell cell2 = new Cell(cell, splitValue, cell.xMaxEnc, cell.yMinEnc, cell.yMaxEnc, cell.zMinEnc, cell.zMaxEnc, cell.splitCount + 1);
                            if (VERBOSE) {
                                log.println("    split cell1: " + cell1);
                                log.println("    split cell2: " + cell2);
                            }
                            queue.add(cell1);
                            queue.add(cell2);
                        }
                        break;
                    case 1:
                        // Split on Y:
                        {
                            int splitValue = RandomNumbers.randomIntBetween(random(), cell.yMinEnc, cell.yMaxEnc);
                            if (VERBOSE) {
                                log.println("    now split on y=" + splitValue);
                            }
                            Cell cell1 = new Cell(cell, cell.xMinEnc, cell.xMaxEnc, cell.yMinEnc, splitValue, cell.zMinEnc, cell.zMaxEnc, cell.splitCount + 1);
                            Cell cell2 = new Cell(cell, cell.xMinEnc, cell.xMaxEnc, splitValue, cell.yMaxEnc, cell.zMinEnc, cell.zMaxEnc, cell.splitCount + 1);
                            if (VERBOSE) {
                                log.println("    split cell1: " + cell1);
                                log.println("    split cell2: " + cell2);
                            }
                            queue.add(cell1);
                            queue.add(cell2);
                        }
                        break;
                    case 2:
                        // Split on Z:
                        {
                            int splitValue = RandomNumbers.randomIntBetween(random(), cell.zMinEnc, cell.zMaxEnc);
                            if (VERBOSE) {
                                log.println("    now split on z=" + splitValue);
                            }
                            Cell cell1 = new Cell(cell, cell.xMinEnc, cell.xMaxEnc, cell.yMinEnc, cell.yMaxEnc, cell.zMinEnc, splitValue, cell.splitCount + 1);
                            Cell cell2 = new Cell(cell, cell.xMinEnc, cell.xMaxEnc, cell.yMinEnc, cell.yMaxEnc, splitValue, cell.zMaxEnc, cell.splitCount + 1);
                            if (VERBOSE) {
                                log.println("    split cell1: " + cell1);
                                log.println("    split cell2: " + cell2);
                            }
                            queue.add(cell1);
                            queue.add(cell2);
                        }
                        break;
                }
            }
        }
        if (VERBOSE) {
            log.println("  " + hits.size() + " hits");
        }
        // Done matching, now verify:
        boolean fail = false;
        for (int docID = 0; docID < numDocs; docID++) {
            GeoPoint point = docs[docID];
            GeoPoint mappedPoint = unquantizedDocs[docID];
            boolean expected = shape.isWithin(mappedPoint);
            boolean actual = hits.contains(docID);
            if (actual != expected) {
                if (actual) {
                    log.println("doc=" + docID + " should not have matched but did");
                } else {
                    log.println("doc=" + docID + " should match but did not");
                }
                log.println("  point=" + point);
                log.println("  mappedPoint=" + mappedPoint);
                fail = true;
            }
        }
        if (fail) {
            System.out.print(sw.toString());
            fail("invalid hits for shape=" + shape);
        }
    }
}
Also used : GeoShape(org.apache.lucene.spatial3d.geom.GeoShape) ArrayList(java.util.ArrayList) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) GeoArea(org.apache.lucene.spatial3d.geom.GeoArea) StringWriter(java.io.StringWriter) XYZBounds(org.apache.lucene.spatial3d.geom.XYZBounds) PrintWriter(java.io.PrintWriter) HashSet(java.util.HashSet)

Example 14 with GeoPoint

use of org.apache.lucene.spatial3d.geom.GeoPoint in project lucene-solr by apache.

the class TestGeo3DPoint method explain.

public static String explain(String fieldName, GeoShape shape, GeoPoint targetDocPoint, GeoPoint scaledDocPoint, IndexReader reader, int docID) throws Exception {
    final XYZBounds bounds = new XYZBounds();
    shape.getBounds(bounds);
    // First find the leaf reader that owns this doc:
    int subIndex = ReaderUtil.subIndex(docID, reader.leaves());
    LeafReader leafReader = reader.leaves().get(subIndex).reader();
    StringBuilder b = new StringBuilder();
    b.append("target is in leaf " + leafReader + " of full reader " + reader + "\n");
    DocIdSetBuilder hits = new DocIdSetBuilder(leafReader.maxDoc());
    ExplainingVisitor visitor = new ExplainingVisitor(shape, targetDocPoint, scaledDocPoint, new PointInShapeIntersectVisitor(hits, shape, bounds), docID - reader.leaves().get(subIndex).docBase, 3, Integer.BYTES, b);
    // Do first phase, where we just figure out the "path" that leads to the target docID:
    leafReader.getPointValues(fieldName).intersect(visitor);
    // Do second phase, where we we see how the wrapped visitor responded along that path:
    visitor.startSecondPhase();
    leafReader.getPointValues(fieldName).intersect(visitor);
    return b.toString();
}
Also used : LeafReader(org.apache.lucene.index.LeafReader) XYZBounds(org.apache.lucene.spatial3d.geom.XYZBounds) DocIdSetBuilder(org.apache.lucene.util.DocIdSetBuilder) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint)

Example 15 with GeoPoint

use of org.apache.lucene.spatial3d.geom.GeoPoint in project lucene-solr by apache.

the class TestGeo3DPoint method testEncodeDecodeIsStable.

public void testEncodeDecodeIsStable() throws Exception {
    int iters = atLeast(1000);
    for (int iter = 0; iter < iters; iter++) {
        double lat = GeoTestUtil.nextLatitude();
        double lon = GeoTestUtil.nextLongitude();
        GeoPoint point = new GeoPoint(PlanetModel.WGS84, toRadians(lat), toRadians(lon));
        // encode point
        GeoPoint pointEnc = new GeoPoint(Geo3DUtil.decodeValue(Geo3DUtil.encodeValue(point.x)), Geo3DUtil.decodeValue(Geo3DUtil.encodeValue(point.y)), Geo3DUtil.decodeValue(Geo3DUtil.encodeValue(point.z)));
        // encode it again (double encode)
        GeoPoint pointEnc2 = new GeoPoint(Geo3DUtil.decodeValue(Geo3DUtil.encodeValue(pointEnc.x)), Geo3DUtil.decodeValue(Geo3DUtil.encodeValue(pointEnc.y)), Geo3DUtil.decodeValue(Geo3DUtil.encodeValue(pointEnc.z)));
        //System.out.println("TEST " + iter + ":\n  point    =" + point + "\n  pointEnc =" + pointEnc + "\n  pointEnc2=" + pointEnc2);
        assertEquals(pointEnc.x, pointEnc2.x, 0.0);
        assertEquals(pointEnc.y, pointEnc2.y, 0.0);
        assertEquals(pointEnc.z, pointEnc2.z, 0.0);
    }
}
Also used : GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint)

Aggregations

GeoPoint (org.apache.lucene.spatial3d.geom.GeoPoint)19 ArrayList (java.util.ArrayList)9 GeoShape (org.apache.lucene.spatial3d.geom.GeoShape)6 Test (org.junit.Test)5 Polygon (org.apache.lucene.geo.Polygon)3 GeoBBox (org.apache.lucene.spatial3d.geom.GeoBBox)3 GeoPolygon (org.apache.lucene.spatial3d.geom.GeoPolygon)3 XYZBounds (org.apache.lucene.spatial3d.geom.XYZBounds)3 HashSet (java.util.HashSet)2 GeoPath (org.apache.lucene.spatial3d.geom.GeoPath)2 Rectangle (org.locationtech.spatial4j.shape.Rectangle)2 Shape (org.locationtech.spatial4j.shape.Shape)2 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Document (org.apache.lucene.document.Document)1 NumericDocValuesField (org.apache.lucene.document.NumericDocValuesField)1 IndexReader (org.apache.lucene.index.IndexReader)1 IndexWriter (org.apache.lucene.index.IndexWriter)1 IndexWriterConfig (org.apache.lucene.index.IndexWriterConfig)1