| /* |
| * 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.spatial4j; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.apache.lucene.spatial.SpatialTestData; |
| import org.apache.lucene.spatial.composite.CompositeSpatialStrategy; |
| import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase; |
| import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy; |
| import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree; |
| import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree; |
| import org.apache.lucene.spatial.prefix.tree.S2PrefixTree; |
| import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree; |
| import org.apache.lucene.spatial.query.SpatialOperation; |
| import org.apache.lucene.spatial.serialized.SerializedDVStrategy; |
| import org.apache.lucene.spatial3d.geom.GeoAreaShape; |
| import org.apache.lucene.spatial3d.geom.GeoPath; |
| import org.apache.lucene.spatial3d.geom.GeoPathFactory; |
| import org.apache.lucene.spatial3d.geom.GeoPoint; |
| import org.apache.lucene.spatial3d.geom.GeoPointShape; |
| import org.apache.lucene.spatial3d.geom.GeoPolygonFactory; |
| import org.apache.lucene.spatial3d.geom.PlanetModel; |
| import org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator; |
| import org.junit.Test; |
| import org.locationtech.spatial4j.shape.Rectangle; |
| import org.locationtech.spatial4j.shape.Shape; |
| |
| import static org.locationtech.spatial4j.distance.DistanceUtils.DEGREES_TO_RADIANS; |
| |
| public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase { |
| |
| private PlanetModel planetModel; |
| private RandomGeo3dShapeGenerator shapeGenerator; |
| private SpatialPrefixTree grid; |
| private RecursivePrefixTreeStrategy rptStrategy; |
| |
| private void setupGrid() { |
| int type = random().nextInt(4); |
| if (type == 0) { |
| this.grid = new GeohashPrefixTree(ctx, 2); |
| } else if (type == 1) { |
| this.grid = new QuadPrefixTree(ctx, 5); |
| } else { |
| int arity = random().nextInt(3) + 1; |
| this.grid = new S2PrefixTree(ctx, 5 - arity, arity); |
| } |
| this.rptStrategy = newRPT(); |
| this.rptStrategy.setPruneLeafyBranches(random().nextBoolean()); |
| } |
| |
| protected RecursivePrefixTreeStrategy newRPT() { |
| final RecursivePrefixTreeStrategy rpt = new RecursivePrefixTreeStrategy(this.grid, |
| getClass().getSimpleName() + "_rpt"); |
| rpt.setDistErrPct(0.10);//not too many cells |
| return rpt; |
| } |
| |
| private void setupStrategy() { |
| shapeGenerator = new RandomGeo3dShapeGenerator(); |
| planetModel = shapeGenerator.randomPlanetModel(); |
| Geo3dSpatialContextFactory factory = new Geo3dSpatialContextFactory(); |
| factory.planetModel = planetModel; |
| ctx = factory.newSpatialContext(); |
| |
| setupGrid(); |
| |
| SerializedDVStrategy serializedDVStrategy = new SerializedDVStrategy(ctx, getClass().getSimpleName() + "_sdv"); |
| this.strategy = new CompositeSpatialStrategy("composite_" + getClass().getSimpleName(), |
| rptStrategy, serializedDVStrategy); |
| } |
| |
| @Test |
| public void testFailure1() throws IOException { |
| setupStrategy(); |
| final List<GeoPoint> points = new ArrayList<GeoPoint>(); |
| points.add(new GeoPoint(planetModel, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS)); |
| points.add(new GeoPoint(planetModel, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS)); |
| points.add(new GeoPoint(planetModel, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS)); |
| points.add(new GeoPoint(planetModel, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS)); |
| |
| final Shape triangle = new Geo3dShape<>(GeoPolygonFactory.makeGeoPolygon(planetModel, points),ctx); |
| final Rectangle rect = ctx.makeRectangle(-49, -45, 73, 86); |
| testOperation(rect,SpatialOperation.Intersects,triangle, false); |
| } |
| |
| @Test |
| public void testFailureLucene6535() throws IOException { |
| setupStrategy(); |
| |
| final List<GeoPoint> points = new ArrayList<>(); |
| points.add(new GeoPoint(planetModel, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS)); |
| points.add(new GeoPoint(planetModel, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS)); |
| points.add(new GeoPoint(planetModel, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS)); |
| points.add(new GeoPoint(planetModel, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS)); |
| final GeoPoint[] pathPoints = new GeoPoint[] { |
| new GeoPoint(planetModel, 55.0 * DEGREES_TO_RADIANS, -26.0 * DEGREES_TO_RADIANS), |
| new GeoPoint(planetModel, -90.0 * DEGREES_TO_RADIANS, 0.0), |
| new GeoPoint(planetModel, 54.0 * DEGREES_TO_RADIANS, 165.0 * DEGREES_TO_RADIANS), |
| new GeoPoint(planetModel, -90.0 * DEGREES_TO_RADIANS, 0.0)}; |
| final GeoPath path = GeoPathFactory.makeGeoPath(planetModel, 29 * DEGREES_TO_RADIANS, pathPoints); |
| final Shape shape = new Geo3dShape<>(path,ctx); |
| final Rectangle rect = ctx.makeRectangle(131, 143, 39, 54); |
| testOperation(rect,SpatialOperation.Intersects,shape,true); |
| } |
| |
| @Test |
| public void testOperations() throws IOException { |
| setupStrategy(); |
| |
| testOperationRandomShapes(SpatialOperation.Intersects); |
| } |
| |
| @Override |
| protected Shape randomIndexedShape() { |
| int type = shapeGenerator.randomShapeType(); |
| GeoAreaShape areaShape = shapeGenerator.randomGeoAreaShape(type, planetModel); |
| if (areaShape instanceof GeoPointShape) { |
| return new Geo3dPointShape((GeoPointShape) areaShape, ctx); |
| } |
| return new Geo3dShape<>(areaShape, ctx); |
| } |
| |
| @Override |
| protected Shape randomQueryShape() { |
| int type = shapeGenerator.randomShapeType(); |
| GeoAreaShape areaShape = shapeGenerator.randomGeoAreaShape(type, planetModel); |
| return new Geo3dShape<>(areaShape, ctx); |
| } |
| |
| @Test |
| public void testOperationsFromFile() throws IOException { |
| setupStrategy(); |
| final Iterator<SpatialTestData> indexedSpatialData = getSampleData( "states-poly.txt"); |
| final List<Shape> indexedShapes = new ArrayList<>(); |
| while(indexedSpatialData.hasNext()) { |
| indexedShapes.add(indexedSpatialData.next().shape); |
| } |
| final Iterator<SpatialTestData> querySpatialData = getSampleData( "states-bbox.txt"); |
| final List<Shape> queryShapes = new ArrayList<>(); |
| while(querySpatialData.hasNext()) { |
| queryShapes.add(querySpatialData.next().shape); |
| if (TEST_NIGHTLY) { |
| queryShapes.add(randomQueryShape()); |
| } |
| } |
| queryShapes.add(randomQueryShape()); |
| testOperation(SpatialOperation.Intersects, indexedShapes, queryShapes, random().nextBoolean()); |
| } |
| } |