You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kw...@apache.org on 2017/08/03 13:50:10 UTC
[1/3] lucene-solr:branch_6x: LUCENE-7606: Add spatial relationships
between all currently-defined Geo shapes
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6x 5aa71427f -> b294052d5
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/SimpleGeoPolygonRelationshipsTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/SimpleGeoPolygonRelationshipsTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/SimpleGeoPolygonRelationshipsTest.java
new file mode 100644
index 0000000..0d33639
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/SimpleGeoPolygonRelationshipsTest.java
@@ -0,0 +1,837 @@
+/*
+* 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.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Check relationship between polygon and GeoShapes of basic polygons. Normally we construct
+ * the convex, concave counterpart and the convex polygon as a complex polygon.
+ */
+public class SimpleGeoPolygonRelationshipsTest {
+
+ /**
+ * Test with two shapes with no crossing edges and no points in common in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygon1() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
+ GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -60.4,
+ 20.1, -60.4,
+ 20.1, -60.3,
+ 20.0, -60.3);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -60.4,
+ 20.1, -60.4,
+ 20.1, -60.3,
+ 20.0, -60.3);
+
+
+ //Convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.WITHIN, rel);//Check
+
+ //Concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //Complex
+ rel = originalComplexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = originalComplexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+ }
+
+
+ /**
+ * Test with two shapes with crossing edges and some points inside in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygon2() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
+ GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ //POLYGON ((20.0 -60.4, 23.1 -60.4, 23.1 -60.3, 20.0 -60.3,20.0 -60.4))
+ GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -60.4,
+ 23.1, -60.4,
+ 23.1, -60.3,
+ 20.0, -60.3);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -60.4,
+ 23.1, -60.4,
+ 23.1, -60.3,
+ 20.0, -60.3);
+
+ //Convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //Concave
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //Complex
+ rel = originalComplexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+
+ rel = originalComplexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ /**
+ * Test with two shapes with no crossing edges and all points inside in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygon3() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
+ GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ //POLYGON ((20.0 -61.1, 20.1 -61.1, 20.1 -60.5, 20.0 -60.5,20.0 -61.1))
+ GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -61.1,
+ 20.1, -61.1,
+ 20.1, -60.5,
+ 20.0, -60.5);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -61.1,
+ 20.1, -61.1,
+ 20.1, -60.5,
+ 20.0, -60.5);
+
+ //Convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //Concave
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.WITHIN, rel);//check
+
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ //Complex
+ rel = originalComplexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalComplexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ /**
+ * Test with two shapes with crossing edges and no points inside in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygon4() {
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
+ GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ //POLYGON ((20.0 -62.4, 20.1 -62.4, 20.1 -60.3, 20.0 -60.3,20.0 -62.4)) intersects no points inside
+ GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -62.4,
+ 20.1, -62.4,
+ 20.1, -60.3,
+ 20.0, -60.3);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -62.4,
+ 20.1, -62.4,
+ 20.1, -60.3,
+ 20.0, -60.3);
+
+ //Convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //Complex
+ rel = originalComplexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalComplexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalComplexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ /**
+ * Test with two shapes with no crossing edges and polygon in hole in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygonWithHole1() {
+ //POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
+ GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7);
+ GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31, hole);
+
+ GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31);
+
+ GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7, holeInv);
+
+ //POLYGON((-135.7 -30.6, -135.7 -30.45, -136 -30.45, -136 -30.6, -135.7 -30.6)) in the hole
+ GeoPolygon polConvex = buildConvexGeoPolygon(-135.7, -30.6,
+ -135.7, -30.45,
+ -136, -30.45,
+ -136, -30.6);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-135.7, -30.6,
+ -135.7, -30.45,
+ -136, -30.45,
+ -136, -30.6);
+
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.WITHIN, rel);
+ }
+
+ /**
+ * Test with two shapes with crossing edges in hole and some points inside in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygonWithHole2() {
+ //POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
+ GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7);
+ GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31, hole);
+
+ GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31);
+
+ GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7, holeInv);
+
+ //POLYGON((-135.5 -31.2, -135.5 -30.8, -136 -30.8, -136 -31.2, -135.5 -31.2)) intersects the hole
+ GeoPolygon polConvex = buildConvexGeoPolygon(-135.5, -30.2,
+ -135.5, -30.8,
+ -136, -30.8,
+ -136, -30.2);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-135.5, -30.2,
+ -135.5, -30.8,
+ -136, -30.8,
+ -136, -30.2);
+
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ /**
+ * Test with two shapes with crossing edges and some points inside in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygonWithHole3() {
+ //POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
+ GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7);
+ GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31, hole);
+
+ GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31);
+
+ GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7, holeInv);
+
+ //POLYGON((-135.2 -30.8, -135.2 -30.2, -136.8 -30.2, -136.8 -30.8, -135.2 -30.8)) inside the polygon covering the hole
+ GeoPolygon polConvex = buildConvexGeoPolygon(-135.2, -30.8,
+ -135.2, -30.3,
+ -136.8, -30.2,
+ -136.8, -30.8);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-135.2, -30.8,
+ -135.2, -30.3,
+ -136.8, -30.2,
+ -136.8, -30.8);
+
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ /**
+ * Test with two shapes with no crossing edges and all points inside in convex case.
+ */
+ @Test
+ public void testGeoSimplePolygonWithHole4() {
+ //POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
+ GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7);
+ GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31, hole);
+
+ GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
+ -135, -30,
+ -137, -30,
+ -137, -31);
+
+ GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
+ -135.5, -30.4,
+ -136.5, -30.4,
+ -136.5, -30.7, holeInv);
+
+ // POLYGON((-135.7 -30.3, -135.7 -30.2, -136 -30.2, -136 -30.3, -135.7 -30.3))inside the polygon
+ GeoPolygon polConvex = buildConvexGeoPolygon(-135.7, -30.3,
+ -135.7, -30.2,
+ -136, -30.2,
+ -136, -30.3);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-135.7, -30.3,
+ -135.7, -30.2,
+ -136, -30.2,
+ -136, -30.3);
+
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConvexPolInv.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPolInv);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoSimplePolygonWithCircle() {
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
+ GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoCircle outCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-70), Math.toRadians(23), Math.toRadians(1));
+ int rel = originalConvexPol.getRelationship(outCircle);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = originalConcavePol.getRelationship(outCircle);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = originalComplexPol.getRelationship(outCircle);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ GeoCircle overlapCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-61.5), Math.toRadians(20), Math.toRadians(1));
+ rel = originalConvexPol.getRelationship(overlapCircle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = originalConcavePol.getRelationship(overlapCircle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = originalComplexPol.getRelationship(overlapCircle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ GeoCircle inCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(21), Math.toRadians(0.1));
+ rel = originalConvexPol.getRelationship(inCircle);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = originalConcavePol.getRelationship(inCircle);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = originalComplexPol.getRelationship(inCircle);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ GeoCircle onCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(21), Math.toRadians(10.));
+ rel = originalConvexPol.getRelationship(onCircle);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = originalConcavePol.getRelationship(onCircle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = originalComplexPol.getRelationship(onCircle);
+ assertEquals(GeoArea.CONTAINS, rel);
+ }
+
+ @Test
+ public void testGeoSimplePolygonWithBBox() {
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
+ GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713);
+
+ GeoBBox outRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-69),
+ Math.toRadians(-70),
+ Math.toRadians(22),
+ Math.toRadians(23));
+ int rel = originalConvexPol.getRelationship(outRectangle);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = outRectangle.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = originalConcavePol.getRelationship(outRectangle);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = originalComplexPol.getRelationship(outRectangle);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ GeoBBox overlapRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-61),
+ Math.toRadians(-62),
+ Math.toRadians(22),
+ Math.toRadians(23));
+ rel = originalConvexPol.getRelationship(overlapRectangle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = overlapRectangle.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = originalConcavePol.getRelationship(overlapRectangle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = originalComplexPol.getRelationship(overlapRectangle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ GeoBBox inRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-61),
+ Math.toRadians(-61.1),
+ Math.toRadians(22.5),
+ Math.toRadians(23));
+ rel = originalConvexPol.getRelationship(inRectangle);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = inRectangle.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = originalConcavePol.getRelationship(inRectangle);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = originalComplexPol.getRelationship(inRectangle);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ GeoBBox onRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-59),
+ Math.toRadians(-64.1),
+ Math.toRadians(18.5),
+ Math.toRadians(27));
+ rel = originalConvexPol.getRelationship(onRectangle);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = onRectangle.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = originalConcavePol.getRelationship(onRectangle);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = originalComplexPol.getRelationship(onRectangle);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ }
+
+ @Test
+ public void testGeoSimplePolygonWithComposite() {
+ GeoShape shape = getCompositeShape();
+
+ //POLYGON((-145.8555 -5.13, -145.8540 -5.13, -145.8540 -5.12, -145.8555 -5.12, -145.8555 -5.13))
+ GeoPolygon polConvex = buildConvexGeoPolygon(-145.8555, -5.13,
+ -145.8540, -5.13,
+ -145.8540, -5.12,
+ -145.8555, -5.12);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
+ -145.8540, -5.13,
+ -145.8540, -5.12,
+ -145.8555, -5.12);
+
+ int rel = polConvex.getRelationship(shape);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConcave.getRelationship(shape);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ //POLYGON((-145.8555 -5.13, -145.85 -5.13, -145.85 -5.12, -145.8555 -5.12, -145.8555 -5.13))
+ polConvex = buildConvexGeoPolygon(-145.8555, -5.13,
+ -145.85, -5.13,
+ -145.85, -5.12,
+ -145.8555, -5.12);
+
+ polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
+ -145.85, -5.13,
+ -145.85, -5.12,
+ -145.8555, -5.12);
+
+ rel = polConvex.getRelationship(shape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(shape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //POLYGON((-146 -5.18, -145.854 -5.18, -145.854 -5.11, -146 -5.11, -146 -5.18))
+ //Case overlaping on of the shapes
+ polConvex = buildConvexGeoPolygon(-146, -5.18,
+ -145.854, -5.18,
+ -145.854, -5.11,
+ -146, -5.11);
+
+ polConcave = buildConcaveGeoPolygon(-146, -5.18,
+ -145.854, -5.18,
+ -145.854, -5.11,
+ -146, -5.11);
+
+ rel = polConvex.getRelationship(shape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(shape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //POLYGON((-145.88 -5.13, -145.87 -5.13, -145.87 -5.12, -145.88 -5.12, -145.88 -5.13))
+ polConvex = buildConvexGeoPolygon(-145.88, -5.13,
+ -145.87, -5.13,
+ -145.87, -5.12,
+ -145.88, -5.12);
+
+ polConcave = buildConcaveGeoPolygon(-145.88, -5.13,
+ -145.87, -5.13,
+ -145.87, -5.12,
+ -145.88, -5.12);
+
+ rel = polConvex.getRelationship(shape);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(shape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ private GeoPolygon buildConvexGeoPolygon(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon3, double lat3,
+ double lon4, double lat4) {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
+ }
+
+ private GeoPolygon buildConcaveGeoPolygon(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon3, double lat3,
+ double lon4, double lat4) {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ return GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE, points);
+ }
+
+ private GeoPolygon buildComplexGeoPolygon(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon3, double lat3,
+ double lon4, double lat4) {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ GeoPolygonFactory.PolygonDescription pd = new GeoPolygonFactory.PolygonDescription(points);
+ return GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(pd));
+ }
+
+ private GeoPolygon buildConvexGeoPolygonWithHole(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon3, double lat3,
+ double lon4, double lat4,
+ GeoPolygon hole) {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ //return new GeoConvexPolygon(PlanetModel.SPHERE,points, Collections.singletonList(hole));
+ return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, Collections.singletonList(hole));
+ }
+
+ private GeoPolygon buildConcaveGeoPolygonWithHole(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon3, double lat3,
+ double lon4, double lat4,
+ GeoPolygon hole) {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ return GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE, points, Collections.singletonList(hole));
+ }
+
+ private GeoShape getCompositeShape(){
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17543698881), Math.toRadians(-145.790967486));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11348060995), Math.toRadians(-145.790854979));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11339421216), Math.toRadians(-145.853073512));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17535061936), Math.toRadians(-145.853192037));
+ final List<GeoPoint> points1 = new ArrayList<>();
+ points1.add(point1);
+ points1.add(point2);
+ points1.add(point3);
+ points1.add(point4);
+ GeoPolygon pol1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE,points1);
+ GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17527125408), Math.toRadians(-145.8563923));
+ GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11332154814), Math.toRadians(-145.856222168));
+ GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11317773171), Math.toRadians(-145.918433943));
+ GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17512738429), Math.toRadians(-145.918610092));
+ final List<GeoPoint> points2 = new ArrayList<>();
+ points2.add(point5);
+ points2.add(point6);
+ points2.add(point7);
+ points2.add(point8);
+ GeoPolygon pol2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
+ GeoCompositeMembershipShape composite = new GeoCompositeMembershipShape();
+ composite.addShape(pol1);
+ composite.addShape(pol2);
+ return composite;
+ }
+}
[2/3] lucene-solr:branch_6x: LUCENE-7606: Add spatial relationships
between all currently-defined Geo shapes
Posted by kw...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/CompositeGeoPolygonRelationshipsTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/CompositeGeoPolygonRelationshipsTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/CompositeGeoPolygonRelationshipsTest.java
new file mode 100644
index 0000000..f7d6606
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/CompositeGeoPolygonRelationshipsTest.java
@@ -0,0 +1,842 @@
+/*
+ * 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.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Check relationship between polygon and GeoShapes of composite polygons. Normally we construct
+ * the composite polygon (when possible) and the complex one.
+ */
+public class CompositeGeoPolygonRelationshipsTest {
+
+ @Test
+ public void testGeoCompositePolygon1() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ GeoPolygon polConvex = buildGeoPolygon(20.0, -60.4,
+ 20.1, -60.4,
+ 20.1, -60.3,
+ 20.0, -60.3,
+ 20.0, -60.3);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -60.4,
+ 20.1, -60.4,
+ 20.1, -60.3,
+ 20.0, -60.3);
+
+ //convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoCompositePolygon2() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ //POLYGON ((20.9 -60.8, 21.1 -60.8, 21.1 -60.6, 20.9 -60.6,20.9 -60.8))
+ GeoPolygon polConvex = buildGeoPolygon(20.9, -60.8,
+ 21.1, -60.8,
+ 21.1, -60.6,
+ 20.9, -60.6,
+ 20.9, -60.6);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -60.8,
+ 21.1, -60.8,
+ 21.1, -60.6,
+ 20.9, -60.6);
+
+ //convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoCompositePolygon3() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ //POLYGON ((20.9 -61.1, 21.1 -61.1, 21.1 -60.9, 20.9 -60.9,20.9 -61.1))
+ GeoPolygon polConvex = buildGeoPolygon(20.9, -61.1,
+ 21.1, -61.1,
+ 21.1, -60.9,
+ 20.9, -60.9,
+ 20.9, -60.9);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -61.1,
+ 21.1, -61.1,
+ 21.1, -60.9,
+ 20.9, -60.9);
+
+ //convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoCompositePolygon4() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ //POLYGON ((20.9 -61.4, 21.1 -61.4, 21.1 -61.2, 20.9 -61.2,20.9 -61.4))
+ GeoPolygon polConvex = buildGeoPolygon(20.9, -61.4,
+ 21.1, -61.4,
+ 21.1, -61.2,
+ 20.9, -61.2,
+ 20.9, -61.2);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -61.4,
+ 21.1, -61.4,
+ 21.1, -61.2,
+ 20.9, -61.2);
+
+ //convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ }
+
+ @Test
+ public void testGeoCompositePolygon5() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originaConvexlPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ //POLYGON ((19 -62, 23 -62, 23 -60, 19 -60,19 -62))
+ GeoPolygon polConvex = buildGeoPolygon(19, -62,
+ 23, -62,
+ 23, -60,
+ 19, -60,
+ 19, -60);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(19, -62,
+ 23, -62,
+ 23, -60,
+ 19, -60);
+
+ //convex
+ int rel = originaConvexlPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originaConvexlPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originaConvexlPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originaConvexlPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoCompositePolygon6() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ //POLYGON ((19 -62, 24 -62, 24 -60, 19 -60,19 -62))
+ GeoPolygon polConvex = buildGeoPolygon(19, -62,
+ 24, -62,
+ 24, -60,
+ 19, -60,
+ 19, -60);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(19, -62,
+ 24, -62,
+ 24, -60,
+ 19, -60);
+
+ //convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = originalConcavePol.getRelationship(polConcave);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConcave.getRelationship(originalConcavePol);
+ assertEquals(GeoArea.CONTAINS, rel);
+ }
+
+
+
+ @Test
+ public void testGeoCompositePolygon7() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
+ GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+ //POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
+ GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
+ 21, -61,
+ 22.820804, -60.257713,
+ 23.207901, -61.453298,
+ 20.119948, -61.655652);
+
+ //POLYGON ((20.2 -61.4, 20.5 -61.4, 20.5 -60.8, 20.2 -60.8,20.2 -61.4))
+ GeoPolygon polConvex = buildGeoPolygon(20.2, -61.4,
+ 20.5, -61.4,
+ 20.5, -60.8,
+ 20.2, -60.8,
+ 20.2, -60.8);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.2, -61.4,
+ 20.5, -61.4,
+ 20.5, -60.8,
+ 20.2, -60.8);
+
+ //convex
+ int rel = originalConvexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ //concave
+ rel = originalConcavePol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = originalConvexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(originalConvexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoCompositePolygon8() {
+
+ //POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713,21 -61, 19.845091 -60.452631))
+ GeoPolygon originalPol = buildGeoPolygon(19.84509, -60.452631,
+ 20.119948, -61.655652,
+ 23.207901, -61.453298,
+ 22.820804, -60.257713,
+ 21, -61);
+
+
+ GeoShape shape = getInsideCompositeShape();
+
+ int rel = originalPol.getRelationship(shape);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ }
+
+
+ @Test
+ public void testGeoPolygonPole1() {
+ //POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
+ GeoPolygon compositePol= getCompositePolygon();
+ GeoPolygon complexPol= getComplexPolygon();
+
+ //POLYGON ((20.9 -61.4, 21.1 -61.4, 21.1 -61.2, 20.9 -61.2,20.9 -61.4))
+ GeoPolygon polConvex = buildGeoPolygon(20.9, -61.4,
+ 21.1, -61.4,
+ 21.1, -61.2,
+ 20.9, -61.2,
+ 20.9, -61.2);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -61.4,
+ 21.1, -61.4,
+ 21.1, -61.2,
+ 20.9, -61.2);
+
+ int rel = compositePol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(compositePol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = compositePol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(compositePol);
+ assertEquals(GeoArea.WITHIN, rel);
+
+ rel = complexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(complexPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+
+ rel = complexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(complexPol);
+ assertEquals(GeoArea.WITHIN, rel);
+ }
+
+ @Test
+ public void testGeoPolygonPole2() {
+ //POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
+ GeoPolygon compositePol= getCompositePolygon();
+ GeoPolygon complexPol= getComplexPolygon();
+
+ //POLYGON((-1 81, -1 79,1 79,1 81, -1 81))
+ GeoPolygon polConvex = buildGeoPolygon(-1,81,
+ -1,79,
+ 1,79,
+ 1,81,
+ 1,81);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-1,81,
+ -1,79,
+ 1,79,
+ 1,81);
+
+ int rel = compositePol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(compositePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = compositePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(compositePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = complexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(complexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = complexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(complexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testGeoPolygonPole3() {
+ //POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
+ GeoPolygon compositePol= getCompositePolygon();
+ GeoPolygon complexPol= getComplexPolygon();
+
+ //POLYGON((-1 86, -1 84,1 84,1 86, -1 86))
+ GeoPolygon polConvex = buildGeoPolygon(-1,86,
+ -1,84,
+ 1,84,
+ 1,86,
+ 1,86);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-1,86,
+ -1,84,
+ 1,84,
+ 1,86);
+
+ int rel = compositePol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(compositePol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = compositePol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(compositePol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+
+ rel = complexPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(complexPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+
+ rel = complexPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(complexPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+
+ @Test
+ public void testMultiPolygon1() {
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPolygon multiPol= getMultiPolygon();
+
+ //POLYGON((-145.8555 -5.13, -145.8540 -5.13, -145.8540 -5.12, -145.8555 -5.12, -145.8555 -5.13))
+ GeoPolygon polConvex = buildGeoPolygon(-145.8555, -5.13,
+ -145.8540, -5.13,
+ -145.8540, -5.12,
+ -145.8555, -5.12,
+ -145.8555, -5.12);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
+ -145.8540, -5.13,
+ -145.8540, -5.12,
+ -145.8555, -5.12);
+
+ int rel = multiPol.getRelationship(polConvex);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConvex.getRelationship(multiPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+ assertEquals(false,multiPol.intersects(polConvex));
+ assertEquals(false,polConvex.intersects(multiPol));
+
+ rel = multiPol.getRelationship(polConcave);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConcave.getRelationship(multiPol);
+ assertEquals(GeoArea.WITHIN, rel);
+ assertEquals(false,multiPol.intersects(polConcave));
+ assertEquals(false,polConcave.intersects(multiPol));
+ }
+
+ @Test
+ public void testMultiPolygon2() {
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPolygon multiPol= getMultiPolygon();
+
+ //POLYGON((-145.8555 -5.13, -145.85 -5.13, -145.85 -5.12, -145.8555 -5.12, -145.8555 -5.13))
+ GeoPolygon polConvex = buildGeoPolygon(-145.8555, -5.13,
+ -145.85, -5.13,
+ -145.85, -5.12,
+ -145.8555, -5.12,
+ -145.8555, -5.12);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
+ -145.85, -5.13,
+ -145.85, -5.12,
+ -145.8555, -5.12);
+
+ int rel = multiPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(multiPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ assertEquals(true,multiPol.intersects(polConvex));
+ assertEquals(true,polConvex.intersects(multiPol));
+
+ rel = multiPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(multiPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ assertEquals(true,multiPol.intersects(polConcave));
+ assertEquals(true,polConcave.intersects(multiPol));
+ }
+
+ @Test
+ public void testMultiPolygon3() {
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPolygon multiPol= getMultiPolygon();
+
+ //POLYGON((-146 -5.18, -145.854 -5.18, -145.854 -5.11, -146 -5.11, -146 -5.18))
+ //Case overlapping one of the polygons so intersection is false!
+ GeoPolygon polConvex = buildGeoPolygon(-146, -5.18,
+ -145.854, -5.18,
+ -145.854, -5.11,
+ -146, -5.11,
+ -146, -5.11);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-146, -5.18,
+ -145.854, -5.18,
+ -145.854, -5.11,
+ -146, -5.11);
+
+ int rel = multiPol.getRelationship(polConvex);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConvex.getRelationship(multiPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ assertEquals(false,multiPol.intersects(polConvex));
+ assertEquals(false,polConvex.intersects(multiPol));
+
+ rel = multiPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(multiPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ assertEquals(false,multiPol.intersects(polConcave));
+ assertEquals(false,polConcave.intersects(multiPol));
+
+ }
+
+ @Test
+ public void testMultiPolygon4() {
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPolygon multiPol= getMultiPolygon();
+
+ //POLYGON((-145.88 -5.13, -145.87 -5.13, -145.87 -5.12, -145.88 -5.12, -145.88 -5.13))
+ GeoPolygon polConvex = buildGeoPolygon(-145.88, -5.13,
+ -145.87, -5.13,
+ -145.87, -5.12,
+ -145.88, -5.12,
+ -145.88, -5.12);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-145.88, -5.13,
+ -145.87, -5.13,
+ -145.87, -5.12,
+ -145.88, -5.12);
+
+ int rel = multiPol.getRelationship(polConvex);
+ assertEquals(GeoArea.WITHIN, rel);
+ rel = polConvex.getRelationship(multiPol);
+ assertEquals(GeoArea.CONTAINS, rel);
+ assertEquals(false,multiPol.intersects(polConvex));
+ assertEquals(false,polConvex.intersects(multiPol));
+
+ rel = multiPol.getRelationship(polConcave);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ rel = polConcave.getRelationship(multiPol);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ assertEquals(false,multiPol.intersects(polConcave));
+ assertEquals(false,polConcave.intersects(multiPol));
+ }
+
+ @Test
+ public void testMultiPolygon5() {
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPolygon multiPol= getMultiPolygon();
+
+ //POLYGON((-146 -5.18, -145 -5.18, -145 -5.11, -146 -5.11, -146 -5.18))
+ GeoPolygon polConvex = buildGeoPolygon(-146, -5.18,
+ -145, -5.18,
+ -145, -5.11,
+ -146, -5.11,
+ -146, -5.11);
+
+ GeoPolygon polConcave = buildConcaveGeoPolygon(-146, -5.18,
+ -145, -5.18,
+ -145, -5.11,
+ -146, -5.11);
+
+ int rel = multiPol.getRelationship(polConvex);
+ assertEquals(GeoArea.CONTAINS, rel);
+ rel = polConvex.getRelationship(multiPol);
+ assertEquals(GeoArea.WITHIN, rel);
+ assertEquals(false,multiPol.intersects(polConvex));
+
+ rel = multiPol.getRelationship(polConcave);
+ assertEquals(GeoArea.DISJOINT, rel);
+ rel = polConcave.getRelationship(multiPol);
+ assertEquals(GeoArea.DISJOINT, rel);
+ assertEquals(false,multiPol.intersects(polConcave));
+ }
+
+ private GeoPolygon buildGeoPolygon(double lon1,double lat1,
+ double lon2,double lat2,
+ double lon3,double lat3,
+ double lon4,double lat4,
+ double lon5,double lat5)
+ {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat5), Math.toRadians(lon5));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ points.add(point5);
+ return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
+ }
+
+ private GeoPolygon buildConcaveGeoPolygon(double lon1,double lat1,
+ double lon2,double lat2,
+ double lon3,double lat3,
+ double lon4,double lat4)
+ {
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ return GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE,points);
+ }
+
+ private GeoPolygon getCompositePolygon(){
+ //POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(0));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(45));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(90));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(135));
+ GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(180));
+ GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-135));
+ GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(-90));
+ GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-45));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ points.add(point5);
+ points.add(point6);
+ points.add(point7);
+ points.add(point8);
+ return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
+ }
+
+ private GeoPolygon getComplexPolygon(){
+ //POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(0));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(45));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(90));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(135));
+ GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(180));
+ GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-135));
+ GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(-90));
+ GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-45));
+ final List<GeoPoint> points = new ArrayList<>();
+ points.add(point1);
+ points.add(point2);
+ points.add(point3);
+ points.add(point4);
+ points.add(point5);
+ points.add(point6);
+ points.add(point7);
+ points.add(point8);
+ GeoPolygonFactory.PolygonDescription pd = new GeoPolygonFactory.PolygonDescription(points);
+ return GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(pd));
+ }
+
+ private GeoPolygon getMultiPolygon(){
+ //MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
+ //((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17543698881), Math.toRadians(-145.790967486));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11348060995), Math.toRadians(-145.790854979));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11339421216), Math.toRadians(-145.853073512));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17535061936), Math.toRadians(-145.853192037));
+ final List<GeoPoint> points1 = new ArrayList<>();
+ points1.add(point1);
+ points1.add(point2);
+ points1.add(point3);
+ points1.add(point4);
+ GeoPolygonFactory.PolygonDescription pd1 = new GeoPolygonFactory.PolygonDescription(points1);
+ GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17527125408), Math.toRadians(-145.8563923));
+ GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11332154814), Math.toRadians(-145.856222168));
+ GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11317773171), Math.toRadians(-145.918433943));
+ GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17512738429), Math.toRadians(-145.918610092));
+ final List<GeoPoint> points2 = new ArrayList<>();
+ points2.add(point5);
+ points2.add(point6);
+ points2.add(point7);
+ points2.add(point8);
+ GeoPolygonFactory.PolygonDescription pd2 = new GeoPolygonFactory.PolygonDescription(points2);
+ final List<GeoPolygonFactory.PolygonDescription> pds = new ArrayList<>();
+ pds.add(pd1);
+ pds.add(pd2);
+ return GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, pds);
+ }
+
+ public GeoShape getInsideCompositeShape(){
+ //MULTIPOLYGON(((19.945091 -60.552631, 20.319948 -61.555652, 20.9 -61.5, 20.9 -61, 19.945091 -60.552631)),
+ // ((21.1 -61.5, 23.107901 -61.253298, 22.720804 -60.457713,21.1 -61, 21.1 -61.5)))
+ GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-60.552631), Math.toRadians(19.945091));
+ GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.555652), Math.toRadians(20.319948));
+ GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.5), Math.toRadians(20.9));
+ GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(20.9));
+ final List<GeoPoint> points1 = new ArrayList<>();
+ points1.add(point1);
+ points1.add(point2);
+ points1.add(point3);
+ points1.add(point4);
+ GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.5), Math.toRadians(21.1));
+ GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.253298), Math.toRadians(23.107901));
+ GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-60.457713), Math.toRadians(22.720804));
+ GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(21.1));
+ final List<GeoPoint> points2 = new ArrayList<>();
+ points2.add(point5);
+ points2.add(point6);
+ points2.add(point7);
+ points2.add(point8);
+ GeoPolygon p1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points1);
+ GeoPolygon p2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
+ GeoCompositeMembershipShape compositeMembershipShape = new GeoCompositeMembershipShape();
+ compositeMembershipShape.addShape(p1);
+ compositeMembershipShape.addShape(p2);
+ return compositeMembershipShape;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeGenerator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeGenerator.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeGenerator.java
new file mode 100644
index 0000000..f8b6629
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeGenerator.java
@@ -0,0 +1,944 @@
+/*
+* 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.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.lucene.util.LuceneTestCase;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
+
+/**
+ * Class for generating random Geo3dShapes. They can be generated under
+ * given constraints which are expressed as a shape and a relationship.
+ *
+ * note that convexity for polygons is defined as polygons that contains
+ * antipodal points, otherwise they are convex. Internally they can be
+ * created using GeoConvexPolygons and GeoConcavePolygons.
+ *
+ */
+public class RandomGeoShapeGenerator extends LuceneTestCase {
+
+ /* Max num of iterations to find right shape under given constrains */
+ final private static int MAX_SHAPE_ITERATIONS = 50;
+ /* Max num of iterations to find right point under given constrains */
+ final private static int MAX_POINT_ITERATIONS = 1000;
+
+ /* Supported shapes */
+ final protected static int CONVEX_POLYGON = 0;
+ final protected static int CONVEX_POLYGON_WITH_HOLES = 1;
+ final protected static int CONCAVE_POLYGON = 2;
+ final protected static int CONCAVE_POLYGON_WITH_HOLES = 3;
+ final protected static int COMPLEX_POLYGON = 4;
+ final protected static int CIRCLE = 5;
+ final protected static int RECTANGLE = 6;
+ final protected static int PATH = 7;
+ final protected static int COLLECTION = 8;
+
+ /* Helper shapes for generating constraints whch are just three sided polygons */
+ final protected static int CONVEX_SIMPLE_POLYGON = 500;
+ final protected static int CONCAVE_SIMPLE_POLYGON = 501;
+
+
+ /**
+ * Method that returns empty Constraints object..
+ *
+ * @return an empty Constraints object
+ */
+ public Constraints getEmptyConstraint(){
+ return new Constraints();
+ }
+
+ /**
+ * Method that returns a random generated a random Shape code from all
+ * supported shapes.
+ *
+ * @return a random generated shape code
+ */
+ public int randomShapeType(){
+ return random().nextInt(9);
+ }
+
+ /**
+ * Method that returns a random generated a random Shape code from all
+ * convex supported shapes.
+ *
+ * @return a random generated convex shape code
+ */
+ public int randomConvexShapeType(){
+ int shapeType = randomShapeType();
+ while (isConcave(shapeType)){
+ shapeType = randomShapeType();
+ }
+ return shapeType;
+ }
+
+ /**
+ * Method that returns a random generated a random Shape code from all
+ * concave supported shapes.
+ *
+ * @return a random generated concave shape code
+ */
+ public int randomConcaveShapeType(){
+ int shapeType = randomShapeType();
+ while (!isConcave(shapeType)){
+ shapeType = randomShapeType();
+ }
+ return shapeType;
+ }
+
+ /**
+ * Method that returns a random generated GeoAreaShape code from all
+ * supported GeoAreaShapes.
+ *
+ * We are removing Collections because it is difficult to create shapes
+ * with properties in some cases.
+ *
+ * @return a random generated polygon code
+ */
+ public int randomGeoAreaShapeType(){
+ return random().nextInt(8);
+ }
+
+ /**
+ * Check if a shape code represents a concave shape
+ *
+ * @return true if the shape represented by the code is concave
+ */
+ public boolean isConcave(int shapeType){
+ return (shapeType == CONCAVE_POLYGON);
+ }
+
+ /**
+ * Method that returns a random generated Planet model from the supported
+ * Planet models. currently SPHERE and WGS84
+ *
+ * @return a random generated Planet model
+ */
+ public PlanetModel randomPlanetModel() {
+ final int shapeType = random().nextInt(2);
+ switch (shapeType) {
+ case 0: {
+ return PlanetModel.SPHERE;
+ }
+ case 1: {
+ return PlanetModel.WGS84;
+ }
+ default:
+ throw new IllegalStateException("Unexpected planet model");
+ }
+ }
+
+ /**
+ * Method that returns a random generated GeoPoint under given constraints. Returns
+ * NULL if it cannot find a point under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPoint.
+ */
+ public GeoPoint randomGeoPoint(PlanetModel planetModel, Constraints constraints) {
+ int iterations = 0;
+ while (iterations < MAX_POINT_ITERATIONS) {
+ double lat = randomDouble();
+ if (Math.PI/2 - Math.abs(lat) <0){
+ continue;
+ }
+ double lon = randomDouble();
+ if (Math.PI - Math.abs(lat) <0){
+ continue;
+ }
+ iterations++;
+ GeoPoint point = new GeoPoint(planetModel, lat, lon);
+ if (constraints.isWithin(point)) {
+ return point;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated GeoAreaShape.
+ *
+ * @param shapeType The GeoAreaShape code.
+ * @param planetModel The planet model.
+ * @return The random generated GeoAreaShape.
+ */
+ public GeoAreaShape randomGeoAreaShape(int shapeType, PlanetModel planetModel){
+ GeoAreaShape geoAreaShape = null;
+ while (geoAreaShape == null){
+ geoAreaShape = randomGeoAreaShape(shapeType,planetModel,new Constraints());
+ }
+ return geoAreaShape;
+ }
+
+ /**
+ * Method that returns a random generated GeoAreaShape under given constraints. Returns
+ * NULL if it cannot build the GeoAreaShape under the given constraints.
+ *
+ * @param shapeType The GeoAreaShape code.
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoAreaShape.
+ */
+ public GeoAreaShape randomGeoAreaShape(int shapeType, PlanetModel planetModel, Constraints constraints){
+ return (GeoAreaShape)randomGeoShape(shapeType, planetModel, constraints);
+ }
+
+ /**
+ * Method that returns a random generated GeoShape.
+ *
+ * @param shapeType The shape code.
+ * @param planetModel The planet model.
+ * @return The random generated GeoShape.
+ */
+ public GeoShape randomGeoShape(int shapeType, PlanetModel planetModel){
+ GeoShape geoShape = null;
+ while (geoShape == null){
+ geoShape = randomGeoShape(shapeType,planetModel,new Constraints());
+ }
+ return geoShape;
+ }
+
+ /**
+ * Method that returns a random generated GeoShape under given constraints. Returns
+ * NULL if it cannot build the GeoShape under the given constraints.
+ *
+ * @param shapeType The polygon code.
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoShape.
+ */
+ public GeoShape randomGeoShape(int shapeType, PlanetModel planetModel, Constraints constraints){
+ switch (shapeType) {
+ case CONVEX_POLYGON: {
+ return convexPolygon(planetModel, constraints);
+ }
+ case CONVEX_POLYGON_WITH_HOLES: {
+ return convexPolygonWithHoles(planetModel, constraints);
+ }
+ case CONCAVE_POLYGON: {
+ return concavePolygon(planetModel, constraints);
+ }
+ case CONCAVE_POLYGON_WITH_HOLES: {
+ return concavePolygonWithHoles(planetModel, constraints);
+ }
+ case COMPLEX_POLYGON: {
+ return complexPolygon(planetModel, constraints);
+ }
+ case CIRCLE: {
+ return circle(planetModel, constraints);
+ }
+ case RECTANGLE: {
+ return rectangle(planetModel, constraints);
+ }
+ case PATH: {
+ return path(planetModel, constraints);
+ }
+ case COLLECTION: {
+ return collection(planetModel, constraints);
+ }
+ case CONVEX_SIMPLE_POLYGON: {
+ return simpleConvexPolygon(planetModel, constraints);
+ }
+ case CONCAVE_SIMPLE_POLYGON: {
+ return concaveSimplePolygon(planetModel, constraints);
+ }
+ default:
+ throw new IllegalStateException("Unexpected shape type");
+ }
+ }
+
+ /**
+ * Method that returns a random generated a GeoCircle under given constraints. Returns
+ * NULL if it cannot build the GeoCircle under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoCircle.
+ */
+ private GeoCircle circle(PlanetModel planetModel , Constraints constraints) {
+ int iterations=0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ final GeoPoint center = randomGeoPoint(planetModel, constraints);
+ if (center == null){
+ continue;
+ }
+ final double radius = randomCutoffAngle();
+ try {
+
+ GeoCircle circle = GeoCircleFactory.makeGeoCircle(planetModel, center.getLatitude(), center.getLongitude(), radius);
+ if (!constraints.valid(circle)) {
+ continue;
+ }
+ return circle;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a GeoBBox under given constraints. Returns
+ * NULL if it cannot build the GeoBBox under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoBBox.
+ */
+ private GeoBBox rectangle(PlanetModel planetModel, Constraints constraints) {
+
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ final GeoPoint point1 = randomGeoPoint(planetModel, constraints);
+ if (point1 == null){
+ continue;
+ }
+ final GeoPoint point2 = randomGeoPoint(planetModel, constraints);
+ if (point2 == null){
+ continue;
+ }
+
+ double minLat = Math.min(point1.getLatitude(), point2.getLatitude());
+ double maxLat = Math.max(point1.getLatitude(), point2.getLatitude());
+ double minLon = Math.min(point1.getLongitude(), point2.getLongitude());
+ double maxLon = Math.max(point1.getLongitude(), point2.getLongitude());
+
+ try {
+ GeoBBox bbox = GeoBBoxFactory.makeGeoBBox(planetModel, maxLat, minLat, minLon, maxLon);
+ if (!constraints.valid(bbox)) {
+ continue;
+ }
+ return bbox;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a GeoPath under given constraints. Returns
+ * NULL if it cannot build the GeoPath under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPath.
+ */
+ private GeoPath path(PlanetModel planetModel, Constraints constraints) {
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ int vertexCount = random().nextInt(2) + 2;
+ List<GeoPoint> geoPoints = points(vertexCount, planetModel, constraints);
+ double width =randomCutoffAngle();
+ try {
+ GeoPath path = GeoPathFactory.makeGeoPath(planetModel, width, geoPoints.toArray(new GeoPoint[geoPoints.size()]));
+ if (!constraints.valid(path)) {
+ continue;
+ }
+ return path;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a GeoCompositeMembershipShape under given constraints. Returns
+ * NULL if it cannot build the GGeoCompositeMembershipShape under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoCompositeMembershipShape.
+ */
+ private GeoCompositeAreaShape collection(PlanetModel planetModel, Constraints constraints) {
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ int numberShapes = random().nextInt(3) + 2;
+ GeoCompositeAreaShape collection = new GeoCompositeAreaShape();
+ for(int i=0; i<numberShapes;i++){
+ GeoPolygon member = convexPolygon(planetModel, constraints);
+ if (member != null){
+ collection.addShape(member);
+ }
+ }
+ if (collection.shapes.size() ==0){
+ continue;
+ }
+ return collection;
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a convex GeoPolygon under given constraints. Returns
+ * NULL if it cannot build the GePolygon under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon convexPolygon(PlanetModel planetModel, Constraints constraints) {
+ int vertexCount = random().nextInt(4) + 3;
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
+ List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints);
+ if (!constraints.valid(polygon) || isConcave(planetModel, polygon)) {
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a convex GeoPolygon with holes under given constraints. Returns
+ * NULL if it cannot build the GeoPolygon with holes under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon convexPolygonWithHoles(PlanetModel planetModel, Constraints constraints) {
+ int vertexCount = random().nextInt(4) + 3;
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
+ List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints);
+ //polygon should comply with all constraints except disjoint as we have holes
+ Constraints polygonConstraints = new Constraints();
+ polygonConstraints.putAll(constraints.getContains());
+ polygonConstraints.putAll(constraints.getWithin());
+ polygonConstraints.putAll(constraints.getDisjoint());
+ if (!polygonConstraints.valid(polygon) || isConcave(planetModel, polygon)){
+ continue;
+ }
+ //hole must overlap with polygon and comply with any CONTAINS constraint.
+ Constraints holeConstraints = new Constraints();
+ holeConstraints.putAll(constraints.getContains());
+ holeConstraints.put(polygon,GeoArea.OVERLAPS);
+ //Points must be with in the polygon and must comply
+ // CONTAINS and DISJOINT constraints
+ Constraints pointsConstraints = new Constraints();
+ pointsConstraints.put(polygon,GeoArea.WITHIN);
+ pointsConstraints.putAll(constraints.getContains());
+ pointsConstraints.putAll(constraints.getDisjoint());
+ List<GeoPolygon> holes = concavePolygonHoles(planetModel, holeConstraints, pointsConstraints);
+ //we should have at least one hole
+ if (holes.size() == 0){
+ continue;
+ }
+ polygon = GeoPolygonFactory.makeGeoPolygon(planetModel,orderedGeoPoints,holes);
+ if (!constraints.valid(polygon) || isConcave(planetModel, polygon)){
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random list if concave GeoPolygons under given constraints. Method
+ * use to generate convex holes. Note that constraints for points and holes are different,
+ *
+ * @param planetModel The planet model.
+ * @param holeConstraints The given constraints that a hole must comply.
+ * @param pointConstraints The given constraints that a point must comply.
+ * @return The random generated GeoPolygon.
+ */
+ private List<GeoPolygon> concavePolygonHoles(PlanetModel planetModel,
+ Constraints holeConstraints,
+ Constraints pointConstraints) {
+ int iterations =0;
+ int holesCount = random().nextInt(3) + 1;
+ List<GeoPolygon> holes = new ArrayList<>();
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ int vertexCount = random().nextInt(3) + 3;
+ List<GeoPoint> geoPoints = points(vertexCount, planetModel, pointConstraints);
+ geoPoints = orderPoints(geoPoints);
+ Collections.reverse(geoPoints);
+ try {
+ GeoPolygon hole = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints);
+ if (!holeConstraints.valid(hole) || isConvex(planetModel, hole)) {
+ continue;
+ }
+ holes.add(hole);
+ if (holes.size() == holesCount){
+ return holes;
+ }
+ pointConstraints.put(hole, GeoArea.DISJOINT);
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return holes;
+ }
+
+ /**
+ * Method that returns a random generated a concave GeoPolygon under given constraints. Returns
+ * NULL if it cannot build the concave GeoPolygon under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon concavePolygon(PlanetModel planetModel, Constraints constraints) {
+
+ int vertexCount = random().nextInt(4) + 3;
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
+ List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
+ Collections.reverse(orderedGeoPoints);
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints);
+ if (!constraints.valid(polygon) || isConvex(planetModel, polygon)) {
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a concave GeoPolygon with holes under given constraints. Returns
+ * NULL if it cannot build the GeoPolygon under the given constraints. Note that the final GeoPolygon is
+ * convex as the hole wraps the convex GeoPolygon.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon concavePolygonWithHoles(PlanetModel planetModel, Constraints constraints) {
+ int vertexCount = random().nextInt(4) + 3;
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ //we first build the hole. We consider all constraints except
+ // disjoint as we have a hole
+ Constraints holeConstraints = new Constraints();
+ holeConstraints.putAll(constraints.getContains());
+ holeConstraints.putAll(constraints.getWithin());
+ holeConstraints.putAll(constraints.getOverlaps());
+ GeoPolygon hole = convexPolygon(planetModel, holeConstraints);
+ if (hole == null){
+ continue;
+ }
+ // Now we get points for polygon. Must we with in the hole
+ // and we add contain constraints
+ Constraints pointConstraints = new Constraints();
+ pointConstraints.put(hole, GeoArea.WITHIN);
+ pointConstraints.putAll(constraints.getContains());
+ List<GeoPoint> geoPoints = points(vertexCount,planetModel, pointConstraints);
+ List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
+ Collections.reverse(orderedGeoPoints);
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints, Collections.singletonList(hole));
+ //final polygon must be convex
+ if (!constraints.valid(polygon) || isConcave(planetModel,polygon)) {
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated complex GeoPolygon under given constraints. Returns
+ * NULL if it cannot build the complex GeoPolygon under the given constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon complexPolygon(PlanetModel planetModel, Constraints constraints) {
+ int polygonsCount =random().nextInt(2) + 1;
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ List<GeoPolygonFactory.PolygonDescription> polDescription = new ArrayList<>();
+ while(polDescription.size() < polygonsCount){
+ int vertexCount = random().nextInt(14) + 3;
+ List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
+ orderPoints(geoPoints);
+ polDescription.add(new GeoPolygonFactory.PolygonDescription(geoPoints));
+ }
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeLargeGeoPolygon(planetModel,polDescription);
+ if (!constraints.valid(polygon)) {
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a concave square GeoPolygon under given constraints. Returns
+ * NULL if it cannot build the concave GeoPolygon under the given constraints. This shape is an utility
+ * to build constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon simpleConvexPolygon(PlanetModel planetModel, Constraints constraints) {
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ List<GeoPoint> points = points(3,planetModel,constraints);
+ points = orderPoints(points);
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeGeoConvexPolygon(planetModel, points);
+ if(!constraints.valid(polygon) || isConcave(planetModel,polygon)){
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random generated a convex square GeoPolygon under given constraints. Returns
+ * NULL if it cannot build the convex GeoPolygon under the given constraints. This shape is an utility
+ * to build constraints.
+ *
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated GeoPolygon.
+ */
+ private GeoPolygon concaveSimplePolygon(PlanetModel planetModel, Constraints constraints) {
+ int iterations = 0;
+ while (iterations < MAX_SHAPE_ITERATIONS) {
+ iterations++;
+ List<GeoPoint> points = points(3, planetModel, constraints);
+ points = orderPoints(points);
+ Collections.reverse(points);
+ try {
+ GeoPolygon polygon = GeoPolygonFactory.makeGeoConcavePolygon(planetModel, points);
+ if(!constraints.valid(polygon) || isConvex(planetModel, polygon)){
+ continue;
+ }
+ return polygon;
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that returns a random list of generated GeoPoints under given constraints. If it cannot
+ * find a point it will add a point that might not comply with the constraints.
+ *
+ * @param count The number of points
+ * @param planetModel The planet model.
+ * @param constraints The given constraints.
+ * @return The random generated List of GeoPoints.
+ */
+ private List<GeoPoint> points(int count, PlanetModel planetModel, Constraints constraints){
+ List<GeoPoint> geoPoints = new ArrayList<>(count);
+ for(int i= 0; i< count; i++) {
+ GeoPoint point = randomGeoPoint(planetModel, constraints);
+ if (point == null){
+ point = randomGeoPoint(planetModel, new Constraints());
+ }
+ geoPoints.add(point);
+ }
+ return geoPoints;
+ }
+
+ /**
+ * Check if a GeoPolygon is pure concave. Note that our definition for concavity is that the polygon
+ * contains antipodal points.
+ *
+ * @param planetModel The planet model.
+ * @param shape The polygon to check.
+ * @return True if the polygon contains antipodal points.
+ */
+ private boolean isConcave(PlanetModel planetModel, GeoPolygon shape){
+ return (shape.isWithin(planetModel.NORTH_POLE) && shape.isWithin(planetModel.SOUTH_POLE))||
+ (shape.isWithin(planetModel.MAX_X_POLE) && shape.isWithin(planetModel.MIN_X_POLE)) ||
+ (shape.isWithin(planetModel.MAX_Y_POLE) && shape.isWithin(planetModel.MIN_Y_POLE));
+ }
+
+ /**
+ * Check if a GeoPolygon is pure convex. Note that our definition for convexity is that the polygon
+ * does not contain antipodal points.
+ *
+ * @param planetModel The planet model.
+ * @param shape The polygon to check.
+ * @return True if the polygon dies not contains antipodal points.
+ */
+ private boolean isConvex(PlanetModel planetModel, GeoPolygon shape){
+ return !isConcave(planetModel,shape);
+ }
+
+ /**
+ * Generates a random number between 0 and PI.
+ *
+ * @return the cutoff angle.
+ */
+ private double randomCutoffAngle() {
+ while(true) {
+ double radius = randomDouble();
+ if (radius <0 || radius > Math.PI){
+ continue;
+ }
+ return radius;
+ }
+ }
+
+ /**
+ * Method that orders a lit of points anti-clock-wise to prevent crossing edges.
+ *
+ * @param originalPoints The points to order.
+ * @return The list of ordered points anti-clockwise.
+ */
+ private List<GeoPoint> orderPoints(List<GeoPoint> originalPoints){
+ List<GeoPoint> points = new ArrayList<>(originalPoints.size());
+ points.addAll(originalPoints); //make a copy
+ GeoPoint lPoint = getPointLefLon(points);
+ points.remove(lPoint);
+ GeoPoint rPoint = getPointRigthLon(points);
+ points.remove(rPoint);
+ List<GeoPoint> APoints = getPointsBelowAndSort(points, lPoint);
+ List<GeoPoint> BPoints = getPointsAboveAndsort(points, lPoint);
+ List<GeoPoint> result = new ArrayList<>();
+ result.add(lPoint);
+ result.addAll(APoints);
+ result.add(rPoint);
+ result.addAll(BPoints);
+ return result;
+ }
+
+ private List<GeoPoint> getPointsAboveAndsort(List<GeoPoint> points,GeoPoint lPoint) {
+ List<GeoPoint> BPoints = new ArrayList<>();
+ for (GeoPoint point : points){
+ if(point.getLatitude() > lPoint.getLatitude()){
+ BPoints.add(point);
+ }
+ }
+ Collections.sort(BPoints, new Comparator<GeoPoint>() {
+ public int compare(GeoPoint idx1, GeoPoint idx2) {
+ return Double.compare(idx1.getLongitude(), idx2.getLongitude());
+ }
+ });
+ return BPoints;
+ }
+
+ private List<GeoPoint> getPointsBelowAndSort(List<GeoPoint> points,GeoPoint lPoint) {
+ List<GeoPoint> APoints = new ArrayList<>();
+ for (GeoPoint point : points){
+ if(point.getLatitude() < lPoint.getLatitude()){
+ APoints.add(point);
+ }
+ }
+ Collections.sort(APoints, new Comparator<GeoPoint>() {
+ public int compare(GeoPoint idx1, GeoPoint idx2) {
+ return Double.compare(idx1.getLongitude(), idx2.getLongitude());
+ }
+ });
+ return APoints;
+ }
+
+ private GeoPoint getPointLefLon(List<GeoPoint> points) {
+ GeoPoint lPoint = null;
+ for (GeoPoint point : points){
+ if(lPoint == null ){
+ lPoint = point;
+ }
+ else{
+ if (lPoint.getLongitude() > point.getLongitude()){
+ lPoint = point;
+ }
+ }
+ }
+ return lPoint;
+ }
+
+ private GeoPoint getPointRigthLon(List<GeoPoint> points) {
+ GeoPoint rPoint = null;
+ for (GeoPoint point : points){
+ if(rPoint == null ){
+ rPoint = point;
+ }
+ else{
+ if (rPoint.getLongitude() < point.getLongitude()){
+ rPoint = point;
+ }
+ }
+ }
+ return rPoint;
+ }
+
+ /**
+ * Class that holds the constraints that are given to
+ * build shapes. It consists in a list of GeoAreaShapes
+ * and relationships the new shape needs to satisfy.
+ */
+ class Constraints extends HashMap<GeoAreaShape, Integer>{
+
+ /**
+ * Check if the shape is valid under the constraints.
+ *
+ * @param shape The shape to check
+ * @return true if the shape satisfy the constraints, else false.
+ */
+ public boolean valid(GeoShape shape) {
+ if (shape == null){
+ return false;
+ }
+ for (GeoAreaShape constraint : keySet()) {
+ if (constraint.getRelationship(shape) != get(constraint)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check if a point is Within the constraints.
+ *
+ * @param point The point to check
+ * @return true if the point satisfy the constraints, else false.
+ */
+ public boolean isWithin(GeoPoint point) {
+ for (GeoShape constraint : keySet()) {
+ if (!(validPoint(point, constraint, get(constraint)))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check if a point is Within one constraint given by a shape and a relationship.
+ *
+ * @param point The point to check
+ * @param shape The shape of the constraint
+ * @param relationship The relationship of the constraint.
+ * @return true if the point satisfy the constraint, else false.
+ */
+ private boolean validPoint(GeoPoint point, GeoShape shape, int relationship) {
+ //For GeoCompositeMembershipShape we only consider the first shape to help
+ // converging
+ if (relationship == GeoArea.WITHIN && shape instanceof GeoCompositeMembershipShape) {
+ shape = (((GeoCompositeMembershipShape) shape).shapes.get(0));
+ }
+ switch (relationship) {
+ case GeoArea.DISJOINT:
+ return !shape.isWithin(point);
+ case GeoArea.OVERLAPS:
+ return true;
+ case GeoArea.CONTAINS:
+ return !shape.isWithin(point);
+ case GeoArea.WITHIN:
+ return shape.isWithin(point);
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Collect the CONTAINS constraints in the object
+ *
+ * @return the CONTAINS constraints.
+ */
+ public Constraints getContains(){
+ return getConstraintsOfType(GeoArea.CONTAINS);
+ }
+
+ /**
+ * Collect the WITHIN constraints in the object
+ *
+ * @return the WITHIN constraints.
+ */
+ public Constraints getWithin(){
+ return getConstraintsOfType(GeoArea.WITHIN);
+ }
+
+ /**
+ * Collect the OVERLAPS constraints in the object
+ *
+ * @return the OVERLAPS constraints.
+ */
+ public Constraints getOverlaps(){
+ return getConstraintsOfType(GeoArea.OVERLAPS);
+ }
+
+ /**
+ * Collect the DISJOINT constraints in the object
+ *
+ * @return the DISJOINT constraints.
+ */
+ public Constraints getDisjoint(){
+ return getConstraintsOfType(GeoArea.DISJOINT);
+ }
+
+ private Constraints getConstraintsOfType(int type){
+ Constraints constraints = new Constraints();
+ for (GeoAreaShape constraint : keySet()) {
+ if (type == get(constraint)) {
+ constraints.put(constraint, type);
+ }
+ }
+ return constraints;
+ }
+ }
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeRelationshipTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeRelationshipTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeRelationshipTest.java
new file mode 100644
index 0000000..fe1b1d9
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoShapeRelationshipTest.java
@@ -0,0 +1,240 @@
+package org.apache.lucene.spatial3d.geom;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import org.junit.Test;
+
+/**
+ * Random test to check relationship between GeoAreaShapes and GeoShapes.
+ */
+public class RandomGeoShapeRelationshipTest extends RandomGeoShapeGenerator {
+
+
+ /**
+ * Test for WITHIN points. We build a WITHIN shape with respect the geoAreaShape
+ * and create a point WITHIN the shape. The resulting shape should be WITHIN
+ * the original shape.
+ *
+ */
+ @Test
+ @Repeat(iterations = 5)
+ public void testRandomPointWithin() {
+ int referenceShapeType = CONVEX_POLYGON;
+ PlanetModel planetModel = randomPlanetModel();
+ int shapeType = randomShapeType();
+ GeoAreaShape shape = null;
+ GeoPoint point = null;
+ while (point == null) {
+ shape = randomGeoAreaShape(shapeType, planetModel);
+ Constraints constraints = getEmptyConstraint();
+ constraints.put(shape, GeoArea.WITHIN);
+ GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
+ if (reference != null) {
+ constraints = new Constraints();
+ constraints.put(reference, GeoArea.WITHIN);
+ point = randomGeoPoint(planetModel, constraints);
+ }
+ }
+ assertTrue(shape.isWithin(point));
+ }
+
+ /**
+ * Test for NOT WITHIN points. We build a DIJOINT shape with respect the geoAreaShape
+ * and create a point WITHIN that shape. The resulting shape should not be WITHIN
+ * the original shape.
+ *
+ */
+ @Repeat(iterations = 5)
+ public void testRandomPointNotWithin() {
+ int referenceShapeType = CONVEX_POLYGON;
+ PlanetModel planetModel = randomPlanetModel();
+ int shapeType = randomShapeType();
+ GeoAreaShape shape = null;
+ GeoPoint point = null;
+ while (point == null) {
+ shape = randomGeoAreaShape(shapeType, planetModel);
+ Constraints constraints = getEmptyConstraint();
+ constraints.put(shape, GeoArea.DISJOINT);
+ GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
+ if (reference != null) {
+ constraints = new Constraints();
+ constraints.put(reference, GeoArea.WITHIN);
+ point = randomGeoPoint(planetModel, constraints);
+ }
+ }
+ assertFalse(shape.isWithin(point));
+ }
+
+ /**
+ * Test for disjoint shapes. We build a DISJOINT shape with respect the geoAreaShape
+ * and create shapes WITHIN that shapes. The resulting shape should be DISJOINT
+ * to the geoAreaShape.
+ *
+ * Note that both shapes cannot be concave.
+ */
+ @Test
+ @Repeat(iterations = 5)
+ public void testRandomDisjoint() {
+ int referenceShapeType = CONVEX_SIMPLE_POLYGON;
+ PlanetModel planetModel = randomPlanetModel();
+ int geoAreaShapeType = randomGeoAreaShapeType();
+ int shapeType =randomConvexShapeType();
+
+ GeoShape shape = null;
+ GeoAreaShape geoAreaShape = null;
+ while (shape == null) {
+ geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
+ Constraints constraints = new Constraints();
+ constraints.put(geoAreaShape, GeoArea.DISJOINT);
+ GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
+ if (reference != null) {
+ constraints = getEmptyConstraint();
+ constraints.put(reference, GeoArea.WITHIN);
+ shape = randomGeoShape(shapeType, planetModel, constraints);
+ }
+ }
+ int rel = geoAreaShape.getRelationship(shape);
+ assertEquals(GeoArea.DISJOINT, rel);
+ if (shape instanceof GeoArea) {
+ rel = ((GeoArea)shape).getRelationship(geoAreaShape);
+ assertEquals(GeoArea.DISJOINT, rel);
+ }
+ }
+
+ /**
+ * Test for within shapes. We build a shape WITHIN the geoAreaShape and create
+ * shapes WITHIN that shape. The resulting shape should be WITHIN
+ * to the geoAreaShape.
+ *
+ * Note that if the geoAreaShape is not concave the other shape must be not concave.
+ */
+ @Test
+ @Repeat(iterations = 5)
+ public void testRandomWithIn() {
+ PlanetModel planetModel = randomPlanetModel();
+ int geoAreaShapeType = randomGeoAreaShapeType();
+ int shapeType =randomShapeType();
+ int referenceShapeType = CONVEX_SIMPLE_POLYGON;
+ if (!isConcave(geoAreaShapeType)){
+ shapeType =randomConvexShapeType();
+ }
+ if(isConcave(shapeType)){//both concave
+ referenceShapeType = CONCAVE_SIMPLE_POLYGON;
+ }
+ GeoShape shape = null;
+ GeoAreaShape geoAreaShape = null;
+ while (shape == null) {
+ geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
+ Constraints constraints = new Constraints();
+ constraints.put(geoAreaShape, GeoArea.WITHIN);
+ GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
+ if (reference != null) {
+ constraints = new Constraints();
+ constraints.put(reference, GeoArea.WITHIN);
+ shape = randomGeoShape(shapeType, planetModel, constraints);
+ }
+ }
+ int rel = geoAreaShape.getRelationship(shape);
+ assertEquals(GeoArea.WITHIN, rel);
+ if (shape instanceof GeoArea) {
+ rel = ((GeoArea)shape).getRelationship(geoAreaShape);
+ assertEquals(GeoArea.CONTAINS, rel);
+ }
+ }
+
+
+ /**
+ * Test for contains shapes. We build a shape containing the geoAreaShape and create
+ * shapes WITHIN that shape. The resulting shape should CONTAIN
+ * the geoAreaShape.
+ *
+ * Note that if the geoAreaShape is concave the other shape must be concave.
+ * If shape is concave, the shape for reference should be concave as well.
+ *
+ */
+ @Test
+ @Repeat(iterations = 1)
+ public void testRandomContains() {
+ int referenceShapeType = CONVEX_SIMPLE_POLYGON;
+ PlanetModel planetModel = randomPlanetModel();
+ int geoAreaShapeType = randomGeoAreaShapeType();
+ while (geoAreaShapeType == COLLECTION){
+ geoAreaShapeType = randomGeoAreaShapeType();
+ }
+ int shapeType = randomShapeType();
+ if (isConcave(geoAreaShapeType)){
+ shapeType = randomConcaveShapeType();
+ }
+ if (isConcave(shapeType)){
+ referenceShapeType = CONCAVE_SIMPLE_POLYGON;
+ }
+ GeoShape shape = null;
+ GeoAreaShape geoAreaShape = null;
+ while (shape == null) {
+ geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
+ Constraints constraints = getEmptyConstraint();
+ constraints.put(geoAreaShape, GeoArea.CONTAINS);
+ GeoPolygon reference =(GeoPolygon)randomGeoAreaShape(referenceShapeType, planetModel, constraints);
+ if (reference != null) {
+ constraints = getEmptyConstraint();
+ constraints.put(reference, GeoArea.CONTAINS);
+ shape = randomGeoShape(shapeType, planetModel, constraints);
+ }
+ }
+ int rel = geoAreaShape.getRelationship(shape);
+ assertEquals(GeoArea.CONTAINS, rel);
+ if (shape instanceof GeoArea) {
+ rel = ((GeoArea)shape).getRelationship(geoAreaShape);
+ assertEquals(GeoArea.WITHIN, rel);
+ }
+ }
+
+ /**
+ * Test for overlapping shapes. We build a shape that contains part of the
+ * geoAreaShape, is disjoint to other part and contains a disjoint shape. We create
+ * shapes according the criteria. The resulting shape should OVERLAP
+ * the geoAreaShape.
+ */
+ @Test
+ @Repeat(iterations = 5)
+ public void testRandomOverlaps() {
+ PlanetModel planetModel = randomPlanetModel();
+ int geoAreaShapeType = randomGeoAreaShapeType();
+ int shapeType = randomShapeType();
+
+ GeoShape shape = null;
+ GeoAreaShape geoAreaShape = null;
+ while (shape == null) {
+ geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
+ Constraints constraints = getEmptyConstraint();
+ constraints.put(geoAreaShape,GeoArea.WITHIN);
+ GeoAreaShape reference1 = randomGeoAreaShape(CONVEX_SIMPLE_POLYGON, planetModel, constraints);
+ if (reference1 == null){
+ continue;
+ }
+ constraints = getEmptyConstraint();
+ constraints.put(geoAreaShape, GeoArea.WITHIN);
+ constraints.put(reference1, GeoArea.DISJOINT);
+ GeoAreaShape reference2 = randomGeoAreaShape(CONVEX_SIMPLE_POLYGON, planetModel, constraints);
+ if (reference2 == null){
+ continue;
+ }
+ constraints = getEmptyConstraint();
+ constraints.put(geoAreaShape, GeoArea.DISJOINT);
+ GeoAreaShape reference3 = randomGeoAreaShape(CONVEX_SIMPLE_POLYGON, planetModel, constraints);
+ if (reference3 != null) {
+ constraints = new Constraints();
+ constraints.put(reference1, GeoArea.DISJOINT);
+ constraints.put(reference2, GeoArea.CONTAINS);
+ constraints.put(reference3, GeoArea.CONTAINS);
+ shape = randomGeoShape(shapeType, planetModel, constraints);
+ }
+ }
+ int rel = geoAreaShape.getRelationship(shape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ if (shape instanceof GeoArea) {
+ rel = ((GeoArea)shape).getRelationship(geoAreaShape);
+ assertEquals(GeoArea.OVERLAPS, rel);
+ }
+ }
+}
+
[3/3] lucene-solr:branch_6x: LUCENE-7606: Add spatial relationships
between all currently-defined Geo shapes
Posted by kw...@apache.org.
LUCENE-7606: Add spatial relationships between all currently-defined Geo shapes
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b294052d
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b294052d
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b294052d
Branch: refs/heads/branch_6x
Commit: b294052d581719ebb3bf538aace07d5f5deb303b
Parents: 5aa7142
Author: Karl Wright <Da...@gmail.com>
Authored: Thu Aug 3 09:32:11 2017 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Thu Aug 3 09:48:03 2017 -0400
----------------------------------------------------------------------
.../lucene/spatial3d/geom/GeoAreaShape.java | 39 +
.../apache/lucene/spatial3d/geom/GeoBBox.java | 2 +-
.../lucene/spatial3d/geom/GeoBaseAreaShape.java | 125 +++
.../lucene/spatial3d/geom/GeoBaseBBox.java | 38 +-
.../spatial3d/geom/GeoBaseDistanceShape.java | 2 +-
.../lucene/spatial3d/geom/GeoBasePolygon.java | 2 +-
.../spatial3d/geom/GeoComplexPolygon.java | 45 +-
.../spatial3d/geom/GeoCompositeAreaShape.java | 141 +++
.../geom/GeoCompositeMembershipShape.java | 7 +-
.../spatial3d/geom/GeoCompositePolygon.java | 2 +-
.../spatial3d/geom/GeoConcavePolygon.java | 21 +
.../lucene/spatial3d/geom/GeoConvexPolygon.java | 21 +
.../geom/GeoDegenerateHorizontalLine.java | 7 +-
.../geom/GeoDegenerateLatitudeZone.java | 7 +-
.../geom/GeoDegenerateLongitudeSlice.java | 7 +-
.../spatial3d/geom/GeoDegeneratePoint.java | 5 +
.../geom/GeoDegenerateVerticalLine.java | 7 +-
.../lucene/spatial3d/geom/GeoDistanceShape.java | 2 +-
.../lucene/spatial3d/geom/GeoLatitudeZone.java | 46 +-
.../spatial3d/geom/GeoLongitudeSlice.java | 33 +-
.../spatial3d/geom/GeoNorthLatitudeZone.java | 38 +-
.../spatial3d/geom/GeoNorthRectangle.java | 45 +-
.../lucene/spatial3d/geom/GeoPolygon.java | 2 +-
.../lucene/spatial3d/geom/GeoRectangle.java | 45 +-
.../spatial3d/geom/GeoSouthLatitudeZone.java | 37 +-
.../spatial3d/geom/GeoSouthRectangle.java | 43 +-
.../spatial3d/geom/GeoStandardCircle.java | 8 +
.../lucene/spatial3d/geom/GeoStandardPath.java | 37 +
.../geom/GeoWideDegenerateHorizontalLine.java | 9 +-
.../spatial3d/geom/GeoWideLongitudeSlice.java | 32 +-
.../spatial3d/geom/GeoWideNorthRectangle.java | 48 +-
.../lucene/spatial3d/geom/GeoWideRectangle.java | 46 +-
.../spatial3d/geom/GeoWideSouthRectangle.java | 44 +-
.../apache/lucene/spatial3d/geom/GeoWorld.java | 5 +
.../CompositeGeoPolygonRelationshipsTest.java | 842 +++++++++++++++++
.../spatial3d/geom/RandomGeoShapeGenerator.java | 944 +++++++++++++++++++
.../geom/RandomGeoShapeRelationshipTest.java | 240 +++++
.../geom/SimpleGeoPolygonRelationshipsTest.java | 837 ++++++++++++++++
38 files changed, 3433 insertions(+), 428 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaShape.java
new file mode 100644
index 0000000..b00ffca
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaShape.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * Shape that implements GeoArea. This type of shapes are able to resolve the
+ * spatial relationship of other shapes with itself.
+ *
+ * @lucene.experimental
+ */
+
+public interface GeoAreaShape extends GeoMembershipShape, GeoArea{
+
+ /**
+ * Assess whether a shape intersects with any of the edges this shape.
+ * Note well that this method return false if the shape contains, is within
+ * or is disjoint with the given shape.
+ *
+ * @param geoShape is the shape to assess for intersection with this shape's edges.
+ *
+ * @return true if there's such an intersection, false if not.
+ */
+ boolean intersects(GeoShape geoShape);
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
index 0ae2425..683333c 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
@@ -23,7 +23,7 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.experimental
*/
-public interface GeoBBox extends GeoMembershipShape, GeoSizeable, GeoArea {
+public interface GeoBBox extends GeoAreaShape, GeoSizeable {
/**
* Expand box by specified angle.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseAreaShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseAreaShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseAreaShape.java
new file mode 100644
index 0000000..5bd8ab3
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseAreaShape.java
@@ -0,0 +1,125 @@
+/*
+ * 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;
+
+/**
+ * Base extended areaShape object.
+ *
+ * @lucene.internal
+ */
+abstract class GeoBaseAreaShape extends GeoBaseMembershipShape implements GeoAreaShape {
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ */
+ public GeoBaseAreaShape(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+ /** All edgepoints inside shape */
+ protected final static int ALL_INSIDE = 0;
+ /** Some edgepoints inside shape */
+ protected final static int SOME_INSIDE = 1;
+ /** No edgepoints inside shape */
+ protected final static int NONE_INSIDE = 2;
+
+ /** Determine the relationship between the GeoAreShape and the
+ * shape's edgepoints.
+ *@param geoShape is the shape.
+ *@return the relationship.
+ */
+ protected int isShapeInsideGeoAreaShape(final GeoShape geoShape) {
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (GeoPoint p : geoShape.getEdgePoints()) {
+ if (isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+ /** Determine the relationship between the GeoAreaShape's edgepoints and the
+ * provided shape.
+ *@param geoshape is the shape.
+ *@return the relationship.
+ */
+ protected int isGeoAreaShapeInsideShape(final GeoShape geoshape) {
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (GeoPoint p : getEdgePoints()) {
+ if (geoshape.isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+ @Override
+ public int getRelationship(GeoShape geoShape) {
+ final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
+ if (insideGeoAreaShape == SOME_INSIDE) {
+ return GeoArea.OVERLAPS;
+ }
+
+ final int insideShape = isGeoAreaShapeInsideShape(geoShape);
+ if (insideShape == SOME_INSIDE) {
+ return GeoArea.OVERLAPS;
+ }
+
+ if (insideGeoAreaShape == ALL_INSIDE && insideShape==ALL_INSIDE) {
+ return GeoArea.OVERLAPS;
+ }
+
+ if (intersects(geoShape)){
+ return GeoArea.OVERLAPS;
+ }
+
+ if (insideGeoAreaShape == ALL_INSIDE) {
+ return GeoArea.WITHIN;
+ }
+
+ if (insideShape==ALL_INSIDE) {
+ return GeoArea.CONTAINS;
+ }
+
+ return GeoArea.DISJOINT;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
index ba92cc2..59562be 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
@@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.internal
*/
-abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
+abstract class GeoBaseBBox extends GeoBaseAreaShape implements GeoBBox {
/** Construct, given planet model.
*@param planetModel is the planet model.
@@ -31,42 +31,6 @@ abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
super(planetModel);
}
- // Signals for relationship of edge points to shape
-
- /** All edgepoints inside shape */
- protected final static int ALL_INSIDE = 0;
- /** Some edgepoints inside shape */
- protected final static int SOME_INSIDE = 1;
- /** No edgepoints inside shape */
- protected final static int NONE_INSIDE = 2;
-
- /** Determine the relationship between this BBox and the provided
- * shape's edgepoints.
- *@param path is the shape.
- *@return the relationship.
- */
- protected int isShapeInsideBBox(final GeoShape path) {
- final GeoPoint[] pathPoints = path.getEdgePoints();
- boolean foundOutside = false;
- boolean foundInside = false;
- for (GeoPoint p : pathPoints) {
- if (isWithin(p)) {
- foundInside = true;
- } else {
- foundOutside = true;
- }
- if (foundInside && foundOutside) {
- return SOME_INSIDE;
- }
- }
- if (!foundInside && !foundOutside)
- return NONE_INSIDE;
- if (foundInside && !foundOutside)
- return ALL_INSIDE;
- if (foundOutside && !foundInside)
- return NONE_INSIDE;
- return SOME_INSIDE;
- }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
index 82e811a..d7be2ab 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
@@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.experimental
*/
-public abstract class GeoBaseDistanceShape extends GeoBaseMembershipShape implements GeoDistanceShape {
+public abstract class GeoBaseDistanceShape extends GeoBaseAreaShape implements GeoDistanceShape {
/** Constructor.
*@param planetModel is the planet model to use.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
index 08c0634..7fe8c98 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
@@ -21,7 +21,7 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.internal
*/
-abstract class GeoBasePolygon extends GeoBaseMembershipShape implements GeoPolygon {
+abstract class GeoBasePolygon extends GeoBaseAreaShape implements GeoPolygon {
/** Constructor.
*@param planetModel is the planet model to use.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoComplexPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoComplexPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoComplexPolygon.java
index 7f8f649..6bd66d4 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoComplexPolygon.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoComplexPolygon.java
@@ -369,6 +369,32 @@ class GeoComplexPolygon extends GeoBasePolygon {
return true;
}
+ @Override
+ public boolean intersects(GeoShape geoShape) {
+ // Create the intersector
+ final EdgeIterator intersector = new IntersectorShapeIterator(geoShape);
+ // First, compute the bounds for the the plane
+ final XYZBounds xyzBounds = new XYZBounds();
+ geoShape.getBounds(xyzBounds);
+
+ // Figure out which tree likely works best
+ final double xDelta = xyzBounds.getMaximumX() - xyzBounds.getMinimumX();
+ final double yDelta = xyzBounds.getMaximumY() - xyzBounds.getMinimumY();
+ final double zDelta = xyzBounds.getMaximumZ() - xyzBounds.getMinimumZ();
+ // Select the smallest range
+ if (xDelta <= yDelta && xDelta <= zDelta) {
+ // Drill down in x
+ return !xTree.traverse(intersector, xyzBounds.getMinimumX(), xyzBounds.getMaximumX());
+ } else if (yDelta <= xDelta && yDelta <= zDelta) {
+ // Drill down in y
+ return !yTree.traverse(intersector, xyzBounds.getMinimumY(), xyzBounds.getMaximumY());
+ } else if (zDelta <= xDelta && zDelta <= yDelta) {
+ // Drill down in z
+ return !zTree.traverse(intersector, xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ());
+ }
+ return true;
+ }
+
@Override
public void getBounds(Bounds bounds) {
@@ -691,7 +717,24 @@ class GeoComplexPolygon extends GeoBasePolygon {
}
}
-
+
+
+ /** Assess whether edge intersects the provided shape.
+ */
+ private class IntersectorShapeIterator implements EdgeIterator {
+
+ private final GeoShape shape;
+
+ public IntersectorShapeIterator(final GeoShape shape) {
+ this.shape = shape;
+ }
+
+ @Override
+ public boolean matches(final Edge edge) {
+ return !shape.intersects(edge.plane, edge.notablePoints, edge.startPlane, edge.endPlane);
+ }
+ }
+
/** Count the number of verifiable edge crossings.
*/
private class LinearCrossingEdgeIterator implements EdgeIterator {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeAreaShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeAreaShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeAreaShape.java
new file mode 100644
index 0000000..c7ad81d
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeAreaShape.java
@@ -0,0 +1,141 @@
+/*
+ * 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;
+
+/**
+ * GeoCompositeAreShape is a set of GeoAreaShape's, treated as a unit.
+ *
+ * @lucene.experimental
+ */
+public class GeoCompositeAreaShape extends GeoCompositeMembershipShape implements GeoAreaShape {
+
+ /**
+ * Add a shape to the composite. It throw an IllegalArgumentException
+ * if the shape is not a GeoAreaShape
+ *@param shape is the shape to add.
+ */
+ @Override
+ public void addShape(final GeoMembershipShape shape) {
+ if (!(shape instanceof GeoAreaShape)){
+ throw new IllegalArgumentException("GeoCompositeAreaShape must be composed of GeoAreaShapes");
+ }
+ shapes.add(shape);
+ }
+
+ public boolean intersects(GeoShape geoShape){
+ for(GeoShape inShape : shapes){
+ if (((GeoAreaShape)inShape).intersects(geoShape)){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** All edgepoints inside shape */
+ protected final static int ALL_INSIDE = 0;
+ /** Some edgepoints inside shape */
+ protected final static int SOME_INSIDE = 1;
+ /** No edgepoints inside shape */
+ protected final static int NONE_INSIDE = 2;
+
+ /** Determine the relationship between the GeoAreShape and the
+ * shape's edgepoints.
+ *@param geoShape is the shape.
+ *@return the relationship.
+ */
+ protected int isShapeInsideGeoAreaShape(final GeoShape geoShape) {
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (GeoPoint p : geoShape.getEdgePoints()) {
+ if (isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+ /** Determine the relationship between the GeoAreShape's edgepoints and the
+ * provided shape.
+ *@param geoshape is the shape.
+ *@return the relationship.
+ */
+ protected int isGeoAreaShapeInsideShape(final GeoShape geoshape) {
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (GeoPoint p : getEdgePoints()) {
+ if (geoshape.isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+ @Override
+ public int getRelationship(GeoShape geoShape) {
+ final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
+ if (insideGeoAreaShape == SOME_INSIDE) {
+ return GeoArea.OVERLAPS;
+ }
+
+ final int insideShape = isGeoAreaShapeInsideShape(geoShape);
+ if (insideShape == SOME_INSIDE) {
+ return GeoArea.OVERLAPS;
+ }
+
+ if (insideGeoAreaShape == ALL_INSIDE && insideShape==ALL_INSIDE) {
+ return GeoArea.OVERLAPS;
+ }
+
+ if (intersects(geoShape)){
+ return GeoArea.OVERLAPS;
+ }
+
+ if (insideGeoAreaShape == ALL_INSIDE) {
+ return GeoArea.WITHIN;
+ }
+
+ if (insideShape==ALL_INSIDE) {
+ return GeoArea.CONTAINS;
+ }
+
+ return GeoArea.DISJOINT;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
index 6600a34..24428f9 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
@@ -17,6 +17,7 @@
package org.apache.lucene.spatial3d.geom;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -57,7 +58,11 @@ public class GeoCompositeMembershipShape implements GeoMembershipShape {
@Override
public GeoPoint[] getEdgePoints() {
- return shapes.get(0).getEdgePoints();
+ List<GeoPoint> edgePoints = new ArrayList<>();
+ for(int i=0;i<shapes.size();i++){
+ edgePoints.addAll(Arrays.asList(shapes.get(i).getEdgePoints()));
+ }
+ return edgePoints.toArray(new GeoPoint[edgePoints.size()]);
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
index 920d3fb..be373ed 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
@@ -21,7 +21,7 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.experimental
*/
-public class GeoCompositePolygon extends GeoCompositeMembershipShape implements GeoPolygon {
+public class GeoCompositePolygon extends GeoCompositeAreaShape implements GeoPolygon {
/** Constructor.
*/
public GeoCompositePolygon() {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java
index e2a4c1e..75fecc8 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java
@@ -366,6 +366,27 @@ class GeoConcavePolygon extends GeoBasePolygon {
return false;
}
+ @Override
+ public boolean intersects(GeoShape geoShape) {
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
+ if (!isInternalEdges.get(edgeIndex)) {
+ if (geoShape.intersects(edge, points, eitherBounds.get(edge))) {
+ return true;
+ }
+ }
+ }
+ if (holes != null) {
+ for (final GeoPolygon hole : holes) {
+ if (hole.intersects(geoShape)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/** A membership implementation representing polygon edges that must apply.
*/
protected static class EitherBound implements Membership {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
index 6bd0aad..bf75e3b 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
@@ -356,6 +356,27 @@ class GeoConvexPolygon extends GeoBasePolygon {
return false;
}
+ @Override
+ public boolean intersects(GeoShape shape) {
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
+ if (!isInternalEdges.get(edgeIndex)) {
+ if (shape.intersects(edge, points, eitherBounds.get(edge))) {
+ return true;
+ }
+ }
+ }
+ if (holes != null) {
+ for (final GeoPolygon hole : holes) {
+ if (hole.intersects(shape)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/** A membership implementation representing polygon edges that must apply.
*/
protected static class EitherBound implements Membership {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
index 927fbdc..9518180 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
@@ -155,6 +155,11 @@ class GeoDegenerateHorizontalLine extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(plane, planePoints, leftPlane, rightPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.addHorizontalPlane(planetModel, latitude, plane, leftPlane, rightPlane)
@@ -164,7 +169,7 @@ class GeoDegenerateHorizontalLine extends GeoBaseBBox {
@Override
public int getRelationship(final GeoShape path) {
//System.err.println("getting relationship between "+this+" and "+path);
- if (path.intersects(plane, planePoints, leftPlane, rightPlane)) {
+ if (intersects(path)) {
//System.err.println(" overlaps");
return OVERLAPS;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
index ea6bb57..fc6b234 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
@@ -86,6 +86,11 @@ class GeoDegenerateLatitudeZone extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(plane, planePoints);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.noLongitudeBound()
@@ -98,7 +103,7 @@ class GeoDegenerateLatitudeZone extends GeoBaseBBox {
// work with no area endpoints. So we rely entirely on intersections.
//System.out.println("Got here! latitude="+latitude+" path="+path);
- if (path.intersects(plane, planePoints)) {
+ if (intersects(path)) {
return OVERLAPS;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
index 09f468c..e610ff4 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
@@ -97,6 +97,11 @@ class GeoDegenerateLongitudeSlice extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(plane, planePoints, boundingPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds
@@ -107,7 +112,7 @@ class GeoDegenerateLongitudeSlice extends GeoBaseBBox {
@Override
public int getRelationship(final GeoShape path) {
// Look for intersections.
- if (path.intersects(plane, planePoints, boundingPlane))
+ if (intersects(path))
return OVERLAPS;
if (path.isWithin(interiorPoint))
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
index ab08579..2860757 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
@@ -67,6 +67,11 @@ class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
}
@Override
+ public boolean intersects(GeoShape geoShape) {
+ return false;
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
bounds.addPoint(this);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
index dff53b4..c8acf78 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
@@ -145,6 +145,11 @@ public class GeoDegenerateVerticalLine extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.addVerticalPlane(planetModel, longitude, plane, boundingPlane, topPlane, bottomPlane)
@@ -154,7 +159,7 @@ public class GeoDegenerateVerticalLine extends GeoBaseBBox {
@Override
public int getRelationship(final GeoShape path) {
//System.err.println(this+" relationship to "+path);
- if (path.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane)) {
+ if (intersects(path)) {
//System.err.println(" overlaps");
return OVERLAPS;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
index ebd433f..c49ed30 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
@@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.experimental
*/
-public interface GeoDistanceShape extends GeoMembershipShape, GeoDistance {
+public interface GeoDistanceShape extends GeoAreaShape, GeoDistance {
/**
* Compute a bound based on a provided distance measure.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
index 14618f5..716efb5 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
@@ -120,6 +120,12 @@ class GeoLatitudeZone extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(topPlane, planePoints, bottomPlane) ||
+ geoShape.intersects(bottomPlane, planePoints, topPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.noLongitudeBound()
@@ -128,46 +134,6 @@ class GeoLatitudeZone extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean topBoundaryInsideShape = path.isWithin(topBoundaryPoint);
- final boolean bottomBoundaryInsideShape = path.isWithin(bottomBoundaryPoint);
-
- if (topBoundaryInsideShape && !bottomBoundaryInsideShape ||
- !topBoundaryInsideShape && bottomBoundaryInsideShape)
- return OVERLAPS;
-
- final boolean insideShape = topBoundaryInsideShape && bottomBoundaryInsideShape;
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(topPlane, planePoints, bottomPlane) ||
- path.intersects(bottomPlane, planePoints, topPlane))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane);
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
index 294d4e8..fc21a21 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
@@ -128,6 +128,12 @@ class GeoLongitudeSlice extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(leftPlane, planePoints, rightPlane) ||
+ geoShape.intersects(rightPlane, planePoints, leftPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds
@@ -139,33 +145,6 @@ class GeoLongitudeSlice extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- if (path.intersects(leftPlane, planePoints, rightPlane) ||
- path.intersects(rightPlane, planePoints, leftPlane)) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- return WITHIN;
- }
-
- if (insideShape) {
- return CONTAINS;
- }
-
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane);
final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
index 2acfc4e..7c3ea96 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
@@ -99,6 +99,12 @@ class GeoNorthLatitudeZone extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return
+ geoShape.intersects(bottomPlane, planePoints);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds
@@ -106,38 +112,6 @@ class GeoNorthLatitudeZone extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(bottomBoundaryPoint);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(bottomPlane, planePoints))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
return distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
index 27422d2..2a1b7c5 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
@@ -175,6 +175,14 @@ class GeoNorthRectangle extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return
+ geoShape.intersects(bottomPlane, bottomPlanePoints, leftPlane, rightPlane) ||
+ geoShape.intersects(leftPlane, leftPlanePoints, rightPlane, bottomPlane) ||
+ geoShape.intersects(rightPlane, rightPlanePoints, leftPlane, bottomPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds
@@ -186,43 +194,6 @@ class GeoNorthRectangle extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (
- path.intersects(bottomPlane, bottomPlanePoints, leftPlane, rightPlane) ||
- path.intersects(leftPlane, leftPlanePoints, bottomPlane, rightPlane) ||
- path.intersects(rightPlane, rightPlanePoints, leftPlane, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, leftPlane, rightPlane);
final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, bottomPlane);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
index 742bdf8..9125d14 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
@@ -21,6 +21,6 @@ package org.apache.lucene.spatial3d.geom;
*
* @lucene.experimental
*/
-public interface GeoPolygon extends GeoMembershipShape {
+public interface GeoPolygon extends GeoAreaShape {
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
index 3d0a97d..faf2952 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
@@ -197,6 +197,14 @@ class GeoRectangle extends GeoBaseBBox {
}
@Override
+ public boolean intersects(GeoShape geoShape) {
+ return geoShape.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
+ geoShape.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
+ geoShape.intersects(leftPlane, leftPlanePoints, rightPlane, topPlane, bottomPlane) ||
+ geoShape.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.addHorizontalPlane(planetModel, topLat, topPlane, bottomPlane, leftPlane, rightPlane)
@@ -208,43 +216,6 @@ class GeoRectangle extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(ULHC);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
- path.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane, rightPlane) ||
- path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, leftPlane, rightPlane);
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, leftPlane, rightPlane);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
index c915c24..acb7cb0 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
@@ -102,6 +102,11 @@ class GeoSouthLatitudeZone extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(topPlane, planePoints);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds
@@ -109,38 +114,6 @@ class GeoSouthLatitudeZone extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(topBoundaryPoint);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(topPlane, planePoints))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
return distanceStyle.computeDistance(planetModel, topPlane, x,y,z);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
index ed380e1..f75fc8c 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
@@ -173,6 +173,13 @@ class GeoSouthRectangle extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(topPlane, topPlanePoints, leftPlane, rightPlane) ||
+ geoShape.intersects(leftPlane, leftPlanePoints, rightPlane, topPlane) ||
+ geoShape.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds
@@ -184,42 +191,6 @@ class GeoSouthRectangle extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, leftPlane, rightPlane) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane, rightPlane) ||
- path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, leftPlane, rightPlane);
final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
index 06bef00..ec83edf 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
@@ -140,6 +140,14 @@ class GeoStandardCircle extends GeoBaseCircle {
}
@Override
+ public boolean intersects(GeoShape geoShape) {
+ if (circlePlane == null) {
+ return false;
+ }
+ return geoShape.intersects(circlePlane, circlePoints);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
if (circlePlane == null) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
index 51c5078..b3b6594 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
@@ -289,6 +289,23 @@ class GeoStandardPath extends GeoBasePath {
}
@Override
+ public boolean intersects(GeoShape geoShape) {
+ for (final SegmentEndpoint pathPoint : endPoints) {
+ if (pathPoint.intersects(geoShape)) {
+ return true;
+ }
+ }
+
+ for (final PathSegment pathSegment : segments) {
+ if (pathSegment.intersects(geoShape)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
// For building bounds, order matters. We want to traverse
@@ -549,6 +566,17 @@ class GeoStandardPath extends GeoBasePath {
return circlePlane.intersects(planetModel, p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
}
+ /** Determine if this endpoint intersects a GeoShape.
+ *@param geoShape is the GeoShape.
+ *@return true if there is shape intersect this endpoint.
+ */
+ public boolean intersects(final GeoShape geoShape) {
+ //System.err.println(" looking for intersection between plane "+p+" and circle "+circlePlane+" on proper side of "+cutoffPlanes+" within "+bounds);
+ if (circlePlane == null)
+ return false;
+ return geoShape.intersects(circlePlane, this.notablePoints, this.cutoffPlanes);
+ }
+
/** Get the bounds for a segment endpoint.
*@param planetModel is the planet model.
*@param bounds are the bounds to be modified.
@@ -799,6 +827,15 @@ class GeoStandardPath extends GeoBasePath {
lowerConnectingPlane.intersects(planetModel, p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
}
+ /** Determine if this endpoint intersects a specified GeoShape.
+ *@param geoShape is the GeoShape.
+ *@return true if there GeoShape intersects this endpoint.
+ */
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(upperConnectingPlane, upperConnectingPlanePoints, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
+ geoShape.intersects(lowerConnectingPlane, lowerConnectingPlanePoints, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+ }
+
/** Get the bounds for a segment endpoint.
*@param planetModel is the planet model.
*@param bounds are the bounds to be modified.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
index fe93473..90d35ee 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
@@ -166,6 +166,13 @@ class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return geoShape.intersects(plane, planePoints, eitherBound);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.isWide()
@@ -176,7 +183,7 @@ class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
@Override
public int getRelationship(final GeoShape path) {
- if (path.intersects(plane, planePoints, eitherBound)) {
+ if (intersects(path)) {
return OVERLAPS;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
index 705d961..e15c275 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
@@ -140,6 +140,14 @@ class GeoWideLongitudeSlice extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return geoShape.intersects(leftPlane, planePoints) ||
+ geoShape.intersects(rightPlane, planePoints);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.isWide()
@@ -151,30 +159,6 @@ class GeoWideLongitudeSlice extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- if (path.intersects(leftPlane, planePoints) ||
- path.intersects(rightPlane, planePoints))
- return OVERLAPS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- if (insideShape)
- return CONTAINS;
-
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
// Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
// unbounded distance to both the left and the right and only take the minimum of the two.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
index 849d4e9..5672003 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
@@ -177,6 +177,16 @@ class GeoWideNorthRectangle extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return
+ geoShape.intersects(bottomPlane, bottomPlanePoints, eitherBound) ||
+ geoShape.intersects(leftPlane, leftPlanePoints, bottomPlane) ||
+ geoShape.intersects(rightPlane, rightPlanePoints, bottomPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.isWide()
@@ -188,44 +198,6 @@ class GeoWideNorthRectangle extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" comparing to "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (
- path.intersects(bottomPlane, bottomPlanePoints, eitherBound) ||
- path.intersects(leftPlane, leftPlanePoints, bottomPlane) ||
- path.intersects(rightPlane, rightPlanePoints, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, eitherBound);
// Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
index 53c8c59..43b9bc7 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
@@ -205,6 +205,14 @@ class GeoWideRectangle extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
+ geoShape.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
+ geoShape.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
+ geoShape.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.isWide()
@@ -217,44 +225,6 @@ class GeoWideRectangle extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" comparing to "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(ULHC);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
- path.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
- path.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, eitherBound);
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, eitherBound);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
index 29d89c5..ea60322 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
@@ -176,6 +176,13 @@ class GeoWideSouthRectangle extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return geoShape.intersects(topPlane, topPlanePoints, eitherBound) ||
+ geoShape.intersects(leftPlane, leftPlanePoints, topPlane) ||
+ geoShape.intersects(rightPlane, rightPlanePoints, topPlane);
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
bounds.isWide()
@@ -187,43 +194,6 @@ class GeoWideSouthRectangle extends GeoBaseBBox {
}
@Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" comparing to "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, eitherBound) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane) ||
- path.intersects(rightPlane, rightPlanePoints, topPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, eitherBound);
// Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b294052d/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
index 17352b9..ebe11db 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
@@ -67,6 +67,11 @@ class GeoWorld extends GeoBaseBBox {
}
@Override
+ public boolean intersects(final GeoShape geoShape) {
+ return false;
+ }
+
+ @Override
public void getBounds(Bounds bounds) {
super.getBounds(bounds);
// Unnecessary