You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2016/03/09 17:00:19 UTC
[08/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java
new file mode 100755
index 0000000..f5a148f
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java
@@ -0,0 +1,364 @@
+/*
+ * 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.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoBBoxTest {
+
+ protected final double DEGREES_TO_RADIANS = Math.PI / 180.0;
+
+ @Test
+ public void testBBoxDegenerate() {
+ GeoBBox box;
+ GeoConvexPolygon cp;
+ int relationship;
+ List<GeoPoint> points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, 24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -49 * DEGREES_TO_RADIANS, -176 * DEGREES_TO_RADIANS));
+ GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -64 * DEGREES_TO_RADIANS, -64 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, 180 * DEGREES_TO_RADIANS);
+ relationship = box.getRelationship(shape);
+ assertEquals(GeoArea.CONTAINS, relationship);
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -61.85 * DEGREES_TO_RADIANS, -67.5 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, -168.75 * DEGREES_TO_RADIANS);
+ //System.out.println("Shape = " + shape + " Rect = " + box);
+ relationship = box.getRelationship(shape);
+ assertEquals(GeoArea.CONTAINS, relationship);
+ }
+
+ @Test
+ public void testBBoxPointWithin() {
+ GeoBBox box;
+ GeoPoint gp;
+
+ // Standard normal Rect box, not crossing dateline
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 0.0);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.1);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.1);
+ assertFalse(box.isWithin(gp));
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.ARC,gp),1e-2);
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
+
+ // Standard normal Rect box, crossing dateline
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 1.0, -Math.PI + 1.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertFalse(box.isWithin(gp));
+
+ // Latitude zone rectangle
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI, Math.PI);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertTrue(box.isWithin(gp));
+
+ // World
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, Math.PI);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertTrue(box.isWithin(gp));
+
+ }
+
+ @Test
+ public void testBBoxExpand() {
+ GeoBBox box;
+ GeoPoint gp;
+ // Standard normal Rect box, not crossing dateline
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+ box = box.expand(0.1);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.0);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, 0.0);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.15, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.05);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.15);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.05);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.15);
+ assertFalse(box.isWithin(gp));
+ }
+
+ @Test
+ public void testBBoxBounds() {
+ GeoBBox c;
+ LatLonBounds b;
+ XYZBounds xyzb;
+ GeoArea solid;
+ GeoPoint point;
+ int relationship;
+
+ c= GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.7570958596622309, -0.7458670829264561, -0.9566079379002148, 1.4802570961901191);
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,0.10922258701604912,0.1248184603754517,-0.8172414690802067,0.9959041483215542,-0.6136586624726926,0.6821740363641521);
+ point = new GeoPoint(PlanetModel.SPHERE, 0.3719987557178081, 1.4529582778845198);
+ assertTrue(c.isWithin(point));
+ assertTrue(solid.isWithin(point));
+ relationship = solid.getRelationship(c);
+ assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.CONTAINS || relationship == GeoArea.WITHIN);
+
+ c= GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.006607096847842122, -0.002828135860810422, -0.0012934461873348349, 0.006727418645092394);
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,0.9999995988328008,1.0000000002328306,-0.0012934708508166816,0.006727393021214471,-0.002828157275369464,0.006607074060760007);
+ point = new GeoPoint(PlanetModel.SPHERE, -5.236470872437899E-4, 3.992578692654256E-4);
+ assertTrue(c.isWithin(point));
+ assertTrue(solid.isWithin(point));
+ relationship = solid.getRelationship(c);
+ assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.CONTAINS || relationship == GeoArea.WITHIN);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.25, -Math.PI * 0.25, -1.0, 1.0);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
+ assertEquals(1.0, b.getRightLongitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.25, b.getMaxLatitude(), 0.000001);
+ assertEquals(0.382051, xyzb.getMinimumX(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
+ assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(0.707107, xyzb.getMaximumZ(), 0.000001);
+
+ GeoArea area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX() - 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMaximumX() + 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMinimumY() - 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMaximumY() + 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMinimumZ() - 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMaximumZ() + 2.0 * Vector.MINIMUM_RESOLUTION);
+ assertEquals(GeoArea.WITHIN, area.getRelationship(c));
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
+ assertEquals(1.0, b.getRightLongitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+ assertEquals(0.382051, xyzb.getMinimumX(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
+ assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(0.0, xyzb.getMaximumZ(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, 1.0, -1.0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ //assertEquals(1.0,b.getLeftLongitude(),0.000001);
+ //assertEquals(-1.0,b.getRightLongitude(),0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumX(), 0.000001);
+ assertEquals(0.540303, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumY(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(0.0, xyzb.getMaximumZ(), 0.000001);
+
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -1.0, 1.0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
+ //assertEquals(1.0, b.getRightLongitude(), 0.000001);
+ assertEquals(0.0, xyzb.getMinimumX(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
+ assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumZ(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 1.0, -1.0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(1.0,b.getLeftLongitude(),0.000001);
+ //assertEquals(-1.0,b.getRightLongitude(),0.000001);
+ assertEquals(-1.0, xyzb.getMinimumX(), 0.000001);
+ assertEquals(0.540303, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumY(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumZ(), 0.000001);
+
+ // Check wide variants of rectangle and longitude slice
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI + 0.1, Math.PI - 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 0.1, -Math.PI + 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
+ assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI + 0.1, Math.PI - 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, Math.PI - 0.1, -Math.PI + 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
+ //assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
+
+ // Check latitude zone
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 1.0, -1.0, -Math.PI, Math.PI);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-1.0, b.getMinLatitude(), 0.000001);
+ assertEquals(1.0, b.getMaxLatitude(), 0.000001);
+
+ // Now, combine a few things to test the bounds object
+ GeoBBox c1;
+ GeoBBox c2;
+
+ c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
+ c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
+
+ b = new LatLonBounds();
+ c1.getBounds(b);
+ c2.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+
+ c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
+ c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI * 0.5);
+
+ b = new LatLonBounds();
+ c1.getBounds(b);
+ c2.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI*0.5,b.getRightLongitude(),0.000001);
+
+ c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI * 0.5, 0.0);
+ c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
+
+ b = new LatLonBounds();
+ c1.getBounds(b);
+ c2.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI * 0.5,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI,b.getRightLongitude(),0.000001);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java
new file mode 100755
index 0000000..186bf4c
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java
@@ -0,0 +1,410 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+public class GeoCircleTest extends LuceneTestCase {
+
+ @Test
+ public void testCircleDistance() {
+ GeoCircle c;
+ GeoPoint gp;
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertEquals(0.05, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ assertEquals(0.049995, c.computeDistance(DistanceStyle.LINEAR,gp), 0.000001);
+ assertEquals(0.049979, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ }
+
+ @Test
+ public void testCircleFullWorld() {
+ GeoCircle c;
+ GeoPoint gp;
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, Math.PI);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertTrue(c.isWithin(gp));
+ LatLonBounds b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ }
+
+ @Test
+ public void testCirclePointWithin() {
+ GeoCircle c;
+ GeoPoint gp;
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
+ assertEquals(0.12,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),0.01);
+ assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),0.01);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+ }
+
+ @Test
+ public void testCircleBounds() {
+ GeoCircle c;
+ LatLonBounds b;
+ XYZBounds xyzb;
+ GeoArea area;
+ GeoPoint p1;
+ GeoPoint p2;
+ int relationship;
+
+ // ...
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, -0.005931145568901605, -0.001942031539653079, 1.2991918568260272E-4);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, 1.001098377143621, 1.001100011578687, -0.00207467080358696, -0.0018136665346280983, -0.006067808248760161, -0.005807683665759485);
+ p1 = new GeoPoint(PlanetModel.WGS84, -0.00591253844632244, -0.0020069187259065093);
+ p2 = new GeoPoint(1.001099185736782, -0.0020091272069679327, -0.005919118245803968);
+ assertTrue(c.isWithin(p1));
+ assertTrue(area.isWithin(p1));
+ relationship = area.getRelationship(c);
+ assertTrue(relationship != GeoArea.DISJOINT);
+
+ // Twelfth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.00824379317765984,-0.0011677469001838581,0.0011530035396910402);
+ p1 = new GeoPoint(PlanetModel.WGS84,-0.006505092992723671,0.007654282718327381);
+ p2 = new GeoPoint(1.0010681673665647,0.007662608264336381,-0.006512324005914593);
+ assertTrue(!c.isWithin(p1));
+ assertTrue(!c.isWithin(p2));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.WITHIN);
+ // Point is actually outside the bounds, and outside the shape
+ assertTrue(!area.isWithin(p1));
+ // Approximate point the same
+ assertTrue(!area.isWithin(p2));
+
+ // Eleventh BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-0.004431288600558495,-0.003687846671278374,1.704543429364245E-8);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Tenth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.0018829770647349636,-0.001969499061382591,1.3045439293158305E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Ninth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-4.211990380885122E-5,-0.0022958453508173044,1.4318475623498535E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Eighth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,0.005321278689117842,-0.00216937368755372,1.5306034422500785E-4);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Seventh BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-0.0021627146783861745, -0.0017298167021592304,2.0818312293195752E-4);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Sixth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.006450320645814321,0.004660694205115142,0.00489710732634323);
+ //xyzb = new XYZBounds();
+ //c.getBounds(xyzb);
+ //System.err.println("xmin="+xyzb.getMinimumX()+", xmax="+xyzb.getMaximumX()+",ymin="+xyzb.getMinimumY()+", ymax="+xyzb.getMaximumY()+",zmin="+xyzb.getMinimumZ()+", zmax="+xyzb.getMaximumZ());
+ //xmin=1.0010356621420726, xmax=1.0011141249179447,ymin=-2.5326643901354566E-4, ymax=0.009584741915757169,zmin=-0.011359874956269283, zmax=-0.0015549504447452225
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,1.0010822580620098,1.0010945779732867,0.007079167343247293,0.007541006774427837,-0.0021855011220022575,-0.001896122718181518);
+ assertTrue(GeoArea.CONTAINS != area.getRelationship(c));
+ /*
+ p1 = new GeoPoint(1.0010893045436076,0.007380935180644008,-0.002140671370616495);
+ // This has a different bounding box, so we can't use it.
+ //p2 = new GeoPoint(PlanetModel.WGS84,-0.002164069780096702, 0.007505617500830066);
+ p2 = new GeoPoint(PlanetModel.WGS84,p1.getLatitude(),p1.getLongitude());
+ assertTrue(PlanetModel.WGS84.pointOnSurface(p2));
+ assertTrue(!c.isWithin(p2));
+ assertTrue(!area.isWithin(p2));
+ assertTrue(!c.isWithin(p1));
+ assertTrue(PlanetModel.WGS84.pointOnSurface(p1)); // This fails
+ assertTrue(!area.isWithin(p1)); // This fails
+ */
+
+ // Fifth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.004282454525970269, -1.6739831367422277E-4, 1.959639723134033E-6);
+ assertTrue(c.isWithin(c.getEdgePoints()[0]));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ assertTrue(GeoArea.WITHIN == area.getRelationship(c) || GeoArea.OVERLAPS == area.getRelationship(c));
+
+ // Fourth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.0048795517261255, 0.004053904306995974, 5.93699764258874E-6);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ assertTrue(GeoArea.WITHIN == area.getRelationship(c) || GeoArea.OVERLAPS == area.getRelationship(c));
+
+ // Yet another test case from BKD
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, 0.006229478708446979, 0.005570196723795424, 3.840276763694387E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ p1 = new GeoPoint(PlanetModel.WGS84, 0.006224927111830945, 0.005597367237251763);
+ p2 = new GeoPoint(1.0010836083810235, 0.005603490759433942, 0.006231850560862502);
+ assertTrue(PlanetModel.WGS84.pointOnSurface(p1));
+ //assertTrue(PlanetModel.WGS84.pointOnSurface(p2));
+ assertTrue(c.isWithin(p1));
+ assertTrue(c.isWithin(p2));
+ assertTrue(area.isWithin(p1));
+ assertTrue(area.isWithin(p2));
+
+ // Another test case from BKD
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.005955031040627789, -0.0029274772647399153, 1.601488279374338E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+
+ // Test case from BKD
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.765816119338, 0.991848766844, 0.8153163226330487);
+ p1 = new GeoPoint(0.7692262265236023, -0.055089298115534646, -0.6365973465711254);
+ assertTrue(c.isWithin(p1));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(p1.x >= xyzb.getMinimumX() && p1.x <= xyzb.getMaximumX());
+ assertTrue(p1.y >= xyzb.getMinimumY() && p1.y <= xyzb.getMaximumY());
+ assertTrue(p1.z >= xyzb.getMinimumZ() && p1.z <= xyzb.getMaximumZ());
+
+ // Vertical circle cases
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.4, b.getLeftLongitude(), 0.000001);
+ assertEquals(0.6, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.1, b.getLeftLongitude(), 0.000001);
+ assertEquals(0.1, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
+ assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ // Horizontal circle cases
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI * 0.5 - 0.1, b.getMinLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ assertEquals(-Math.PI * 0.5 + 0.1, b.getMaxLatitude(), 0.000001);
+
+ // Now do a somewhat tilted plane, facing different directions.
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI * 0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.5 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(Math.PI * 0.5 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -Math.PI * 0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-Math.PI * 0.5 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI * 0.5 + 0.1, b.getRightLongitude(), 0.00001);
+
+ // Slightly tilted, PI/4 direction.
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.01, Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.09, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.11, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.01, -Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.09, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.11, b.getMinLatitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ // Now do a somewhat tilted plane.
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-0.6, b.getLeftLongitude(), 0.00001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.00001);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java
new file mode 100755
index 0000000..a6ca404
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoConvexPolygonTest {
+
+
+ @Test
+ public void testPolygonPointWithin() {
+ GeoConvexPolygon c;
+ GeoPoint gp;
+ c = new GeoConvexPolygon(PlanetModel.SPHERE, -0.1, -0.5);
+ c.addPoint(0.0, -0.6, false);
+ c.addPoint(0.1, -0.5, false);
+ c.addPoint(0.0, -0.4, false);
+ c.done(false);
+ // Sample some points within
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ // Sample some nearby points outside, and compute distance-to-shape for them as well
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
+ assertFalse(c.isWithin(gp));
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-3);
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),1e-3);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ // Random points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+ }
+
+ @Test
+ public void testPolygonBounds() {
+ GeoConvexPolygon c;
+ LatLonBounds b;
+
+ c = new GeoConvexPolygon(PlanetModel.SPHERE, -0.1, -0.5);
+ c.addPoint(0.0, -0.6, false);
+ c.addPoint(0.1, -0.5, false);
+ c.addPoint(0.0, -0.4, false);
+ c.done(false);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java
new file mode 100644
index 0000000..d5fcbdd
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test basic plane functionality.
+ */
+public class GeoModelTest {
+
+ protected final static PlanetModel scaledModel = new PlanetModel(1.2,1.5);
+
+ @Test
+ public void testBasicCircle() {
+ // The point of this test is just to make sure nothing blows up doing normal things with a quite non-spherical model
+ // Make sure that the north pole is in the circle, and south pole isn't
+ final GeoPoint northPole = new GeoPoint(scaledModel, Math.PI * 0.5, 0.0);
+ final GeoPoint southPole = new GeoPoint(scaledModel, -Math.PI * 0.5, 0.0);
+ final GeoPoint point1 = new GeoPoint(scaledModel, Math.PI * 0.25, 0.0);
+ final GeoPoint point2 = new GeoPoint(scaledModel, Math.PI * 0.125, 0.0);
+
+ GeoCircle circle = new GeoStandardCircle(scaledModel, Math.PI * 0.5, 0.0, 0.01);
+ assertTrue(circle.isWithin(northPole));
+ assertFalse(circle.isWithin(southPole));
+ assertFalse(circle.isWithin(point1));
+ LatLonBounds bounds;
+ bounds = new LatLonBounds();
+ circle.getBounds(bounds);
+ assertTrue(bounds.checkNoLongitudeBound());
+ assertTrue(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI * 0.5 - 0.01, bounds.getMinLatitude(), 0.01);
+
+ circle = new GeoStandardCircle(scaledModel, Math.PI * 0.25, 0.0, 0.01);
+ assertTrue(circle.isWithin(point1));
+ assertFalse(circle.isWithin(northPole));
+ assertFalse(circle.isWithin(southPole));
+ bounds = new LatLonBounds();
+ circle.getBounds(bounds);
+ assertFalse(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoLongitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI * 0.25 + 0.01, bounds.getMaxLatitude(), 0.00001);
+ assertEquals(Math.PI * 0.25 - 0.01, bounds.getMinLatitude(), 0.00001);
+ assertEquals(-0.0125, bounds.getLeftLongitude(), 0.0001);
+ assertEquals(0.0125, bounds.getRightLongitude(), 0.0001);
+
+ circle = new GeoStandardCircle(scaledModel, Math.PI * 0.125, 0.0, 0.01);
+ assertTrue(circle.isWithin(point2));
+ assertFalse(circle.isWithin(northPole));
+ assertFalse(circle.isWithin(southPole));
+ bounds = new LatLonBounds();
+ circle.getBounds(bounds);
+ assertFalse(bounds.checkNoLongitudeBound());
+ assertFalse(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ // Symmetric, as expected
+ assertEquals(Math.PI * 0.125 - 0.01, bounds.getMinLatitude(), 0.00001);
+ assertEquals(Math.PI * 0.125 + 0.01, bounds.getMaxLatitude(), 0.00001);
+ assertEquals(-0.0089, bounds.getLeftLongitude(), 0.0001);
+ assertEquals(0.0089, bounds.getRightLongitude(), 0.0001);
+
+ }
+
+ @Test
+ public void testBasicRectangle() {
+ final GeoBBox bbox = GeoBBoxFactory.makeGeoBBox(scaledModel, 1.0, 0.0, 0.0, 1.0);
+ final GeoPoint insidePoint = new GeoPoint(scaledModel, 0.5, 0.5);
+ assertTrue(bbox.isWithin(insidePoint));
+ final GeoPoint topOutsidePoint = new GeoPoint(scaledModel, 1.01, 0.5);
+ assertFalse(bbox.isWithin(topOutsidePoint));
+ final GeoPoint bottomOutsidePoint = new GeoPoint(scaledModel, -0.01, 0.5);
+ assertFalse(bbox.isWithin(bottomOutsidePoint));
+ final GeoPoint leftOutsidePoint = new GeoPoint(scaledModel, 0.5, -0.01);
+ assertFalse(bbox.isWithin(leftOutsidePoint));
+ final GeoPoint rightOutsidePoint = new GeoPoint(scaledModel, 0.5, 1.01);
+ assertFalse(bbox.isWithin(rightOutsidePoint));
+ final LatLonBounds bounds = new LatLonBounds();
+ bbox.getBounds(bounds);
+ assertFalse(bounds.checkNoLongitudeBound());
+ assertFalse(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ assertEquals(1.0, bounds.getMaxLatitude(), 0.00001);
+ assertEquals(0.0, bounds.getMinLatitude(), 0.00001);
+ assertEquals(1.0, bounds.getRightLongitude(), 0.00001);
+ assertEquals(0.0, bounds.getLeftLongitude(), 0.00001);
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java
new file mode 100755
index 0000000..3746069
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java
@@ -0,0 +1,270 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.junit.Test;
+
+import static java.lang.Math.toRadians;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoPathTest {
+
+ @Test
+ public void testPathDistance() {
+ // Start with a really simple case
+ GeoPath p;
+ GeoPoint gp;
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(0.0, 0.0);
+ p.addPoint(0.0, 0.1);
+ p.addPoint(0.0, 0.2);
+ p.done();
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.15);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
+ assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
+ assertEquals(0.12 + 0.0, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, 0.05);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.25);
+ assertEquals(0.20 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.05);
+ assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+
+ // Compute path distances now
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(0.0, 0.0);
+ p.addPoint(0.0, 0.1);
+ p.addPoint(0.0, 0.2);
+ p.done();
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
+ assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
+ assertEquals(0.12, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+
+ // Now try a vertical path, and make sure distances are as expected
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(-Math.PI * 0.25, -0.5);
+ p.addPoint(Math.PI * 0.25, -0.5);
+ p.done();
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.25 + 0.05, -0.5);
+ assertEquals(Math.PI * 0.5 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, -0.5);
+ assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ }
+
+ @Test
+ public void testPathPointWithin() {
+ // Tests whether we can properly detect whether a point is within a path or not
+ GeoPath p;
+ GeoPoint gp;
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ // Build a diagonal path crossing the equator
+ p.addPoint(-0.2, -0.2);
+ p.addPoint(0.2, 0.2);
+ p.done();
+ // Test points on the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, -0.2);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.1);
+ assertTrue(p.isWithin(gp));
+ // Test points off the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, 0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.2, -0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(p.isWithin(gp));
+ // Repeat the test, but across the terminator
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ // Build a diagonal path crossing the equator
+ p.addPoint(-0.2, Math.PI - 0.2);
+ p.addPoint(0.2, -Math.PI + 0.2);
+ p.done();
+ // Test points on the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, Math.PI - 0.2);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI + 0.1);
+ assertTrue(p.isWithin(gp));
+ // Test points off the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, -Math.PI + 0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.2, Math.PI - 0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(p.isWithin(gp));
+
+ }
+
+ @Test
+ public void testGetRelationship() {
+ GeoArea rect;
+ GeoPath p;
+ GeoPath c;
+ GeoPoint point;
+ GeoPoint pointApprox;
+ int relationship;
+ GeoArea area;
+ PlanetModel planetModel;
+
+ planetModel = new PlanetModel(1.151145876105594, 0.8488541238944061);
+ c = new GeoPath(planetModel, 0.008726646259971648);
+ c.addPoint(-0.6925658899376476, 0.6316613927914589);
+ c.addPoint(0.27828548161836364, 0.6785795524104564);
+ c.done();
+ point = new GeoPoint(planetModel,-0.49298555067758226, 0.9892440995026406);
+ pointApprox = new GeoPoint(0.5110940362119821, 0.7774603209946239, -0.49984312299556544);
+ area = GeoAreaFactory.makeGeoArea(planetModel, 0.49937141144985997, 0.5161765426256085, 0.3337218719537796,0.8544419570901649, -0.6347692823688085, 0.3069696588119369);
+ assertTrue(!c.isWithin(point));
+
+ // Start by testing the basic kinds of relationship, increasing in order of difficulty.
+
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(-0.3, -0.3);
+ p.addPoint(0.3, 0.3);
+ p.done();
+ // Easiest: The path is wholly contains the georect
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.05, 0.05);
+ assertEquals(GeoArea.CONTAINS, rect.getRelationship(p));
+ // Next easiest: Some endpoints of the rectangle are inside, and some are outside.
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.05, 0.5);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ // Now, all points are outside, but the figures intersect
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.5, 0.5);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ // Finally, all points are outside, and the figures *do not* intersect
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, 0.5);
+ assertEquals(GeoArea.WITHIN, rect.getRelationship(p));
+ // Check that segment edge overlap detection works
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.1, 0.0, -0.1, 0.0);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.2, 0.1, -0.2, -0.1);
+ assertEquals(GeoArea.DISJOINT, rect.getRelationship(p));
+ // Check if overlap at endpoints behaves as expected next
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, -0.35);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, -0.45);
+ assertEquals(GeoArea.DISJOINT, rect.getRelationship(p));
+
+ }
+
+ @Test
+ public void testPathBounds() {
+ GeoPath c;
+ LatLonBounds b;
+ XYZBounds xyzb;
+ GeoPoint point;
+ int relationship;
+ GeoArea area;
+ PlanetModel planetModel;
+
+ planetModel = new PlanetModel(0.751521665790406,1.248478334209594);
+ c = new GeoPath(planetModel, 0.7504915783575618);
+ c.addPoint(0.10869761172400265, 0.08895880215465272);
+ c.addPoint(0.22467878641991612, 0.10972973084229565);
+ c.addPoint(-0.7398772468744732, -0.4465812941383364);
+ c.addPoint(-0.18462055300079366, -0.6713857796763727);
+ c.done();
+ point = new GeoPoint(planetModel,-0.626645355125733,-1.409304625439381);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(planetModel,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+ assertTrue(area.isWithin(point));
+ // No longer true due to fixed GeoPath waypoints.
+ //assertTrue(c.isWithin(point));
+
+ c = new GeoPath(PlanetModel.WGS84, 0.6894050545377601);
+ c.addPoint(-0.0788176065762948, 0.9431251741731624);
+ c.addPoint(0.510387871458147, 0.5327078872484678);
+ c.addPoint(-0.5624521609859962, 1.5398841746888388);
+ c.addPoint(-0.5025171434638661, -0.5895998642788894);
+ c.done();
+ point = new GeoPoint(PlanetModel.WGS84, 0.023652082107211682, 0.023131910152748437);
+ //System.err.println("Point.x = "+point.x+"; point.y="+point.y+"; point.z="+point.z);
+ assertTrue(c.isWithin(point));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println("minx="+xyzb.getMinimumX()+" maxx="+xyzb.getMaximumX()+" miny="+xyzb.getMinimumY()+" maxy="+xyzb.getMaximumY()+" minz="+xyzb.getMinimumZ()+" maxz="+xyzb.getMaximumZ());
+ //System.err.println("point.x="+point.x+" point.y="+point.y+" point.z="+point.z);
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+ assertTrue(area.isWithin(point));
+
+ c = new GeoPath(PlanetModel.WGS84, 0.7766715171374766);
+ c.addPoint(-0.2751718361148076, -0.7786721269011477);
+ c.addPoint(0.5728375851539309, -1.2700115736820465);
+ c.done();
+ point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
+ assertTrue(c.isWithin(point));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println("minx="+xyzb.getMinimumX()+" maxx="+xyzb.getMaximumX()+" miny="+xyzb.getMinimumY()+" maxy="+xyzb.getMaximumY()+" minz="+xyzb.getMinimumZ()+" maxz="+xyzb.getMaximumZ());
+ //System.err.println("point.x="+point.x+" point.y="+point.y+" point.z="+point.z);
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+ assertTrue(area.isWithin(point));
+
+ c = new GeoPath(PlanetModel.SPHERE, 0.1);
+ c.addPoint(-0.3, -0.3);
+ c.addPoint(0.3, 0.3);
+ c.done();
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.4046919, b.getLeftLongitude(), 0.000001);
+ assertEquals(0.4046919, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.3999999, b.getMinLatitude(), 0.000001);
+ assertEquals(0.3999999, b.getMaxLatitude(), 0.000001);
+
+ }
+
+ @Test
+ public void testCoLinear() {
+ // p1: (12,-90), p2: (11, -55), (129, -90)
+ GeoPath p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(toRadians(-90), toRadians(12));//south pole
+ p.addPoint(toRadians(-55), toRadians(11));
+ p.addPoint(toRadians(-90), toRadians(129));//south pole again
+ p.done();//at least test this doesn't bomb like it used too -- LUCENE-6520
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java
new file mode 100644
index 0000000..ed17928
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomFloat;
+
+/**
+ * Test basic GeoPoint functionality.
+ */
+public class GeoPointTest extends LuceneTestCase {
+ static final double DEGREES_TO_RADIANS = Math.PI / 180;
+
+ @Test
+ public void testConversion() {
+ testPointRoundTrip(PlanetModel.SPHERE, 90 * DEGREES_TO_RADIANS, 0, 1e-6);
+ testPointRoundTrip(PlanetModel.SPHERE, -90 * DEGREES_TO_RADIANS, 0, 1e-6);
+ testPointRoundTrip(PlanetModel.WGS84, 90 * DEGREES_TO_RADIANS, 0, 1e-6);
+ testPointRoundTrip(PlanetModel.WGS84, -90 * DEGREES_TO_RADIANS, 0, 1e-6);
+
+ final int times = atLeast(100);
+ for (int i = 0; i < times; i++) {
+ final double pLat = (randomFloat() * 180.0 - 90.0) * DEGREES_TO_RADIANS;
+ final double pLon = (randomFloat() * 360.0 - 180.0) * DEGREES_TO_RADIANS;
+ testPointRoundTrip(PlanetModel.SPHERE, pLat, pLon, 1e-6);//1e-6 since there's a square root in there (Karl says)
+ testPointRoundTrip(PlanetModel.WGS84, pLat, pLon, 1e-6);
+ }
+ }
+
+ protected void testPointRoundTrip(PlanetModel planetModel, double pLat, double pLon, double epsilon) {
+ final GeoPoint p1 = new GeoPoint(planetModel, pLat, pLon);
+ // In order to force the reverse conversion, we have to construct a geopoint from just x,y,z
+ final GeoPoint p2 = new GeoPoint(p1.x, p1.y, p1.z);
+ // Now, construct the final point based on getLatitude() and getLongitude()
+ final GeoPoint p3 = new GeoPoint(planetModel, p2.getLatitude(), p2.getLongitude());
+ double dist = p1.arcDistance(p3);
+ assertEquals(0, dist, epsilon);
+ }
+
+ @Test
+ public void testSurfaceDistance() {
+ final int times = atLeast(100);
+ for (int i = 0; i < times; i++) {
+ final double p1Lat = (randomFloat() * 180.0 - 90.0) * DEGREES_TO_RADIANS;
+ final double p1Lon = (randomFloat() * 360.0 - 180.0) * DEGREES_TO_RADIANS;
+ final double p2Lat = (randomFloat() * 180.0 - 90.0) * DEGREES_TO_RADIANS;
+ final double p2Lon = (randomFloat() * 360.0 - 180.0) * DEGREES_TO_RADIANS;
+ final GeoPoint p1 = new GeoPoint(PlanetModel.SPHERE, p1Lat, p1Lon);
+ final GeoPoint p2 = new GeoPoint(PlanetModel.SPHERE, p2Lat, p2Lon);
+ final double arcDistance = p1.arcDistance(p2);
+ // Compute ellipsoid distance; it should agree for a sphere
+ final double surfaceDistance = PlanetModel.SPHERE.surfaceDistance(p1,p2);
+ assertEquals(arcDistance, surfaceDistance, 1e-6);
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadLatLon() {
+ new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
new file mode 100755
index 0000000..d9b220d
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoPolygonTest {
+
+
+ @Test
+ public void testPolygonPointWithin() {
+ GeoMembershipShape c;
+ GeoPoint gp;
+ List<GeoPoint> points;
+
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+ // Sample some points within
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ // Sample some nearby points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ // Random points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.01, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.7));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.8));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.7));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.01, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
+
+ /*
+ System.out.println("Points: ");
+ for (GeoPoint p : points) {
+ System.out.println(" "+p);
+ }
+ */
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+ // Sample some points within
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.7);
+ assertTrue(c.isWithin(gp));
+ // Sample some nearby points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ // Random points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+
+ }
+
+ @Test
+ public void testPolygonBounds() {
+ GeoMembershipShape c;
+ LatLonBounds b;
+ List<GeoPoint> points;
+ XYZBounds xyzb;
+ GeoPoint point;
+ GeoArea area;
+
+ // BKD failure
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.WGS84, -0.36716183577912814, 1.4836349969188696));
+ points.add(new GeoPoint(PlanetModel.WGS84, 0.7846038240742979, -0.02743348424931823));
+ points.add(new GeoPoint(PlanetModel.WGS84, -0.7376479402362607, -0.5072961758807019));
+ points.add(new GeoPoint(PlanetModel.WGS84, -0.3760415907667887, 1.4970455334565513));
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, 1);
+
+ point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
+ assertTrue(c.isWithin(point));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ assertTrue(area.isWithin(point));
+
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
new file mode 100644
index 0000000..91bd0c3
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test basic plane functionality.
+ */
+public class PlaneTest {
+
+
+ @Test
+ public void testIdenticalPlanes() {
+ final GeoPoint p = new GeoPoint(PlanetModel.SPHERE, 0.123, -0.456);
+ final Plane plane1 = new Plane(p, 0.0);
+ final Plane plane2 = new Plane(p, 0.0);
+ assertTrue(plane1.isNumericallyIdentical(plane2));
+ final Plane plane3 = new Plane(p, 0.1);
+ assertFalse(plane1.isNumericallyIdentical(plane3));
+ final Vector v1 = new Vector(0.1, -0.732, 0.9);
+ final double constant = 0.432;
+ final Vector v2 = new Vector(v1.x * constant, v1.y * constant, v1.z * constant);
+ final Plane p1 = new Plane(v1, 0.2);
+ final Plane p2 = new Plane(v2, 0.2 * constant);
+ assertTrue(p1.isNumericallyIdentical(p2));
+ }
+
+ @Test
+ public void testInterpolation() {
+ // [X=0.35168818443386646, Y=-0.19637966197066342, Z=0.9152870857244183],
+ // [X=0.5003343189532654, Y=0.522128543226148, Z=0.6906861469771293],
+
+ final GeoPoint start = new GeoPoint(0.35168818443386646, -0.19637966197066342, 0.9152870857244183);
+ final GeoPoint end = new GeoPoint(0.5003343189532654, 0.522128543226148, 0.6906861469771293);
+
+ // [A=-0.6135342247741855, B=0.21504338363863665, C=0.28188192383666794, D=0.0, side=-1.0] internal? false;
+ final Plane p = new Plane(-0.6135342247741855, 0.21504338363863665, 0.28188192383666794, 0.0);
+
+ final GeoPoint[] points = p.interpolate(start, end, new double[]{0.25, 0.50, 0.75});
+
+ for (GeoPoint point : points) {
+ assertTrue(p.evaluateIsZero(point));
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java
new file mode 100644
index 0000000..98c616e
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java
@@ -0,0 +1,220 @@
+/*
+ * 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.spatial3d.geom;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+public class XYZSolidTest extends LuceneTestCase {
+
+ @Test
+ public void testNonDegenerateRelationships() {
+ XYZSolid s;
+ GeoShape shape;
+ // Something bigger than the world
+ s = new StandardXYZSolid(PlanetModel.SPHERE, -2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
+ // Any shape, except whole world, should be within.
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.WITHIN, s.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ // An XYZSolid represents a surface shape, which when larger than the world is in fact
+ // the entire world, so it should overlap the world.
+ assertEquals(GeoArea.OVERLAPS, s.getRelationship(shape));
+
+ // Something overlapping the world on only one side
+ s = new StandardXYZSolid(PlanetModel.SPHERE, -2.0, 0.0, -2.0, 2.0, -2.0, 2.0);
+ // Some things should be disjoint...
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
+ // And, some things should be within...
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.WITHIN, s.getRelationship(shape));
+ // And, some things should overlap.
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, s.getRelationship(shape));
+
+ // Partial world should be contained by GeoWorld object...
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, s.getRelationship(shape));
+
+ // Something inside the world
+ s = new StandardXYZSolid(PlanetModel.SPHERE, -0.1, 0.1, -0.1, 0.1, -0.1, 0.1);
+ // All shapes should be disjoint
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
+
+ }
+
+ @Test
+ public void testDegenerateRelationships() {
+ GeoArea solid;
+ GeoShape shape;
+
+ // Basic test of the factory method - non-degenerate
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, -2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
+ // Any shape, except whole world, should be within.
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.WITHIN, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ // An XYZSolid represents a surface shape, which when larger than the world is in fact
+ // the entire world, so it should overlap the world.
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // Build a degenerate point, not on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a degenerate point that IS on the sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y), which has no points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -0.1, 0.1);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y) which has one point on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -0.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y) which has two points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -1.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,z), which has no points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, 0.0, 0.0);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,z) which has one point on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 1.1, 0.0, 0.0);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y) which has two points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -1.1, 1.1, 0.0, 0.0);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // MHL for y-z check
+
+ // Build a shape that is degenerate in x, which has zero points intersecting sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, -0.1, 0.1);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape that is degenerate in x, which has zero points intersecting sphere, second variation
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, 1.1, 1.2);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape that is disjoint in X but intersects sphere in a complete circle
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -1.1, 1.1, -1.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // Build a shape that is disjoint in X but intersects sphere in a half circle in Y
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 1.1, -1.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // MHL for degenerate Y
+ // MHL for degenerate Z
+
+ }
+
+}