/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.spatial3d.geom;
import java.util.ArrayList;
import java.util.List;
import java.util.BitSet;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class GeoPolygonTest {
@Test
public void testPolygonPointFiltering() {
final GeoPoint point1 = new GeoPoint(PlanetModel.WGS84, 1.0, 2.0);
final GeoPoint point2 = new GeoPoint(PlanetModel.WGS84, 0.5, 2.5);
final GeoPoint point3 = new GeoPoint(PlanetModel.WGS84, 0.0, 0.0);
final GeoPoint point4 = new GeoPoint(PlanetModel.WGS84, Math.PI * 0.5, 0.0);
final GeoPoint point5 = new GeoPoint(PlanetModel.WGS84, 1.0, 0.0);
// First: duplicate points in the middle
{
final List<GeoPoint> originalPoints = new ArrayList<>();
originalPoints.add(point1);
originalPoints.add(point2);
originalPoints.add(point2);
originalPoints.add(point3);
final List<GeoPoint> filteredPoints = GeoPolygonFactory.filterEdges(GeoPolygonFactory.filterPoints(originalPoints), 0.0);
assertEquals(3, filteredPoints.size());
assertEquals(point1, filteredPoints.get(0));
assertEquals(point2, filteredPoints.get(1));
assertEquals(point3, filteredPoints.get(2));
}
// Next, duplicate points at the beginning
{
final List<GeoPoint> originalPoints = new ArrayList<>();
originalPoints.add(point2);
originalPoints.add(point1);
originalPoints.add(point3);
originalPoints.add(point2);
final List<GeoPoint> filteredPoints = GeoPolygonFactory.filterEdges(GeoPolygonFactory.filterPoints(originalPoints), 0.0);
assertEquals(3, filteredPoints.size());
assertEquals(point2, filteredPoints.get(0));
assertEquals(point1, filteredPoints.get(1));
assertEquals(point3, filteredPoints.get(2));
}
// Coplanar point removal
{
final List<GeoPoint> originalPoints = new ArrayList<>();
originalPoints.add(point1);
originalPoints.add(point3);
originalPoints.add(point4);
originalPoints.add(point5);
final List<GeoPoint> filteredPoints = GeoPolygonFactory.filterEdges(GeoPolygonFactory.filterPoints(originalPoints), 0.0);
assertEquals(3, filteredPoints.size());
assertEquals(point1, filteredPoints.get(0));
assertEquals(point3, filteredPoints.get(1));
assertEquals(point5, filteredPoints.get(2));
}
// Over the boundary
{
final List<GeoPoint> originalPoints = new ArrayList<>();
originalPoints.add(point5);
originalPoints.add(point1);
originalPoints.add(point3);
originalPoints.add(point4);
final List<GeoPoint> filteredPoints = GeoPolygonFactory.filterEdges(GeoPolygonFactory.filterPoints(originalPoints), 0.0);
assertEquals(3, filteredPoints.size());
assertEquals(point5, filteredPoints.get(0));
assertEquals(point1, filteredPoints.get(1));
assertEquals(point3, filteredPoints.get(2));
}
}
@Test
public void testPolygonClockwise() {
GeoPolygon c;
GeoPoint gp;
List<GeoPoint> points;
List<GeoPolygonFactory.PolygonDescription> shapes;
// Points go counterclockwise, so
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
//System.out.println(c);
// Middle point should NOT be within!!
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(!c.isWithin(gp));
shapes = new ArrayList<>();
shapes.add(new GeoPolygonFactory.PolygonDescription(points));
c = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, shapes);
assertTrue(!c.isWithin(gp));
// Now, go clockwise
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
//System.out.println(c);
// Middle point should be within!!
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
shapes = new ArrayList<>();
shapes.add(new GeoPolygonFactory.PolygonDescription(points));
c = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, shapes);
assertTrue(c.isWithin(gp));
}
@Test
public void testPolygonIntersects() {
GeoPolygon c;
List<GeoPoint> points;
List<GeoPolygonFactory.PolygonDescription> shapes;
XYZBounds xyzBounds;
XYZSolid xyzSolid;
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
xyzBounds = new XYZBounds();
c.getBounds(xyzBounds);
xyzSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.SPHERE, xyzBounds.getMinimumX(), xyzBounds.getMaximumX(), xyzBounds.getMinimumY(), xyzBounds.getMaximumY(), xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ());
assertEquals(GeoArea.WITHIN, xyzSolid.getRelationship(c));
xyzSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.SPHERE, xyzBounds.getMinimumY(), xyzBounds.getMaximumY(), xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ(), xyzBounds.getMinimumX(), xyzBounds.getMaximumX());
assertEquals(GeoArea.DISJOINT, xyzSolid.getRelationship(c));
shapes = new ArrayList<>();
shapes.add(new GeoPolygonFactory.PolygonDescription(points));
c = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, shapes);
// Same bounds should work
xyzSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.SPHERE, xyzBounds.getMinimumX(), xyzBounds.getMaximumX(), xyzBounds.getMinimumY(), xyzBounds.getMaximumY(), xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ());
assertEquals(GeoArea.WITHIN, xyzSolid.getRelationship(c));
xyzSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.SPHERE, xyzBounds.getMinimumY(), xyzBounds.getMaximumY(), xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ(), xyzBounds.getMinimumX(), xyzBounds.getMaximumX());
assertEquals(GeoArea.DISJOINT, xyzSolid.getRelationship(c));
// Bounds we obtain from the large polygon also should work.
xyzBounds = new XYZBounds();
c.getBounds(xyzBounds);
xyzSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.SPHERE, xyzBounds.getMinimumX(), xyzBounds.getMaximumX(), xyzBounds.getMinimumY(), xyzBounds.getMaximumY(), xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ());
assertEquals(GeoArea.WITHIN, xyzSolid.getRelationship(c));
xyzSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.SPHERE, xyzBounds.getMinimumY(), xyzBounds.getMaximumY(), xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ(), xyzBounds.getMinimumX(), xyzBounds.getMaximumX());
assertEquals(GeoArea.DISJOINT, xyzSolid.getRelationship(c));
}
@Test
public void testPolygonPointWithin() {
GeoPolygon c;
GeoPoint gp;
List<GeoPoint> points;
List<GeoPolygonFactory.PolygonDescription> shapes;
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
// Sample some points within
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
assertTrue(c.isWithin(gp));
// Sample some nearby points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
assertFalse(c.isWithin(gp));
// Random points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
assertFalse(c.isWithin(gp));
// Now, same thing for large polygon
shapes = new ArrayList<>();
shapes.add(new GeoPolygonFactory.PolygonDescription(points));
c = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, shapes);
// Sample some points within
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
assertTrue(c.isWithin(gp));
// Sample some nearby points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
assertFalse(c.isWithin(gp));
// Random points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
assertFalse(c.isWithin(gp));
// Next bunch of small polygon points
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.01, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.7));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.8));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.7));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.01, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
/*
System.out.println("Points: ");
for (GeoPoint p : points) {
System.out.println(" "+p);
}
*/
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
// Sample some points within
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.7);
assertTrue(c.isWithin(gp));
// Sample some nearby points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
assertFalse(c.isWithin(gp));
// Random points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
assertFalse(c.isWithin(gp));
// Now, same thing for large polygon
shapes = new ArrayList<>();
shapes.add(new GeoPolygonFactory.PolygonDescription(points));
c = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, shapes);
// Sample some points within
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.7);
assertTrue(c.isWithin(gp));
// Sample some nearby points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
assertFalse(c.isWithin(gp));
// Random points outside
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
assertFalse(c.isWithin(gp));
}
@Test
public void testPolygonBounds() {
GeoMembershipShape c;
LatLonBounds b;
List<GeoPoint> points;
XYZBounds xyzb;
GeoPoint point;
GeoArea area;
// BKD failure
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.WGS84, -0.36716183577912814, 1.4836349969188696));
points.add(new GeoPoint(PlanetModel.WGS84, 0.7846038240742979, -0.02743348424931823));
points.add(new GeoPoint(PlanetModel.WGS84, -0.7376479402362607, -0.5072961758807019));
points.add(new GeoPoint(PlanetModel.WGS84, -0.3760415907667887, 1.4970455334565513));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points);
point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
assertTrue(c.isWithin(point));
xyzb = new XYZBounds();
c.getBounds(xyzb);
area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
assertTrue(area.isWithin(point));
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
b = new LatLonBounds();
c.getBounds(b);
assertFalse(b.checkNoLongitudeBound());
assertFalse(b.checkNoTopLatitudeBound());
assertFalse(b.checkNoBottomLatitudeBound());
assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
assertEquals(-0.4, b.getRightLongitude(), 0.000001);
assertEquals(-0.1, b.getMinLatitude(), 0.000001);
assertEquals(0.1, b.getMaxLatitude(), 0.000001);
}
@Test
public void testPolygonBoundsCase1() {
GeoPolygon c;
LatLonBounds b;
List<GeoPoint> points;
XYZBounds xyzb;
GeoPoint point1;
GeoPoint point2;
GeoArea area;
// Build the polygon
points = new ArrayList<>();
points.add(new GeoPoint(PlanetModel.WGS84, 0.7769776943105245, -2.157536559188766));
points.add(new GeoPoint(PlanetModel.WGS84, -0.9796549195552824, -0.25078026625235256));
points.add(new GeoPoint(PlanetModel.WGS84, 0.17644522781457245, 2.4225312555674967));
points.add(new GeoPoint(PlanetModel.WGS84, -1.4459804612164617, -1.2970934639728127));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points);
// GeoCompositeMembershipShape: {[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
// [[lat=0.17644522781457245, lon=2.4225312555674967],
// [lat=-1.4459804612164617, lon=-1.2970934639728127],
// [lat=0.7769776943105245, lon=-2.157536559188766]]},
// GeoConcavePolygon: {planetmodel=PlanetModel.WGS84, points=
// [[lat=-0.9796549195552824, lon=-0.25078026625235256],
// [lat=0.17644522781457245, lon=2.4225312555674967],
// [lat=0.7769776943105245, lon=-2.157536559188766]]}]}
point1 = new GeoPoint(PlanetModel.WGS84, -1.2013743680763862, 0.48458963747230094);
point2 = new GeoPoint(0.3189285805649921, 0.16790264636909197, -0.9308557496413026);
assertTrue(c.isWithin(point1));
assertTrue(c.isWithin(point2));
// Now try bounds
xyzb = new XYZBounds();
c.getBounds(xyzb);
area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
assertTrue(area.isWithin(point1));
assertTrue(area.isWithin(point2));
}
@Test
public void testGeoPolygonBoundsCase2() {
// [junit4] 1> TEST: iter=23 shape=GeoCompositeMembershipShape: {[GeoConvexPolygon: {planetmodel=PlanetModel(ab=0.7563871189161702 c=1.2436128810838298), points=
// [[lat=0.014071770744627236, lon=0.011030818292803128],
// [lat=0.006772117088906782, lon=-0.0012531892445234592],
// [lat=0.0022201615609504792, lon=0.005941293187389326]]}, GeoConcavePolygon: {planetmodel=PlanetModel(ab=0.7563871189161702 c=1.2436128810838298), points=
// [[lat=-0.005507100238396111, lon=-0.008487706131259667],
// [lat=0.014071770744627236, lon=0.011030818292803128],
// [lat=0.0022201615609504792, lon=0.005941293187389326]]}]}
PlanetModel pm = new PlanetModel(0.7563871189161702, 1.2436128810838298);
// Build the polygon
GeoCompositeMembershipShape c = new GeoCompositeMembershipShape();
List<GeoPoint> points1 = new ArrayList<>();
points1.add(new GeoPoint(pm, 0.014071770744627236, 0.011030818292803128));
points1.add(new GeoPoint(pm, 0.006772117088906782, -0.0012531892445234592));
points1.add(new GeoPoint(pm, 0.0022201615609504792, 0.005941293187389326));
BitSet p1bits = new BitSet();
c.addShape(new GeoConvexPolygon(pm, points1, p1bits, true));
List<GeoPoint> points2 = new ArrayList<>();
points2.add(new GeoPoint(pm, -0.005507100238396111, -0.008487706131259667));
points2.add(new GeoPoint(pm, 0.014071770744627236, 0.011030818292803128));
points2.add(new GeoPoint(pm, 0.0022201615609504792, 0.005941293187389326));
BitSet p2bits = new BitSet();
p2bits.set(1, true);
c.addShape(new GeoConcavePolygon(pm, points2, p2bits, false));
//System.out.println(c);
// [junit4] 1> point=[lat=0.003540694517552105, lon=-9.99517927901697E-4]
// [junit4] 1> quantized=[X=0.7563849869428783, Y=-7.560204674780763E-4, Z=0.0026781405884151086]
GeoPoint point = new GeoPoint(pm, 0.003540694517552105, -9.99517927901697E-4);
GeoPoint pointQuantized = new GeoPoint(0.7563849869428783, -7.560204674780763E-4, 0.0026781405884151086);
// Now try bounds
XYZBounds xyzb = new XYZBounds();
c.getBounds(xyzb);
GeoArea area = GeoAreaFactory.makeGeoArea(pm,
xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
assertTrue(c.isWithin(point));
assertTrue(c.isWithin(pointQuantized));
// This fails!!
assertTrue(area.isWithin(point));
assertTrue(area.isWithin(pointQuantized));
}
@Test
public void testGeoConcaveRelationshipCase1() {
/*
[junit4] 1> doc=906 matched but should not
[junit4] 1> point=[lat=-0.9825762558001477, lon=2.4832136904725273]
[junit4] 1> quantized=[X=-0.4505446160475436, Y=0.34850109186970535, Z=-0.8539966368663765]
doc=906 added here:
[junit4] 1> cycle: cell=107836 parentCellID=107835 x: -1147288468 TO -742350917, y: -1609508490 TO 1609508490, z: -2147483647 TO 2147483647, splits: 3 queue.size()=1
[junit4] 1> minx=-0.6107484000858642 maxx=-0.39518364125756916 miny=-0.8568069517709872 maxy=0.8568069517709872 minz=-1.1431930485939341 maxz=1.1431930485939341
[junit4] 1> GeoArea.CONTAINS: now addAll
shape:
[junit4] 1> TEST: iter=18 shape=GeoCompositeMembershipShape: {[GeoConvexPolygon: {
planetmodel=PlanetModel(ab=0.8568069516722363 c=1.1431930483277637), points=
[[lat=1.1577814487635816, lon=1.6283601832010004],
[lat=0.6664570999069251, lon=2.0855825542851574],
[lat=-0.23953537010974632, lon=1.8498724094352876]]}, GeoConcavePolygon: {planetmodel=PlanetModel(ab=0.8568069516722363 c=1.1431930483277637), points=
[[lat=1.1577814487635816, lon=1.6283601832010004],
[lat=-0.23953537010974632, lon=1.8498724094352876],
[lat=-1.1766904875978805, lon=-2.1346828411344436]]}]}
*/
PlanetModel pm = new PlanetModel(0.8568069516722363, 1.1431930483277637);
// Build the polygon
GeoCompositeMembershipShape c = new GeoCompositeMembershipShape();
List<GeoPoint> points1 = new ArrayList<>();
points1.add(new GeoPoint(pm, 1.1577814487635816, 1.6283601832010004));
points1.add(new GeoPoint(pm, 0.6664570999069251, 2.0855825542851574));
points1.add(new GeoPoint(pm, -0.23953537010974632, 1.8498724094352876));
BitSet p1bits = new BitSet();
c.addShape(new GeoConvexPolygon(pm, points1, p1bits, true));
List<GeoPoint> points2 = new ArrayList<>();
points2.add(new GeoPoint(pm, 1.1577814487635816, 1.6283601832010004));
points2.add(new GeoPoint(pm, -0.23953537010974632, 1.8498724094352876));
points2.add(new GeoPoint(pm, -1.1766904875978805, -2.1346828411344436));
BitSet p2bits = new BitSet();
p2bits.set(1, true);
c.addShape(new GeoConcavePolygon(pm, points2, p2bits, false));
//System.out.println(c);
GeoPoint point = new GeoPoint(pm, -0.9825762558001477, 2.4832136904725273);
GeoPoint quantizedPoint = new GeoPoint(-0.4505446160475436, 0.34850109186970535, -0.8539966368663765);
GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(pm,
-0.6107484000858642, -0.39518364125756916, -0.8568069517709872, 0.8568069517709872, -1.1431930485939341, 1.1431930485939341);
//System.out.println("relationship = "+xyzSolid.getRelationship(c));
assertTrue(xyzSolid.getRelationship(c) == GeoArea.OVERLAPS);
}
@Test
public void testPolygonFactoryCase1() {
/*
[junit4] 1> Initial points:
[junit4] 1> [X=-0.17279348371564082, Y=0.24422965662722748, Z=0.9521675605930696]
[junit4] 1> [X=-0.6385022730019092, Y=-0.6294493901210775, Z=0.4438687423720006]
[junit4] 1> [X=-0.9519561011293354, Y=-0.05324061687857965, Z=-0.30423702782227385]
[junit4] 1> [X=-0.30329807815178533, Y=-0.9447434167936289, Z=0.13262941042055737]
[junit4] 1> [X=-0.5367607140926697, Y=0.8179452639396644, Z=0.21163783898691005]
[junit4] 1> [X=0.39285411191111597, Y=0.6369575362013932, Z=0.6627439307500357]
[junit4] 1> [X=-0.44715655239362595, Y=0.8332957749253644, Z=0.3273923501593971]
[junit4] 1> [X=0.33024322515264537, Y=0.6945246730529289, Z=0.6387986432043298]
[junit4] 1> [X=-0.1699323603224724, Y=0.8516746480592872, Z=0.4963385521664198]
[junit4] 1> [X=0.2654788898359613, Y=0.7380222309164597, Z=0.6200740473100581]
[junit4] 1> For start plane, the following points are in/out:
[junit4] 1> [X=-0.17279348371564082, Y=0.24422965662722748, Z=0.9521675605930696] is: in
[junit4] 1> [X=-0.6385022730019092, Y=-0.6294493901210775, Z=0.4438687423720006] is: in
[junit4] 1> [X=-0.9519561011293354, Y=-0.05324061687857965, Z=-0.30423702782227385] is: out
[junit4] 1> [X=-0.30329807815178533, Y=-0.9447434167936289, Z=0.13262941042055737] is: in
[junit4] 1> [X=-0.5367607140926697, Y=0.8179452639396644, Z=0.21163783898691005] is: out
[junit4] 1> [X=0.39285411191111597, Y=0.6369575362013932, Z=0.6627439307500357] is: in
[junit4] 1> [X=-0.44715655239362595, Y=0.8332957749253644, Z=0.3273923501593971] is: out
[junit4] 1> [X=0.33024322515264537, Y=0.6945246730529289, Z=0.6387986432043298] is: in
[junit4] 1> [X=-0.1699323603224724, Y=0.8516746480592872, Z=0.4963385521664198] is: out
[junit4] 1> [X=0.2654788898359613, Y=0.7380222309164597, Z=0.6200740473100581] is: out
*/
final List<GeoPoint> points = new ArrayList<>();
points.add(new GeoPoint(0.17279348371564082, 0.24422965662722748, 0.9521675605930696));
points.add(new GeoPoint(-0.6385022730019092, -0.6294493901210775, 0.4438687423720006));
points.add(new GeoPoint(-0.9519561011293354, -0.05324061687857965, -0.30423702782227385));
points.add(new GeoPoint(-0.30329807815178533, -0.9447434167936289, 0.13262941042055737));
points.add(new GeoPoint(-0.5367607140926697, 0.8179452639396644, 0.21163783898691005));
points.add(new GeoPoint(0.39285411191111597, 0.6369575362013932, 0.6627439307500357));
points.add(new GeoPoint(-0.44715655239362595, 0.8332957749253644, 0.3273923501593971));
points.add(new GeoPoint(0.33024322515264537, 0.6945246730529289, 0.6387986432043298));
points.add(new GeoPoint(-0.1699323603224724, 0.8516746480592872, 0.4963385521664198));
points.add(new GeoPoint(0.2654788898359613, 0.7380222309164597, 0.6200740473100581));
boolean illegalArgumentException = false;
try {
final GeoPolygon p = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, null);
} catch (IllegalArgumentException e) {
illegalArgumentException = true;
}
assertTrue(illegalArgumentException);
}
@Test
public void testPolygonFactoryCase2() {
/*
[[lat=-0.48522750470337056, lon=-1.7370471071224087([X=-0.14644023172524287, Y=-0.8727091042681705, Z=-0.4665895520487907])],
[lat=-0.4252164254406539, lon=-1.0929282311747601([X=0.41916238097763436, Y=-0.8093435958043177, Z=-0.4127428785664968])],
[lat=0.2055150822737076, lon=0.8094775925193464([X=0.6760197133035871, Y=0.7093859395658346, Z=0.20427109186920892])],
[lat=-0.504360159046884, lon=-1.27628468850318([X=0.25421329462858633, Y=-0.8380671569889917, Z=-0.4834077932502288])],
[lat=-0.11994023948700858, lon=0.07857194136150605([X=0.9908123546871113, Y=0.07801065055912473, Z=-0.11978097184039621])],
[lat=0.39346633764155237, lon=1.306697331415816([X=0.24124272064589647, Y=0.8921189226448045, Z=0.3836311592666308])],
[lat=-0.07741593942416389, lon=0.5334693210962216([X=0.8594122640512101, Y=0.50755758923985, Z=-0.07742360418968308])],
[lat=0.4654236264787552, lon=1.3013260557429494([X=0.2380080413677112, Y=0.8617612419312584, Z=0.4489988990508502])],
[lat=-1.2964641581620537, lon=-1.487600369139357([X=0.022467282495493006, Y=-0.26942922375508405, Z=-0.960688317984634])]]
*/
final List<GeoPoint> points = new ArrayList<>();
points.add(new GeoPoint(PlanetModel.WGS84, -0.48522750470337056, -1.7370471071224087));
points.add(new GeoPoint(PlanetModel.WGS84, -0.4252164254406539, -1.0929282311747601));
points.add(new GeoPoint(PlanetModel.WGS84, 0.2055150822737076, 0.8094775925193464));
points.add(new GeoPoint(PlanetModel.WGS84, -0.504360159046884, -1.27628468850318));
points.add(new GeoPoint(PlanetModel.WGS84, -0.11994023948700858, 0.07857194136150605));
points.add(new GeoPoint(PlanetModel.WGS84, 0.39346633764155237, 1.306697331415816));
points.add(new GeoPoint(PlanetModel.WGS84, -0.07741593942416389, 0.5334693210962216));
points.add(new GeoPoint(PlanetModel.WGS84, 0.4654236264787552, 1.3013260557429494));
points.add(new GeoPoint(PlanetModel.WGS84, -1.2964641581620537, -1.487600369139357));
boolean illegalArgumentException = false;
try {
final GeoPolygon p = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, null);
} catch (IllegalArgumentException e) {
illegalArgumentException = true;
}
assertTrue(illegalArgumentException);
}
@Test
public void testPolygonFactoryCase3() {
/*
This one failed to be detected as convex:
[junit4] 1> convex part = GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
[[lat=0.39346633764155237, lon=1.306697331415816([X=0.24124272064589647, Y=0.8921189226448045, Z=0.3836311592666308])],
[lat=-0.4252164254406539, lon=-1.0929282311747601([X=0.41916238097763436, Y=-0.8093435958043177, Z=-0.4127428785664968])],
[lat=0.4654236264787552, lon=1.3013260557429494([X=0.2380080413677112, Y=0.8617612419312584, Z=0.4489988990508502])]], internalEdges={0, 1, 2}}
*/
final GeoPoint p3 = new GeoPoint(PlanetModel.WGS84, 0.39346633764155237, 1.306697331415816);
final GeoPoint p2 = new GeoPoint(PlanetModel.WGS84, -0.4252164254406539, -1.0929282311747601);
final GeoPoint p1 = new GeoPoint(PlanetModel.WGS84, 0.4654236264787552, 1.3013260557429494);
final List<GeoPoint> points = new ArrayList<>();
points.add(p3);
points.add(p2);
points.add(p1);
final BitSet internal = new BitSet();
final GeoCompositePolygon rval = new GeoCompositePolygon();
final GeoPolygonFactory.MutableBoolean mutableBoolean = new GeoPolygonFactory.MutableBoolean();
boolean result = GeoPolygonFactory.buildPolygonShape(rval, mutableBoolean, PlanetModel.WGS84, points, internal, 0, 1,
new SidedPlane(p1, p3, p2), new ArrayList<GeoPolygon>(), null);
assertFalse(mutableBoolean.value);
}
@Test
public void testPolygonFactoryCase4() {
// [[lat=0.897812132711355, lon=0.0025364171887532795([X=0.6227358672251874, Y=0.0015795213449218714, Z=0.7812318690127594])],
// [lat=0.897812132711355, lon=0.0025363997354607595([X=0.6227358672527552, Y=0.001579510476130618, Z=0.7812318690127594])],
// [lat=0.8978120628981849, lon=0.0025362601091206([X=0.6227359221556139, Y=0.0015794236644894651, Z=0.7812318257158789])]]
final GeoPoint p1 = new GeoPoint(PlanetModel.WGS84, 0.897812132711355, 0.0025364171887532795);
final GeoPoint p2 = new GeoPoint(PlanetModel.WGS84, 0.897812132711355, 0.0025363997354607595);
final GeoPoint p3 = new GeoPoint(PlanetModel.WGS84, 0.8978120628981849, 0.0025362601091206);
final List<GeoPoint> points = new ArrayList<>();
points.add(p1);
points.add(p2);
points.add(p3);
final List<GeoPolygonFactory.PolygonDescription> shapeList = new ArrayList<>();
final GeoPolygonFactory.PolygonDescription desc = new GeoPolygonFactory.PolygonDescription(points, new ArrayList<GeoPolygonFactory.PolygonDescription>());
shapeList.add(desc);
GeoPolygon p = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.WGS84, shapeList);
}
@Test
public void testPolygonFactoryCase5() {
/*
[junit4] 1> points=[[lat=0.0425265613312593, lon=0.0([X=1.0002076326868337, Y=0.0, Z=0.042561051669501374])],
[lat=0.8894380320379947, lon=-2.8993466885897496([X=-0.6109015457368775, Y=-0.1509528453728308, Z=0.7760109675775679])],
[lat=-0.8298163536994994, lon=-0.1462586594666574([X=0.6673285226073522, Y=-0.09830454048435874, Z=-0.7372817203741138])],
[lat=0.0, lon=-1.7156310907312492E-12([X=1.0011188539924791, Y=-1.7175506314267352E-12, Z=0.0])],
[lat=-0.7766317703682181, lon=3.141592653589793([X=-0.7128972529667801, Y=8.730473389667082E-17, Z=-0.7005064828988063])]]
{[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
[[lat=0.0425265613312593, lon=0.0([X=1.0002076326868337, Y=0.0, Z=0.042561051669501374])],
[lat=0.8894380320379947, lon=-2.8993466885897496([X=-0.6109015457368775, Y=-0.1509528453728308, Z=0.7760109675775679])],
[lat=-0.8298163536994994, lon=-0.1462586594666574([X=0.6673285226073522, Y=-0.09830454048435874, Z=-0.7372817203741138])],
[lat=0.0, lon=-1.7156310907312492E-12([X=1.0011188539924791, Y=-1.7175506314267352E-12, Z=0.0])]], internalEdges={3}},
GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
[[lat=0.0425265613312593, lon=0.0([X=1.0002076326868337, Y=0.0, Z=0.042561051669501374])],
[lat=0.0, lon=-1.7156310907312492E-12([X=1.0011188539924791, Y=-1.7175506314267352E-12, Z=0.0])],
[lat=-0.7766317703682181, lon=3.141592653589793([X=-0.7128972529667801, Y=8.730473389667082E-17, Z=-0.7005064828988063])]], internalEdges={0}}]}
*/
final GeoPoint p1 = new GeoPoint(PlanetModel.WGS84, 0.0425265613312593, 0.0);
final GeoPoint p2 = new GeoPoint(PlanetModel.WGS84, 0.8894380320379947, -2.8993466885897496);
final GeoPoint p3 = new GeoPoint(PlanetModel.WGS84, -0.8298163536994994, -0.1462586594666574);
final GeoPoint p4 = new GeoPoint(PlanetModel.WGS84, 0.0, -1.7156310907312492E-12);
final GeoPoint p5 = new GeoPoint(PlanetModel.WGS84, -0.7766317703682181, 3.141592653589793);
final List<GeoPoint> polyList = new ArrayList<>();
polyList.add(p1);
polyList.add(p2);
polyList.add(p3);
polyList.add(p4);
polyList.add(p5);
GeoPolygon p = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, polyList);
//System.out.println("p = "+p);
XYZBounds bounds = new XYZBounds();
p.getBounds(bounds);
XYZSolid solid = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84, bounds.getMinimumX(), bounds.getMaximumX(),
bounds.getMinimumY(), bounds.getMaximumY(),
bounds.getMinimumZ(), bounds.getMaximumZ());
//final List<GeoPoint> p1List = new ArrayList<>();
//p1List.add(p1);
//p1List.add(p2);
//p1List.add(p3);
//p1List.add(p4);
//final BitSet p1Internal = new BitSet();
//final GeoConvexPolygon poly1 = new GeoConvexPolygon(PlanetModel.WGS84, p1List, p1Internal, false);
/*
final List<GeoPoint> p2List = new ArrayList<>();
p2List.add(p1);
p2List.add(p4);
p2List.add(p5);
final BitSet p2Internal = new BitSet();
final GeoConvexPolygon poly2 = new GeoConvexPolygon(PlanetModel.WGS84, p2List, p2Internal, false);
*/
//XYZBounds bounds1 = new XYZBounds();
//poly1.getBounds(bounds1);
//XYZSolid solid1 = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84, bounds1.getMinimumX(), bounds1.getMaximumX(),
// bounds1.getMinimumY(), bounds1.getMaximumY(),
// bounds1.getMinimumZ(), bounds1.getMaximumZ());
/*
XYZBounds bounds2 = new XYZBounds();
poly2.getBounds(bounds2);
XYZSolid solid2 = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84, bounds2.getMinimumX(), bounds2.getMaximumX(),
bounds2.getMinimumY(), bounds2.getMaximumY(),
bounds2.getMinimumZ(), bounds2.getMaximumZ());
*/
final GeoPoint point = new GeoPoint(PlanetModel.WGS84, -0.41518838180529244, 3.141592653589793);
final GeoPoint encodedPoint = new GeoPoint(-0.9155623168963972, 2.3309121299774915E-10, -0.40359240449795253);
//System.out.println("point = "+point);
//System.out.println("encodedPoint = "+encodedPoint);
assertTrue(p.isWithin(point));
assertTrue(solid.isWithin(point));
//System.out.println("bounds1 = "+bounds1);
//System.out.println("bounds2 = "+bounds2);
//assertTrue(poly1.isWithin(point));
//assertTrue(poly2.isWithin(point));
//assertTrue(solid2.isWithin(point));
//assertTrue(poly2.isWithin(encodedPoint));
}
@Test
public void testLargePolygonFailureCase1() {
/*
[junit4] > shape=GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=65f193fc,
testPoint=[lat=1.3005550159098878, lon=-2.4043250791032897([X=-0.1972404544647752, Y=-0.17911237095124333, Z=0.9617794725902562])],
testPointInSet=false,
shapes={
{[lat=0.972005250702484, lon=-1.9776473855435277([X=-0.22278290030997686, Y=-0.5170266140533727, Z=0.8250470449472769])],
[lat=0.5530477484903267, lon=2.5300578442038137([X=-0.6968439858923609, Y=0.4886310878468911, Z=0.5253825248638686])],
[lat=1.5185372097372358, lon=-0.33848566616392867([X=0.04916162127975167, Y=-0.01730656055596007, Z=0.9964092501726799])]}}
[junit4] > bounds=XYZBounds: [xmin=-1.0011188544924792 xmax=0.04916162177975167 ymin=-1.0011188544924792 ymax=1.0011188544924792 zmin=-5.0E-10 zmax=0.99766957331525]
[junit4] > world bounds=( minX=-1.0011188539924791 maxX=1.0011188539924791 minY=-1.0011188539924791 maxY=1.0011188539924791 minZ=-0.9977622920221051 maxZ=0.9977622920221051
[junit4] > quantized point=[X=0.32866145093230836, Y=0.21519085912590594, Z=0.9177348472123349] within shape? true within bounds? false
[junit4] > unquantized point=[lat=1.166339260547107, lon=0.5797066870374205([X=0.3286614507856878, Y=0.21519085911319938, Z=0.9177348470779726])] within shape? true within bounds? false
[junit4] > docID=10 deleted?=false
[junit4] > query=PointInGeo3DShapeQuery: field=point: Shape: GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=65f193fc, testPoint=[lat=1.3005550159098878, lon=-2.4043250791032897([X=-0.1972404544647752, Y=-0.17911237095124333, Z=0.9617794725902562])], testPointInSet=false, shapes={ {[lat=0.972005250702484, lon=-1.9776473855435277([X=-0.22278290030997686, Y=-0.5170266140533727, Z=0.8250470449472769])], [lat=0.5530477484903267, lon=2.5300578442038137([X=-0.6968439858923609, Y=0.4886310878468911, Z=0.5253825248638686])], [lat=1.5185372097372358, lon=-0.33848566616392867([X=0.04916162127975167, Y=-0.01730656055596007, Z=0.9964092501726799])]}}
[junit4] > explanation:
[junit4] > target is in leaf _0(7.0.0):c13 of full reader StandardDirectoryReader(segments:3:nrt _0(7.0.0):c13)
[junit4] > full BKD path to target doc:
[junit4] > Cell(x=-0.9060562472023252 TO 1.0010658113048514 y=-0.5681445384324596 TO 0.7613281936331098 z=-0.43144274682272304 TO 0.9977622920582089); Shape relationship = OVERLAPS; Quantized point within cell = true; Unquantized point within cell = true
[junit4] > on cell Cell(x=-0.9060562472023252 TO 1.0010658113048514 y=-0.5681445384324596 TO 0.7613281936331098 z=-0.43144274682272304 TO 0.9977622920582089); Shape relationship = OVERLAPS; Quantized point within cell = true; Unquantized point within cell = true, wrapped visitor returned CELL_CROSSES_QUERY
[junit4] > leaf visit docID=10 x=0.32866145093230836 y=0.21519085912590594 z=0.9177348472123349
*/
final GeoPoint testPoint = new GeoPoint(PlanetModel.WGS84, 1.3005550159098878, -2.4043250791032897);
final boolean testPointInSet = false;
final List<GeoPoint> pointList = new ArrayList<>();
pointList.add(new GeoPoint(PlanetModel.WGS84, 0.972005250702484, -1.9776473855435277));
pointList.add(new GeoPoint(PlanetModel.WGS84, 0.5530477484903267, 2.5300578442038137));
pointList.add(new GeoPoint(PlanetModel.WGS84, 1.5185372097372358, -0.33848566616392867));
final GeoPolygon pSanity = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, pointList);
assertTrue(pSanity.isWithin(testPoint) == testPointInSet);
final List<List<GeoPoint>> shapeList = new ArrayList<>();
shapeList.add(pointList);
final GeoPolygon p = new GeoComplexPolygon(PlanetModel.WGS84, shapeList, testPoint, testPointInSet);
final GeoPoint intersectionPoint = new GeoPoint(0.26643017529034996, 0.0, 0.9617794725902564);
assertTrue(pSanity.isWithin(intersectionPoint) == p.isWithin(intersectionPoint));
assertTrue(p.isWithin(intersectionPoint));
final GeoPoint maxXPoint = new GeoPoint(PlanetModel.WGS84, 0.0, 0.0);
assertTrue(pSanity.isWithin(maxXPoint) == p.isWithin(maxXPoint));
final GeoPoint checkPoint = new GeoPoint(PlanetModel.WGS84, 1.166339260547107, 0.5797066870374205);
// Given the choice of test point, does this all make sense?
assertTrue(pSanity.isWithin(checkPoint) == p.isWithin(checkPoint));
final XYZBounds referenceBounds = new XYZBounds();
pSanity.getBounds(referenceBounds);
final XYZBounds actualBounds = new XYZBounds();
p.getBounds(actualBounds);
assertEquals(referenceBounds.getMinimumX(), actualBounds.getMinimumX(), 0.0000001);
assertEquals(referenceBounds.getMaximumX(), actualBounds.getMaximumX(), 0.0000001);
assertEquals(referenceBounds.getMinimumY(), actualBounds.getMinimumY(), 0.0000001);
assertEquals(referenceBounds.getMaximumY(), actualBounds.getMaximumY(), 0.0000001);
assertEquals(referenceBounds.getMinimumZ(), actualBounds.getMinimumZ(), 0.0000001);
assertEquals(referenceBounds.getMaximumZ(), actualBounds.getMaximumZ(), 0.0000001);
}
@Test
public void testLargePolygonFailureCase2() {
/*
[junit4] > Throwable #1: java.lang.AssertionError: FAIL: id=2 should have matched but did not
[junit4] > shape=GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=6eccd33b,
testPoint=[lat=0.03170690566178683, lon=1.0862414976732029([X=0.46609969117964495, Y=0.8854242006628827, Z=0.0317369552646047])],
testPointInSet=false,
shapes={ {
[lat=1.0774842300167298, lon=-0.11534121538553185([X=0.46969930266058374, Y=-0.054417217622152375, Z=0.8794587218580684])],
[lat=0.05101544777239065, lon=1.031558236908661([X=0.5133835679471972, Y=0.8579350866926241, Z=0.051049928818862174])],
[lat=-0.011222928649880962, lon=1.5851249038356199([X=-0.01434320835886277, Y=1.0009526216234983, Z=-0.011235244842183226])],
[lat=-0.02571365137215876, lon=0.5627875521419741([X=0.8464356149277266, Y=0.5339650936800929, Z=-0.025739527171261035])],
[lat=0.03833766792865358, lon=1.0082901344798614([X=0.5335096521470836, Y=0.8462411929752105, Z=0.03837097111317845])],
[lat=0.1719054969347345, lon=0.9024290407832926([X=0.6111941952395734, Y=0.7740553755547761, Z=0.17123457719021212])],
[lat=0.08180947807010808, lon=1.0107147265848113([X=0.5300590148023426, Y=0.8453039531721928, Z=0.08180784289673602])]}}
[junit4] > bounds=XYZBounds: [xmin=-1.0011188544924792 xmax=1.0011188544924792
ymin=-1.0011188544924792 ymax=1.0011188544924792
zmin=-0.025739527671261034 zmax=0.9977622925221051]
[junit4] > world bounds=( minX=-1.0011188539924791 maxX=1.0011188539924791 minY=-1.0011188539924791 maxY=1.0011188539924791 minZ=-0.9977622920221051 maxZ=0.9977622920221051
[junit4] > quantized point=[X=-0.477874179571219, Y=0.5908091335156603, Z=-0.6495967142221521] within shape? true within bounds? false
[junit4] > unquantized point=[lat=-0.7073124559987376, lon=2.2509085326629887([X=-0.47787417938801546, Y=0.5908091336704123, Z=-0.6495967140640758])] within shape? true within bounds? false
[junit4] > docID=2 deleted?=false
[junit4] > query=PointInGeo3DShapeQuery: field=point: Shape: GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=6eccd33b, testPoint=[lat=0.03170690566178683, lon=1.0862414976732029([X=0.46609969117964495, Y=0.8854242006628827, Z=0.0317369552646047])], testPointInSet=false, shapes={ {[lat=1.0774842300167298, lon=-0.11534121538553185([X=0.46969930266058374, Y=-0.054417217622152375, Z=0.8794587218580684])], [lat=0.05101544777239065, lon=1.031558236908661([X=0.5133835679471972, Y=0.8579350866926241, Z=0.051049928818862174])], [lat=-0.011222928649880962, lon=1.5851249038356199([X=-0.01434320835886277, Y=1.0009526216234983, Z=-0.011235244842183226])], [lat=-0.02571365137215876, lon=0.5627875521419741([X=0.8464356149277266, Y=0.5339650936800929, Z=-0.025739527171261035])], [lat=0.03833766792865358, lon=1.0082901344798614([X=0.5335096521470836, Y=0.8462411929752105, Z=0.03837097111317845])], [lat=0.1719054969347345, lon=0.9024290407832926([X=0.6111941952395734, Y=0.7740553755547761, Z=0.17123457719021212])], [lat=0.08180947807010808, lon=1.0107147265848113([X=0.5300590148023426, Y=0.8453039531721928, Z=0.08180784289673602])]}}
[junit4] > explanation:
[junit4] > target is in leaf _0(7.0.0):C11 of full reader StandardDirectoryReader(segments:3:nrt _0(7.0.0):C11)
[junit4] > full BKD path to target doc:
[junit4] > Cell(x=-0.8906255176936849 TO 1.0005089994430834 y=-0.6808995306272861 TO 0.9675171153117977 z=-0.997762292058209 TO 0.9939318087373729); Shape relationship = OVERLAPS; Quantized point within cell = true; Unquantized point within cell = true
[junit4] > on cell Cell(x=-0.8906255176936849 TO 1.0005089994430834 y=-0.6808995306272861 TO 0.9675171153117977 z=-0.997762292058209 TO 0.9939318087373729); Shape relationship = OVERLAPS; Quantized point within cell = true; Unquantized point within cell = true, wrapped visitor returned CELL_CROSSES_QUERY
[junit4] > leaf visit docID=2 x=-0.477874179571219 y=0.5908091335156603 z=-0.6495967142221521
*/
final GeoPoint testPoint = new GeoPoint(PlanetModel.WGS84, 0.03170690566178683, 1.0862414976732029);
final boolean testPointInSet = false;
final List<GeoPoint> pointList = new ArrayList<>();
// If the 1.07748... line is at the top, the bounds are correct and the test succeeds.
// If this line is at the bottom, though, the bounds are wrong and the test fails.
//pointList.add(new GeoPoint(PlanetModel.WGS84, 1.0774842300167298, -0.11534121538553185));
pointList.add(new GeoPoint(PlanetModel.WGS84, 0.05101544777239065, 1.031558236908661));
pointList.add(new GeoPoint(PlanetModel.WGS84, -0.011222928649880962, 1.5851249038356199));
pointList.add(new GeoPoint(PlanetModel.WGS84, -0.02571365137215876, 0.5627875521419741));
pointList.add(new GeoPoint(PlanetModel.WGS84, 0.03833766792865358, 1.0082901344798614));
pointList.add(new GeoPoint(PlanetModel.WGS84, 0.1719054969347345, 0.9024290407832926));
pointList.add(new GeoPoint(PlanetModel.WGS84, 0.08180947807010808, 1.0107147265848113));
pointList.add(new GeoPoint(PlanetModel.WGS84, 1.0774842300167298, -0.11534121538553185));
final GeoPolygon pSanity = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, pointList);
assertTrue(pSanity.isWithin(testPoint) == testPointInSet);
final List<List<GeoPoint>> shapeList = new ArrayList<>();
shapeList.add(pointList);
final GeoPolygon p = new GeoComplexPolygon(PlanetModel.WGS84, shapeList, testPoint, testPointInSet);
//System.err.println(p);
/*
[junit4] 2> GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=dcf3e99,
testPoint=[lat=0.03170690566178683, lon=1.0862414976732029([X=0.46609969117964506, Y=0.8854242006628825, Z=0.0317369552646047])],
testPointInSet=false,
shapes={ {
[lat=1.0774842300167298, lon=-0.11534121538553185([X=0.46969930266058374, Y=-0.054417217622152375, Z=0.8794587218580684])],
[lat=0.05101544777239065, lon=1.031558236908661([X=0.5133835679471972, Y=0.8579350866926241, Z=0.051049928818862174])],
[lat=-0.011222928649880962, lon=1.5851249038356199([X=-0.01434320835886277, Y=1.0009526216234983, Z=-0.011235244842183226])],
[lat=-0.02571365137215876, lon=0.5627875521419741([X=0.8464356149277266, Y=0.5339650936800929, Z=-0.025739527171261035])],
[lat=0.03833766792865358, lon=1.0082901344798614([X=0.5335096521470836, Y=0.8462411929752105, Z=0.03837097111317845])],
[lat=0.1719054969347345, lon=0.9024290407832926([X=0.6111941952395734, Y=0.7740553755547761, Z=0.17123457719021212])]}}
[lat=0.08180947807010808, lon=1.0107147265848113([X=0.5300590148023426, Y=0.8453039531721928, Z=0.08180784289673602])],
*/
final XYZBounds referenceBounds = new XYZBounds();
pSanity.getBounds(referenceBounds);
final XYZBounds actualBounds = new XYZBounds();
p.getBounds(actualBounds);
assertEquals(referenceBounds.getMinimumX(), actualBounds.getMinimumX(), 0.0000001);
assertEquals(referenceBounds.getMaximumX(), actualBounds.getMaximumX(), 0.0000001);
assertEquals(referenceBounds.getMinimumY(), actualBounds.getMinimumY(), 0.0000001);
assertEquals(referenceBounds.getMaximumY(), actualBounds.getMaximumY(), 0.0000001);
assertEquals(referenceBounds.getMinimumZ(), actualBounds.getMinimumZ(), 0.0000001);
assertEquals(referenceBounds.getMaximumZ(), actualBounds.getMaximumZ(), 0.0000001);
final XYZSolid solid = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84,
actualBounds.getMinimumX(), actualBounds.getMaximumX(),
actualBounds.getMinimumY(), actualBounds.getMaximumY(),
actualBounds.getMinimumZ(), actualBounds.getMaximumZ());
final GeoPoint checkPoint = new GeoPoint(PlanetModel.WGS84, -0.7073124559987376, 2.2509085326629887);
// Given the choice of test point, does this all make sense?
assertTrue(pSanity.isWithin(checkPoint) == p.isWithin(checkPoint));
assertTrue(p.isWithin(checkPoint));
assertTrue(solid.isWithin(checkPoint));
}
@Test
public void testPolygonFailureCase1() {
final List<GeoPoint> poly2List = new ArrayList<>();
poly2List.add(new GeoPoint(PlanetModel.WGS84, -0.6370451769779303, 2.5318373679431616));
poly2List.add(new GeoPoint(PlanetModel.WGS84, 1.5707963267948966, -3.141592653589793));
poly2List.add(new GeoPoint(PlanetModel.WGS84, -1.0850383189690824, 2.4457272005608357E-47));
poly2List.add(new GeoPoint(PlanetModel.WGS84, -0.5703530503197992, -3.141592653589793));
final BitSet poly2Bitset = new BitSet();
poly2Bitset.set(1);
boolean result;
try {
final GeoConvexPolygon poly2 = new GeoConvexPolygon(PlanetModel.WGS84, poly2List);
result = true;
} catch (IllegalArgumentException e) {
result = false;
}
assertTrue(!result);
}
@Test
public void testPolygonFailureCase2() {
/*
[junit4] 1> shape=GeoCompositeMembershipShape: {[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=[
[lat=1.079437865394857, lon=-1.720224083538152E-11([X=0.47111944719262044, Y=-8.104310192839264E-12, Z=0.8803759987367299])],
[lat=-1.5707963267948966, lon=0.017453291479645996([X=6.108601474971234E-17, Y=1.066260290095308E-18, Z=-0.997762292022105])],
[lat=0.017453291479645996, lon=2.4457272005608357E-47([X=1.0009653513901666, Y=2.448088186713865E-47, Z=0.01747191415779267])]], internalEdges={2}},
GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=[
[lat=1.079437865394857, lon=-1.720224083538152E-11([X=0.47111944719262044, Y=-8.104310192839264E-12, Z=0.8803759987367299])],
[lat=0.017453291479645996, lon=2.4457272005608357E-47([X=1.0009653513901666, Y=2.448088186713865E-47, Z=0.01747191415779267])],
[lat=0.0884233366943164, lon=0.4323234231678824([X=0.9054355304510789, Y=0.4178006803188124, Z=0.08840463683725623])]], internalEdges={0}}]}
*/
final List<GeoPoint> poly1List = new ArrayList<>();
poly1List.add(new GeoPoint(PlanetModel.WGS84, 1.079437865394857, -1.720224083538152E-11));
poly1List.add(new GeoPoint(PlanetModel.WGS84, -1.5707963267948966, 0.017453291479645996));
poly1List.add(new GeoPoint(PlanetModel.WGS84, 0.017453291479645996, 2.4457272005608357E-47));
final GeoConvexPolygon poly1 = new GeoConvexPolygon(PlanetModel.WGS84, poly1List);
/*
[junit4] 1> unquantized=[lat=-1.5316724989005415, lon=3.141592653589793([X=-0.03902652216795768, Y=4.779370545484258E-18, Z=-0.9970038705813589])]
[junit4] 1> quantized=[X=-0.03902652216283731, Y=2.3309121299774915E-10, Z=-0.9970038706538652]
*/
final GeoPoint point = new GeoPoint(PlanetModel.WGS84, -1.5316724989005415, 3.141592653589793);
assertTrue(poly1.isWithin(point));
final XYZBounds actualBounds1 = new XYZBounds();
poly1.getBounds(actualBounds1);
final XYZSolid solid = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84,
actualBounds1.getMinimumX(), actualBounds1.getMaximumX(),
actualBounds1.getMinimumY(), actualBounds1.getMaximumY(),
actualBounds1.getMinimumZ(), actualBounds1.getMaximumZ());
assertTrue(solid.isWithin(point));
}
}