You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2015/04/22 16:47:01 UTC
svn commit: r1675374 [1/2] - in
/lucene/dev/branches/lucene6196/lucene/spatial/src:
java/org/apache/lucene/spatial/spatial4j/geo3d/
test/org/apache/lucene/spatial/spatial4j/
Author: dsmiley
Date: Wed Apr 22 14:47:00 2015
New Revision: 1675374
URL: http://svn.apache.org/r1675374
Log:
LUCENE-6196: committing Karl's latest patch
https://reviews.apache.org/r/33353/ (diff #9) https://reviews.apache.org/r/33353/diff/raw/
Added:
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java (with props)
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java (with props)
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java (with props)
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java (with props)
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java (with props)
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java (with props)
Modified:
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxBase.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxFactory.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseExtendedShape.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java
lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java
lucene/dev/branches/lucene6196/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxBase.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxBase.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxBase.java Wed Apr 22 14:47:00 2015
@@ -22,6 +22,9 @@ package org.apache.lucene.spatial.spatia
*/
public abstract class GeoBBoxBase implements GeoBBox {
+ protected final static GeoPoint NORTH_POLE = new GeoPoint(0.0,0.0,1.0);
+ protected final static GeoPoint SOUTH_POLE = new GeoPoint(0.0,0.0,-1.0);
+
@Override
public abstract boolean isWithin(final Vector point);
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxFactory.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxFactory.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxFactory.java Wed Apr 22 14:47:00 2015
@@ -30,6 +30,7 @@ public class GeoBBoxFactory
*@return a GeoBBox corresponding to what was specified.
*/
public static GeoBBox makeGeoBBox(double topLat, double bottomLat, double leftLon, double rightLon) {
+ //System.err.println("Making rectangle for topLat="+topLat*180.0/Math.PI+", bottomLat="+bottomLat*180.0/Math.PI+", leftLon="+leftLon*180.0/Math.PI+", rightlon="+rightLon*180.0/Math.PI);
if (topLat > Math.PI * 0.5)
topLat = Math.PI * 0.5;
if (bottomLat < -Math.PI * 0.5)
@@ -41,10 +42,18 @@ public class GeoBBoxFactory
if (leftLon == -Math.PI && rightLon == Math.PI) {
if (topLat == Math.PI * 0.5 && bottomLat == -Math.PI * 0.5)
return new GeoWorld();
- if (topLat == bottomLat)
+ if (topLat == bottomLat) {
+ if (topLat == Math.PI * 0.5 || topLat == -Math.PI * 0.5)
+ return new GeoDegeneratePoint(topLat,0.0);
return new GeoDegenerateLatitudeZone(topLat);
+ }
+ if (topLat == Math.PI * 0.5)
+ return new GeoNorthLatitudeZone(bottomLat);
+ else if (bottomLat == -Math.PI * 0.5)
+ return new GeoSouthLatitudeZone(topLat);
return new GeoLatitudeZone(topLat, bottomLat);
}
+ //System.err.println(" not latitude zone");
double extent = rightLon - leftLon;
if (extent < 0.0)
extent += Math.PI * 2.0;
@@ -57,19 +66,36 @@ public class GeoBBoxFactory
return new GeoLongitudeSlice(leftLon, rightLon);
}
+ //System.err.println(" not longitude slice");
if (leftLon == rightLon) {
if (topLat == bottomLat)
return new GeoDegeneratePoint(topLat, leftLon);
return new GeoDegenerateVerticalLine(topLat, bottomLat, leftLon);
}
+ //System.err.println(" not vertical line");
if (extent >= Math.PI) {
if (topLat == bottomLat) {
+ //System.err.println(" wide degenerate line");
return new GeoWideDegenerateHorizontalLine(topLat, leftLon, rightLon);
}
+ if (topLat == Math.PI * 0.5) {
+ return new GeoWideNorthRectangle(bottomLat, leftLon, rightLon);
+ } else if (bottomLat == -Math.PI * 0.5) {
+ return new GeoWideSouthRectangle(topLat, leftLon, rightLon);
+ }
+ //System.err.println(" wide rect");
return new GeoWideRectangle(topLat, bottomLat, leftLon, rightLon);
}
- if (topLat == bottomLat)
+ if (topLat == bottomLat) {
+ //System.err.println(" horizontal line");
return new GeoDegenerateHorizontalLine(topLat, leftLon, rightLon);
+ }
+ if (topLat == Math.PI * 0.5) {
+ return new GeoNorthRectangle(bottomLat, leftLon, rightLon);
+ } else if (bottomLat == -Math.PI * 0.5) {
+ return new GeoSouthRectangle(topLat, leftLon, rightLon);
+ }
+ //System.err.println(" rectangle");
return new GeoRectangle(topLat, bottomLat, leftLon, rightLon);
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseExtendedShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseExtendedShape.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseExtendedShape.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseExtendedShape.java Wed Apr 22 14:47:00 2015
@@ -59,7 +59,7 @@ public abstract class GeoBaseExtendedSha
*@return true if there's such an intersection, false if not.
*/
@Override
- public abstract boolean intersects(final Plane plane, final Membership... bounds);
+ public abstract boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds);
/** Compute longitude/latitude bounds for the shape.
*@param bounds is the optional input bounds object. If this is null,
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java Wed Apr 22 14:47:00 2015
@@ -27,6 +27,7 @@ public class GeoCircle extends GeoBaseEx
public final double cutoffLinearDistance;
public final SidedPlane circlePlane;
public final GeoPoint[] edgePoints;
+ public static final GeoPoint[] circlePoints = new GeoPoint[0];
public GeoCircle(final double lat, final double lon, final double cutoffAngle)
{
@@ -35,7 +36,7 @@ public class GeoCircle extends GeoBaseEx
throw new IllegalArgumentException("Latitude out of bounds");
if (lon < -Math.PI || lon > Math.PI)
throw new IllegalArgumentException("Longitude out of bounds");
- if (cutoffAngle < 0.0 || cutoffAngle > Math.PI)
+ if (cutoffAngle <= 0.0 || cutoffAngle > Math.PI)
throw new IllegalArgumentException("Cutoff angle out of bounds");
final double sinAngle = Math.sin(cutoffAngle);
final double cosAngle = Math.cos(cutoffAngle);
@@ -47,9 +48,25 @@ public class GeoCircle extends GeoBaseEx
this.cutoffAngle = cutoffAngle;
this.circlePlane = new SidedPlane(center, center, -cosAngle);
- // Compute a point on the circle boundary. This can be any point that is easy to compute.
- // This requires some math, so I've implemented it in Plane.
- this.edgePoints = new GeoPoint[]{center.getSamplePoint(sinAngle,cosAngle)};
+ // Compute a point on the circle boundary.
+ if (cutoffAngle == Math.PI)
+ this.edgePoints = new GeoPoint[0];
+ else {
+ // Move from center only in latitude. Then, if we go past the north pole, adjust the longitude also.
+ double newLat = lat + cutoffAngle;
+ double newLon = lon;
+ if (newLat > Math.PI * 0.5) {
+ newLat = Math.PI - newLat;
+ newLon += Math.PI;
+ }
+ while (newLon > Math.PI) {
+ newLon -= Math.PI * 2.0;
+ }
+ final GeoPoint edgePoint = new GeoPoint(newLat,newLon);
+ //if (Math.abs(circlePlane.evaluate(edgePoint)) > 1e-10)
+ // throw new RuntimeException("Computed an edge point that does not satisfy circlePlane equation! "+circlePlane.evaluate(edgePoint));
+ this.edgePoints = new GeoPoint[]{edgePoint};
+ }
}
@Override
@@ -170,8 +187,6 @@ public class GeoCircle extends GeoBaseEx
@Override
public boolean isWithin(final Vector point)
{
- if (point == null)
- return false;
// Fastest way of determining membership
return circlePlane.isWithin(point);
}
@@ -190,9 +205,9 @@ public class GeoCircle extends GeoBaseEx
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return circlePlane.intersects(p, bounds);
+ return circlePlane.intersects(p, notablePoints, circlePoints, bounds);
}
/** Compute longitude/latitude bounds for the shape.
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java Wed Apr 22 14:47:00 2015
@@ -63,10 +63,10 @@ public class GeoCompositeMembershipShape
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
for (GeoMembershipShape shape : shapes) {
- if (shape.intersects(p,bounds))
+ if (shape.intersects(p,notablePoints,bounds))
return true;
}
return false;
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java Wed Apr 22 14:47:00 2015
@@ -33,6 +33,7 @@ public class GeoConvexPolygon extends Ge
protected SidedPlane[] edges = null;
protected boolean[] internalEdges = null;
+ protected GeoPoint[][] notableEdgePoints = null;
protected GeoPoint[] edgePoints = null;
@@ -98,6 +99,7 @@ public class GeoConvexPolygon extends Ge
throw new IllegalArgumentException("Polygon needs at least three points.");
// Time to construct the planes. If the polygon is truly convex, then any adjacent point
edges = new SidedPlane[points.size()];
+ notableEdgePoints = new GeoPoint[points.size()][];
internalEdges = new boolean[points.size()];
// to a segment can provide an interior measurement.
for (int i = 0; i < points.size(); i++) {
@@ -108,6 +110,7 @@ public class GeoConvexPolygon extends Ge
final SidedPlane sp = new SidedPlane(check,start,end);
//System.out.println("Created edge "+sp+" using start="+start+" end="+end+" check="+check);
edges[i] = sp;
+ notableEdgePoints[i] = new GeoPoint[]{start,end};
internalEdges[i] = isInternalEdge;
}
createCenterPoint();
@@ -163,11 +166,14 @@ public class GeoConvexPolygon extends Ge
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
+ //System.err.println("Checking for polygon intersection with plane "+p+"...");
for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
final SidedPlane edge = edges[edgeIndex];
+ final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
if (!internalEdges[edgeIndex]) {
+ //System.err.println(" non-internal edge "+edge);
// Edges flagged as 'internal only' are excluded from the matching
// Construct boundaries
final Membership[] membershipBounds = new Membership[edges.length-1];
@@ -177,10 +183,13 @@ public class GeoConvexPolygon extends Ge
membershipBounds[count++] = edges[otherIndex];
}
}
- if (edge.intersects(p,bounds,membershipBounds))
+ if (edge.intersects(p,notablePoints, points, bounds,membershipBounds)) {
+ //System.err.println(" intersects!");
return true;
+ }
}
}
+ //System.err.println(" no intersection");
return false;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java Wed Apr 22 14:47:00 2015
@@ -33,7 +33,9 @@ public class GeoDegenerateHorizontalLine
public final Plane plane;
public final SidedPlane leftPlane;
public final SidedPlane rightPlane;
-
+
+ public final GeoPoint[] planePoints;
+
public final GeoPoint centerPoint;
public final GeoPoint[] edgePoints;
@@ -83,6 +85,8 @@ public class GeoDegenerateHorizontalLine
this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
+ this.planePoints = new GeoPoint[]{LHC,RHC};
+
this.edgePoints = new GeoPoint[]{centerPoint};
}
@@ -107,7 +111,7 @@ public class GeoDegenerateHorizontalLine
@Override
public boolean isWithin(final Vector point)
{
- return plane.evaluate(point) == 0.0 &&
+ return plane.evaluateIsZero(point) &&
leftPlane.isWithin(point) &&
rightPlane.isWithin(point);
}
@@ -115,7 +119,7 @@ public class GeoDegenerateHorizontalLine
@Override
public boolean isWithin(final double x, final double y, final double z)
{
- return plane.evaluate(x,y,z) == 0.0 &&
+ return plane.evaluateIsZero(x,y,z) &&
leftPlane.isWithin(x,y,z) &&
rightPlane.isWithin(x,y,z);
}
@@ -135,9 +139,9 @@ public class GeoDegenerateHorizontalLine
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(plane,bounds,leftPlane,rightPlane);
+ return p.intersects(plane,notablePoints,planePoints,bounds,leftPlane,rightPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -158,7 +162,7 @@ public class GeoDegenerateHorizontalLine
@Override
public int getRelationship(final GeoShape path) {
- if (path.intersects(plane,leftPlane,rightPlane))
+ if (path.intersects(plane,planePoints,leftPlane,rightPlane))
return OVERLAPS;
if (path.isWithin(centerPoint))
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java Wed Apr 22 14:47:00 2015
@@ -28,6 +28,7 @@ public class GeoDegenerateLatitudeZone e
public final Plane plane;
public final GeoPoint interiorPoint;
public final GeoPoint[] edgePoints;
+ public final static GeoPoint[] planePoints = new GeoPoint[0];
public GeoDegenerateLatitudeZone(final double latitude)
{
@@ -36,7 +37,6 @@ public class GeoDegenerateLatitudeZone e
this.sinLatitude = Math.sin(latitude);
double cosLatitude = Math.cos(latitude);
this.plane = new Plane(sinLatitude);
-
// Compute an interior point.
interiorPoint = new GeoPoint(cosLatitude,0.0,sinLatitude);
edgePoints = new GeoPoint[]{interiorPoint};
@@ -53,13 +53,13 @@ public class GeoDegenerateLatitudeZone e
@Override
public boolean isWithin(final Vector point)
{
- return point.z == this.sinLatitude;
+ return Math.abs(point.z - this.sinLatitude) < 1e-10;
}
@Override
public boolean isWithin(final double x, final double y, final double z)
{
- return z == this.sinLatitude;
+ return Math.abs(z - this.sinLatitude) < 1e-10;
}
@Override
@@ -75,9 +75,9 @@ public class GeoDegenerateLatitudeZone e
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(plane,bounds);
+ return p.intersects(plane,notablePoints,planePoints,bounds);
}
/** Compute longitude/latitude bounds for the shape.
@@ -102,7 +102,7 @@ public class GeoDegenerateLatitudeZone e
// work with no area endpoints. So we rely entirely on intersections.
//System.out.println("Got here! latitude="+latitude+" path="+path);
- if (path.intersects(plane)) {
+ if (path.intersects(plane,planePoints)) {
return OVERLAPS;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java Wed Apr 22 14:47:00 2015
@@ -30,6 +30,8 @@ public class GeoDegenerateLongitudeSlice
public final GeoPoint interiorPoint;
public final GeoPoint[] edgePoints;
+ public final static GeoPoint[] planePoints = new GeoPoint[]{NORTH_POLE,SOUTH_POLE};
+
/** Accepts only values in the following ranges: lon: {@code -PI -> PI} */
public GeoDegenerateLongitudeSlice(final double longitude)
{
@@ -65,14 +67,14 @@ public class GeoDegenerateLongitudeSlice
@Override
public boolean isWithin(final Vector point)
{
- return plane.evaluate(point) == 0.0 &&
+ return plane.evaluateIsZero(point) &&
boundingPlane.isWithin(point);
}
@Override
public boolean isWithin(final double x, final double y, final double z)
{
- return plane.evaluate(x,y,z) == 0.0 &&
+ return plane.evaluateIsZero(x,y,z) &&
boundingPlane.isWithin(x,y,z);
}
@@ -89,9 +91,9 @@ public class GeoDegenerateLongitudeSlice
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(plane,bounds,boundingPlane);
+ return p.intersects(plane,notablePoints,planePoints,bounds,boundingPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -114,7 +116,7 @@ public class GeoDegenerateLongitudeSlice
@Override
public int getRelationship(final GeoShape path) {
// Look for intersections.
- if (path.intersects(plane,boundingPlane))
+ if (path.intersects(plane,planePoints,boundingPlane))
return OVERLAPS;
if (path.isWithin(interiorPoint))
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java Wed Apr 22 14:47:00 2015
@@ -64,7 +64,7 @@ public class GeoDegeneratePoint extends
*@return true if there's such an intersection, false if not.
*/
@Override
- public boolean intersects(final Plane plane, final Membership... bounds) {
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
if (plane.evaluate(this) == 0.0)
return false;
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java Wed Apr 22 14:47:00 2015
@@ -32,7 +32,9 @@ public class GeoDegenerateVerticalLine e
public final SidedPlane bottomPlane;
public final SidedPlane boundingPlane;
public final Plane plane;
-
+
+ public final GeoPoint[] planePoints;
+
public final GeoPoint centerPoint;
public final GeoPoint[] edgePoints;
@@ -77,6 +79,8 @@ public class GeoDegenerateVerticalLine e
this.boundingPlane = new SidedPlane(centerPoint,-sinLongitude,cosLongitude);
+ this.planePoints = new GeoPoint[]{UHC,LHC};
+
this.edgePoints = new GeoPoint[]{centerPoint};
}
@@ -98,7 +102,7 @@ public class GeoDegenerateVerticalLine e
@Override
public boolean isWithin(final Vector point)
{
- return plane.evaluate(point) == 0.0 &&
+ return plane.evaluateIsZero(point) &&
boundingPlane.isWithin(point) &&
topPlane.isWithin(point) &&
bottomPlane.isWithin(point);
@@ -107,7 +111,7 @@ public class GeoDegenerateVerticalLine e
@Override
public boolean isWithin(final double x, final double y, final double z)
{
- return plane.evaluate(x,y,z) == 0.0 &&
+ return plane.evaluateIsZero(x,y,z) &&
boundingPlane.isWithin(x,y,z) &&
topPlane.isWithin(x,y,z) &&
bottomPlane.isWithin(x,y,z);
@@ -131,9 +135,9 @@ public class GeoDegenerateVerticalLine e
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(plane,bounds,boundingPlane,topPlane,bottomPlane);
+ return p.intersects(plane,notablePoints,planePoints,bounds,boundingPlane,topPlane,bottomPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -155,12 +159,18 @@ public class GeoDegenerateVerticalLine e
@Override
public int getRelationship(final GeoShape path) {
- if (path.intersects(plane,boundingPlane,topPlane,bottomPlane))
+ //System.err.println(this+" relationship to "+path);
+ if (path.intersects(plane,planePoints,boundingPlane,topPlane,bottomPlane)) {
+ //System.err.println(" overlaps");
return OVERLAPS;
+ }
- if (path.isWithin(centerPoint))
+ if (path.isWithin(centerPoint)) {
+ //System.err.println(" contains");
return CONTAINS;
+ }
+ //System.err.println(" disjoint");
return DISJOINT;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java Wed Apr 22 14:47:00 2015
@@ -28,6 +28,7 @@ public class GeoLatitudeZone extends Geo
public final SidedPlane topPlane;
public final SidedPlane bottomPlane;
public final GeoPoint interiorPoint;
+ public final static GeoPoint[] planePoints = new GeoPoint[0];
// We need two additional points because a latitude zone's boundaries don't intersect. This is a very
// special case that most GeoBBox's do not have.
@@ -106,10 +107,10 @@ public class GeoLatitudeZone extends Geo
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(topPlane,bounds,bottomPlane) ||
- p.intersects(bottomPlane,bounds,topPlane);
+ return p.intersects(topPlane,notablePoints,planePoints,bounds,bottomPlane) ||
+ p.intersects(bottomPlane,notablePoints,planePoints,bounds,topPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -149,8 +150,8 @@ public class GeoLatitudeZone extends Geo
// 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,bottomPlane) ||
- path.intersects(bottomPlane,topPlane))
+ 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
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java Wed Apr 22 14:47:00 2015
@@ -29,9 +29,11 @@ public class GeoLongitudeSlice extends G
public final SidedPlane leftPlane;
public final SidedPlane rightPlane;
+ public final static GeoPoint[] planePoints = new GeoPoint[]{NORTH_POLE,SOUTH_POLE};
+
public final GeoPoint centerPoint;
- public final GeoPoint northPole = new GeoPoint(0.0,0.0,1.0);
- public final GeoPoint[] edgePoints = new GeoPoint[]{northPole};
+
+ public final static GeoPoint[] edgePoints = new GeoPoint[]{NORTH_POLE};
/** Accepts only values in the following ranges: lon: {@code -PI -> PI} */
public GeoLongitudeSlice(final double leftLon, double rightLon)
@@ -115,10 +117,10 @@ public class GeoLongitudeSlice extends G
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(leftPlane,bounds,rightPlane) ||
- p.intersects(rightPlane,bounds,leftPlane);
+ return p.intersects(leftPlane,notablePoints,planePoints,bounds,rightPlane) ||
+ p.intersects(rightPlane,notablePoints,planePoints,bounds,leftPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -144,13 +146,13 @@ public class GeoLongitudeSlice extends G
if (insideRectangle == SOME_INSIDE)
return OVERLAPS;
- final boolean insideShape = path.isWithin(northPole);
+ final boolean insideShape = path.isWithin(NORTH_POLE);
if (insideRectangle == ALL_INSIDE && insideShape)
return OVERLAPS;
- if (path.intersects(leftPlane,rightPlane) ||
- path.intersects(rightPlane,leftPlane)) {
+ if (path.intersects(leftPlane,planePoints,rightPlane) ||
+ path.intersects(rightPlane,planePoints,leftPlane)) {
return OVERLAPS;
}
Added: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java?rev=1675374&view=auto
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java (added)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java Wed Apr 22 14:47:00 2015
@@ -0,0 +1,171 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * 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.
+ */
+
+/** This GeoBBox represents an area rectangle limited only in south latitude.
+*/
+public class GeoNorthLatitudeZone extends GeoBBoxBase
+{
+ public final double bottomLat;
+ public final double cosBottomLat;
+ public final SidedPlane bottomPlane;
+ public final GeoPoint interiorPoint;
+ public final static GeoPoint[] planePoints = new GeoPoint[0];
+
+ public final GeoPoint bottomBoundaryPoint;
+
+ // Edge points
+ public final GeoPoint[] edgePoints;
+
+ public GeoNorthLatitudeZone(final double bottomLat)
+ {
+ this.bottomLat = bottomLat;
+
+ final double sinBottomLat = Math.sin(bottomLat);
+ this.cosBottomLat = Math.cos(bottomLat);
+
+ // Construct sample points, so we get our sidedness right
+ final Vector bottomPoint = new Vector(0.0,0.0,sinBottomLat);
+
+ // Compute an interior point. Pick one whose lat is between top and bottom.
+ final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.interiorPoint = new GeoPoint(Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat),0.0,sinMiddleLat);
+ this.bottomBoundaryPoint = new GeoPoint(Math.sqrt(1.0 - sinBottomLat * sinBottomLat),0.0,sinBottomLat);
+
+ this.bottomPlane = new SidedPlane(interiorPoint,sinBottomLat);
+
+ this.edgePoints = new GeoPoint[]{bottomBoundaryPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle)
+ {
+ final double newTopLat = Math.PI * 0.5;
+ final double newBottomLat = bottomLat - angle;
+ return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point)
+ {
+ return
+ bottomPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z)
+ {
+ return
+ bottomPlane.isWithin(x,y,z);
+ }
+
+ @Override
+ public double getRadius()
+ {
+ // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
+ // would contain all the bounding box points, when starting in the "center".
+ if (bottomLat < 0.0)
+ return Math.PI;
+ double maxCosLat = cosBottomLat;
+ return maxCosLat * Math.PI;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints()
+ {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
+ {
+ return
+ p.intersects(bottomPlane,notablePoints,planePoints,bounds);
+ }
+
+ /** Compute longitude/latitude bounds for the shape.
+ *@param bounds is the optional input bounds object. If this is null,
+ * a bounds object will be created. Otherwise, the input object will be modified.
+ *@return a Bounds object describing the shape's bounds. If the bounds cannot
+ * be computed, then return a Bounds object with noLongitudeBound,
+ * noTopLatitudeBound, and noBottomLatitudeBound.
+ */
+ @Override
+ public Bounds getBounds(Bounds bounds)
+ {
+ if (bounds == null)
+ bounds = new Bounds();
+ bounds.noLongitudeBound().noTopLatitudeBound().addLatitudeZone(bottomLat);
+ return bounds;
+ }
+
+ @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
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof GeoNorthLatitudeZone))
+ return false;
+ GeoNorthLatitudeZone other = (GeoNorthLatitudeZone)o;
+ return other.bottomPlane.equals(bottomPlane);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = bottomPlane.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoNorthLatitudeZone: {bottomlat="+bottomLat+"("+bottomLat*180.0/Math.PI+")}";
+ }
+}
+
Added: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java?rev=1675374&view=auto
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java (added)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java Wed Apr 22 14:47:00 2015
@@ -0,0 +1,243 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * 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.
+ */
+
+/** Bounding box limited on three sides (bottom lat, left lon, right lon), including
+* the north pole.
+* The left-right maximum extent for this shape is PI; for anything larger, use
+* GeoWideNorthRectangle.
+*/
+public class GeoNorthRectangle extends GeoBBoxBase
+{
+ public final double bottomLat;
+ public final double leftLon;
+ public final double rightLon;
+
+ public final double cosMiddleLat;
+
+ public final GeoPoint LRHC;
+ public final GeoPoint LLHC;
+
+ public final SidedPlane bottomPlane;
+ public final SidedPlane leftPlane;
+ public final SidedPlane rightPlane;
+
+ public final GeoPoint[] bottomPlanePoints;
+ public final GeoPoint[] leftPlanePoints;
+ public final GeoPoint[] rightPlanePoints;
+
+ public final GeoPoint centerPoint;
+
+ public final GeoPoint[] edgePoints = new GeoPoint[]{NORTH_POLE};
+
+ /** Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI} */
+ public GeoNorthRectangle(final double bottomLat, final double leftLon, double rightLon)
+ {
+ // Argument checking
+ if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent > Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too great");
+
+ this.bottomLat = bottomLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinBottomLat = Math.sin(bottomLat);
+ final double cosBottomLat = Math.cos(bottomLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the points
+ this.LRHC = new GeoPoint(sinBottomLat,sinRightLon,cosBottomLat,cosRightLon);
+ this.LLHC = new GeoPoint(sinBottomLat,sinLeftLon,cosBottomLat,cosLeftLon);
+
+ final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(sinMiddleLat,sinMiddleLon,cosMiddleLat,cosMiddleLon);
+
+ this.bottomPlane = new SidedPlane(centerPoint,sinBottomLat);
+ this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
+
+ this.bottomPlanePoints = new GeoPoint[]{LLHC,LRHC};
+ this.leftPlanePoints = new GeoPoint[]{NORTH_POLE,LLHC};
+ this.rightPlanePoints = new GeoPoint[]{NORTH_POLE,LRHC};
+
+ }
+
+ @Override
+ public GeoBBox expand(final double angle)
+ {
+ final double newTopLat = Math.PI * 0.5;
+ final double newBottomLat = bottomLat - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(newTopLat,newBottomLat,newLeftLon,newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point)
+ {
+ return
+ bottomPlane.isWithin(point) &&
+ leftPlane.isWithin(point) &&
+ rightPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z)
+ {
+ return
+ bottomPlane.isWithin(x,y,z) &&
+ leftPlane.isWithin(x,y,z) &&
+ rightPlane.isWithin(x,y,z);
+ }
+
+ @Override
+ public double getRadius()
+ {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double bottomAngle = centerPoint.arcDistance(LLHC);
+ return Math.max(centerAngle,bottomAngle);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints()
+ {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
+ {
+ return
+ p.intersects(bottomPlane,notablePoints,bottomPlanePoints,bounds,leftPlane,rightPlane) ||
+ p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,rightPlane,bottomPlane) ||
+ p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,leftPlane,bottomPlane);
+ }
+
+ /** Compute longitude/latitude bounds for the shape.
+ *@param bounds is the optional input bounds object. If this is null,
+ * a bounds object will be created. Otherwise, the input object will be modified.
+ *@return a Bounds object describing the shape's bounds. If the bounds cannot
+ * be computed, then return a Bounds object with noLongitudeBound,
+ * noTopLatitudeBound, and noBottomLatitudeBound.
+ */
+ @Override
+ public Bounds getBounds(Bounds bounds)
+ {
+ if (bounds == null)
+ bounds = new Bounds();
+ bounds.noTopLatitudeBound().addLatitudeZone(bottomLat)
+ .addLongitudeSlice(leftLon,rightLon);
+ return bounds;
+ }
+
+ @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(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
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof GeoNorthRectangle))
+ return false;
+ GeoNorthRectangle other = (GeoNorthRectangle)o;
+ return other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = LLHC.hashCode();
+ result = 31 * result + LRHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoNorthRectangle: {bottomlat="+bottomLat+"("+bottomLat*180.0/Math.PI+"), leftlon="+leftLon+"("+leftLon*180.0/Math.PI+"), rightlon="+rightLon+"("+rightLon*180.0/Math.PI+")}";
+ }
+}
+
+
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java Wed Apr 22 14:47:00 2015
@@ -67,6 +67,20 @@ public class GeoPath extends GeoBaseExte
if (ps.isDegenerate())
return;
segments.add(ps);
+ } else {
+ // First point. We compute the basic set of edgepoints here because we've got the lat and lon available.
+ // Move from center only in latitude. Then, if we go past the north pole, adjust the longitude also.
+ double newLat = lat + cutoffAngle;
+ double newLon = lon;
+ if (newLat > Math.PI * 0.5) {
+ newLat = Math.PI - newLat;
+ newLon += Math.PI;
+ }
+ while (newLon > Math.PI) {
+ newLon -= Math.PI * 2.0;
+ }
+ final GeoPoint edgePoint = new GeoPoint(newLat,newLon);
+ this.edgePoints = new GeoPoint[]{edgePoint};
}
final SegmentEndpoint se = new SegmentEndpoint(end, originDistance, cutoffOffset, cutoffAngle, chordDistance);
points.add(se);
@@ -77,8 +91,24 @@ public class GeoPath extends GeoBaseExte
throw new IllegalArgumentException("Path must have at least one point");
if (segments.size() > 0) {
edgePoints = new GeoPoint[]{points.get(0).circlePlane.getSampleIntersectionPoint(segments.get(0).invertedStartCutoffPlane)};
- } else {
- edgePoints = new GeoPoint[]{points.get(0).point.getSamplePoint(cutoffOffset,originDistance)};
+ }
+ for (int i = 0; i < points.size(); i++) {
+ final SegmentEndpoint pathPoint = points.get(i);
+ Membership previousEndBound = null;
+ GeoPoint[] previousEndNotablePoints = null;
+ Membership nextStartBound = null;
+ GeoPoint[] nextStartNotablePoints = null;
+ if (i > 0) {
+ final PathSegment previousSegment = segments.get(i-1);
+ previousEndBound = previousSegment.invertedEndCutoffPlane;
+ previousEndNotablePoints = previousSegment.endCutoffPlanePoints;
+ }
+ if (i < segments.size()) {
+ final PathSegment nextSegment = segments.get(i);
+ nextStartBound = nextSegment.invertedStartCutoffPlane;
+ nextStartNotablePoints = nextSegment.startCutoffPlanePoints;
+ }
+ pathPoint.setCutoffPlanes(previousEndNotablePoints,previousEndBound,nextStartNotablePoints,nextStartBound);
}
}
@@ -267,7 +297,7 @@ public class GeoPath extends GeoBaseExte
}
@Override
- public boolean intersects(final Plane plane, final Membership... bounds)
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds)
{
// We look for an intersection with any of the exterior edges of the path.
// We also have to look for intersections with the cones described by the endpoints.
@@ -279,21 +309,14 @@ public class GeoPath extends GeoBaseExte
// Well, sort of. We can detect intersections also due to overlap of segments with each other.
// But that's an edge case and we won't be optimizing for it.
- for (int i = 0; i < points.size(); i++) {
- final SegmentEndpoint pathPoint = points.get(i);
- Membership previousEndBound = null;
- Membership nextStartBound = null;
- if (i > 0)
- previousEndBound = segments.get(i-1).invertedEndCutoffPlane;
- if (i < segments.size())
- nextStartBound = segments.get(i).invertedStartCutoffPlane;
- if (pathPoint.intersects(plane, bounds, previousEndBound, nextStartBound)) {
+ for (final SegmentEndpoint pathPoint : points) {
+ if (pathPoint.intersects(plane, notablePoints, bounds)) {
return true;
}
}
- for (PathSegment pathSegment : segments) {
- if (pathSegment.intersects(plane, bounds)) {
+ for (final PathSegment pathSegment : segments) {
+ if (pathSegment.intersects(plane, notablePoints, bounds)) {
return true;
}
}
@@ -363,7 +386,11 @@ public class GeoPath extends GeoBaseExte
public final double cutoffNormalDistance;
public final double cutoffAngle;
public final double chordDistance;
-
+ public Membership[] cutoffPlanes = null;
+ public GeoPoint[] notablePoints = null;
+
+ public final static GeoPoint[] circlePoints = new GeoPoint[0];
+
public SegmentEndpoint(final GeoPoint point, final double originDistance, final double cutoffOffset, final double cutoffAngle, final double chordDistance)
{
this.point = point;
@@ -373,6 +400,30 @@ public class GeoPath extends GeoBaseExte
this.circlePlane = new SidedPlane(point, point, -originDistance);
}
+ public void setCutoffPlanes(final GeoPoint[] previousEndNotablePoints, final Membership previousEndPlane,
+ final GeoPoint[] nextStartNotablePoints, final Membership nextStartPlane) {
+ if (previousEndNotablePoints == null && nextStartNotablePoints == null) {
+ cutoffPlanes = new Membership[0];
+ notablePoints = new GeoPoint[0];
+ } else if (previousEndNotablePoints != null && nextStartNotablePoints == null) {
+ cutoffPlanes = new Membership[]{previousEndPlane};
+ notablePoints = previousEndNotablePoints;
+ } else if (previousEndNotablePoints == null && nextStartNotablePoints != null) {
+ cutoffPlanes = new Membership[]{nextStartPlane};
+ notablePoints = nextStartNotablePoints;
+ } else {
+ cutoffPlanes = new Membership[]{previousEndPlane,nextStartPlane};
+ notablePoints = new GeoPoint[previousEndNotablePoints.length + nextStartNotablePoints.length];
+ int i = 0;
+ for (GeoPoint p : previousEndNotablePoints) {
+ notablePoints[i++] = p;
+ }
+ for (GeoPoint p : nextStartNotablePoints) {
+ notablePoints[i++] = p;
+ }
+ }
+ }
+
public boolean isWithin(final Vector point)
{
return circlePlane.isWithin(point);
@@ -407,9 +458,9 @@ public class GeoPath extends GeoBaseExte
return dist;
}
- public boolean intersects(final Plane p, final Membership[] bounds, final Membership previousEndCutoff, final Membership nextStartCutoff)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds)
{
- return circlePlane.intersects(p, bounds, previousEndCutoff, nextStartCutoff);
+ return circlePlane.intersects(p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
}
public void getBounds(Bounds bounds)
@@ -450,6 +501,10 @@ public class GeoPath extends GeoBaseExte
public final SidedPlane lowerConnectingPlane;
public final SidedPlane startCutoffPlane;
public final SidedPlane endCutoffPlane;
+ public final GeoPoint[] upperConnectingPlanePoints;
+ public final GeoPoint[] lowerConnectingPlanePoints;
+ public final GeoPoint[] startCutoffPlanePoints;
+ public final GeoPoint[] endCutoffPlanePoints;
public final double planeBoundingOffset;
public final double arcWidth;
public final double chordDistance;
@@ -475,6 +530,10 @@ public class GeoPath extends GeoBaseExte
lowerConnectingPlane = null;
startCutoffPlane = null;
endCutoffPlane = null;
+ upperConnectingPlanePoints = null;
+ lowerConnectingPlanePoints = null;
+ startCutoffPlanePoints = null;
+ endCutoffPlanePoints = null;
invertedStartCutoffPlane = null;
invertedEndCutoffPlane = null;
} else {
@@ -484,6 +543,18 @@ public class GeoPath extends GeoBaseExte
// Cutoff planes use opposite endpoints as correct side examples
startCutoffPlane = new SidedPlane(end,normalizedConnectingPlane,start);
endCutoffPlane = new SidedPlane(start,normalizedConnectingPlane,end);
+ final Membership[] upperSide = new Membership[]{upperConnectingPlane};
+ final Membership[] lowerSide = new Membership[]{lowerConnectingPlane};
+ final Membership[] startSide = new Membership[]{startCutoffPlane};
+ final Membership[] endSide = new Membership[]{endCutoffPlane};
+ final GeoPoint ULHC = upperConnectingPlane.findIntersections(startCutoffPlane,lowerSide,endSide)[0];
+ final GeoPoint URHC = upperConnectingPlane.findIntersections(endCutoffPlane,lowerSide,startSide)[0];
+ final GeoPoint LLHC = lowerConnectingPlane.findIntersections(startCutoffPlane,upperSide,endSide)[0];
+ final GeoPoint LRHC = lowerConnectingPlane.findIntersections(endCutoffPlane,upperSide,startSide)[0];
+ upperConnectingPlanePoints = new GeoPoint[]{ULHC,URHC};
+ lowerConnectingPlanePoints = new GeoPoint[]{LLHC,LRHC};
+ startCutoffPlanePoints = new GeoPoint[]{ULHC,LLHC};
+ endCutoffPlanePoints = new GeoPoint[]{URHC,LRHC};
invertedStartCutoffPlane = new SidedPlane(startCutoffPlane);
invertedEndCutoffPlane = new SidedPlane(endCutoffPlane);
}
@@ -535,7 +606,7 @@ public class GeoPath extends GeoBaseExte
final double perpZ = normalizedConnectingPlane.x * point.y - normalizedConnectingPlane.y * point.x;
// If we have a degenerate line, then just compute the normal distance from point x to the start
- if (perpX < 1e-10 && perpY < 1e-10 && perpZ < 1e-10)
+ if (Math.abs(perpX) < Vector.MINIMUM_RESOLUTION && Math.abs(perpY) < Vector.MINIMUM_RESOLUTION && Math.abs(perpZ) < Vector.MINIMUM_RESOLUTION)
return point.normalDistance(start);
final double normFactor = 1.0 / Math.sqrt(perpX * perpX + perpY * perpY + perpZ * perpZ);
@@ -556,7 +627,7 @@ public class GeoPath extends GeoBaseExte
final double perpZ = normalizedConnectingPlane.x * point.y - normalizedConnectingPlane.y * point.x;
// If we have a degenerate line, then just compute the normal distance from point x to the start
- if (Math.abs(perpX) < 1e-10 && Math.abs(perpY) < 1e-10 && Math.abs(perpZ) < 1e-10)
+ if (Math.abs(perpX) < Vector.MINIMUM_RESOLUTION && Math.abs(perpY) < Vector.MINIMUM_RESOLUTION && Math.abs(perpZ) < Vector.MINIMUM_RESOLUTION)
return point.linearDistance(start);
// Next, we need the vector of the line, which is the cross product of the normalized connecting plane
@@ -584,10 +655,10 @@ public class GeoPath extends GeoBaseExte
return point.linearDistance(normLineX,normLineY,normLineZ) + start.linearDistance(normLineX,normLineY,normLineZ);
}
- public boolean intersects(final Plane p, final Membership[] bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds)
{
- return upperConnectingPlane.intersects(p, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
- lowerConnectingPlane.intersects(p, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+ return upperConnectingPlane.intersects(p, notablePoints, upperConnectingPlanePoints, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
+ lowerConnectingPlane.intersects(p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
}
public void getBounds(Bounds bounds)
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java Wed Apr 22 14:47:00 2015
@@ -41,42 +41,4 @@ public class GeoPoint extends Vector
return Tools.safeAcos(evaluate(v));
}
- /** Find a single point that is a specified arc distance away from this point.
- */
- public GeoPoint getSamplePoint(final double sinRotationAngle, final double cosRotationAngle) {
- // Rotate in the best of three possible directions: x-y, x-z, y-z.
- final double absX = Math.abs(x);
- final double absY = Math.abs(y);
- final double absZ = Math.abs(z);
- if (absX > absY) {
- // x > y
- if (absY > absZ) {
- // x > y > z
- // rotate in x-y
- return new GeoPoint(x*cosRotationAngle-y*sinRotationAngle,x*sinRotationAngle+y*cosRotationAngle,z);
- } else {
- // x > z > y OR z > x > y
- // rotate in x-z
- return new GeoPoint(x*cosRotationAngle-z*sinRotationAngle,y,x*sinRotationAngle+z*cosRotationAngle);
- }
- } else {
- // y > x
- if (absX > absZ) {
- // y > x > z
- // rotate in x-y
- return new GeoPoint(x*cosRotationAngle-y*sinRotationAngle,x*sinRotationAngle+y*cosRotationAngle,z);
- } else {
- // y > z > x OR z > y > x
- // rotate in y-z
- return new GeoPoint(x,y*cosRotationAngle-z*sinRotationAngle,y*sinRotationAngle+z*cosRotationAngle);
- }
- }
- }
-
- /** Find a single point that is a specified arc distance away from this point.
- */
- public GeoPoint getSamplePoint(final double rotationAngle) {
- return getSamplePoint(Math.sin(rotationAngle), Math.cos(rotationAngle));
- }
-
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java Wed Apr 22 14:47:00 2015
@@ -39,7 +39,12 @@ public class GeoRectangle extends GeoBBo
public final SidedPlane bottomPlane;
public final SidedPlane leftPlane;
public final SidedPlane rightPlane;
-
+
+ public final GeoPoint[] topPlanePoints;
+ public final GeoPoint[] bottomPlanePoints;
+ public final GeoPoint[] leftPlanePoints;
+ public final GeoPoint[] rightPlanePoints;
+
public final GeoPoint centerPoint;
public final GeoPoint[] edgePoints;
@@ -103,6 +108,11 @@ public class GeoRectangle extends GeoBBo
this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
+ this.topPlanePoints = new GeoPoint[]{ULHC,URHC};
+ this.bottomPlanePoints = new GeoPoint[]{LLHC,LRHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC,LLHC};
+ this.rightPlanePoints = new GeoPoint[]{URHC,LRHC};
+
this.edgePoints = new GeoPoint[]{ULHC};
}
@@ -161,12 +171,12 @@ public class GeoRectangle extends GeoBBo
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
- return p.intersects(topPlane,bounds,bottomPlane,leftPlane,rightPlane) ||
- p.intersects(bottomPlane,bounds,topPlane,leftPlane,rightPlane) ||
- p.intersects(leftPlane,bounds,rightPlane,topPlane,bottomPlane) ||
- p.intersects(rightPlane,bounds,leftPlane,topPlane,bottomPlane);
+ return p.intersects(topPlane,notablePoints,topPlanePoints,bounds,bottomPlane,leftPlane,rightPlane) ||
+ p.intersects(bottomPlane,notablePoints,bottomPlanePoints,bounds,topPlane,leftPlane,rightPlane) ||
+ p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,rightPlane,topPlane,bottomPlane) ||
+ p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,leftPlane,topPlane,bottomPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -188,27 +198,40 @@ public class GeoRectangle extends GeoBBo
@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)
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" inside of each other");
return OVERLAPS;
+ }
- if (path.intersects(topPlane,bottomPlane,leftPlane,rightPlane) ||
- path.intersects(bottomPlane,topPlane,leftPlane,rightPlane) ||
- path.intersects(leftPlane,topPlane,bottomPlane,rightPlane) ||
- path.intersects(rightPlane,leftPlane,topPlane,bottomPlane))
+ 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)
+ if (insideShape) {
+ //System.err.println(" shape contains rectangle");
return CONTAINS;
-
+ }
+ //System.err.println(" disjoint");
return DISJOINT;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java Wed Apr 22 14:47:00 2015
@@ -37,11 +37,14 @@ public interface GeoShape extends Member
* helped for some complex shapes that are built out of overlapping parts.
*@param plane is the plane to assess for intersection with the shape's edges or
* bounding curves.
+ *@param notablePoints represents the intersections of the plane with the supplied
+ * bounds. These are used to disambiguate when two planes are identical and it needs
+ * to be determined whether any points exist that fulfill all the bounds.
*@param bounds are a set of bounds that define an area that an
* intersection must be within in order to qualify (provided by a GeoArea).
*@return true if there's such an intersection, false if not.
*/
- public boolean intersects(final Plane plane, final Membership... bounds);
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds);
/** Compute longitude/latitude bounds for the shape.
*@param bounds is the optional input bounds object. If this is null,
Added: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java?rev=1675374&view=auto
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java (added)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java Wed Apr 22 14:47:00 2015
@@ -0,0 +1,167 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * 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.
+ */
+
+/** This GeoBBox represents an area rectangle limited only in north latitude.
+*/
+public class GeoSouthLatitudeZone extends GeoBBoxBase
+{
+ public final double topLat;
+ public final double cosTopLat;
+ public final SidedPlane topPlane;
+ public final GeoPoint interiorPoint;
+ public final static GeoPoint[] planePoints = new GeoPoint[0];
+
+ public final GeoPoint topBoundaryPoint;
+
+ // Edge points
+ public final GeoPoint[] edgePoints;
+
+ public GeoSouthLatitudeZone(final double topLat)
+ {
+ this.topLat = topLat;
+
+ final double sinTopLat = Math.sin(topLat);
+ this.cosTopLat = Math.cos(topLat);
+
+ // Construct sample points, so we get our sidedness right
+ final Vector topPoint = new Vector(0.0,0.0,sinTopLat);
+
+ // Compute an interior point. Pick one whose lat is between top and bottom.
+ final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.interiorPoint = new GeoPoint(Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat),0.0,sinMiddleLat);
+ this.topBoundaryPoint = new GeoPoint(Math.sqrt(1.0 - sinTopLat * sinTopLat),0.0,sinTopLat);
+
+ this.topPlane = new SidedPlane(interiorPoint,sinTopLat);
+
+ this.edgePoints = new GeoPoint[]{topBoundaryPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle)
+ {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point)
+ {
+ return topPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z)
+ {
+ return topPlane.isWithin(x,y,z);
+ }
+
+ @Override
+ public double getRadius()
+ {
+ // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
+ // would contain all the bounding box points, when starting in the "center".
+ if (topLat > 0.0)
+ return Math.PI;
+ double maxCosLat = cosTopLat;
+ return maxCosLat * Math.PI;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints()
+ {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
+ {
+ return p.intersects(topPlane,notablePoints,planePoints,bounds);
+ }
+
+ /** Compute longitude/latitude bounds for the shape.
+ *@param bounds is the optional input bounds object. If this is null,
+ * a bounds object will be created. Otherwise, the input object will be modified.
+ *@return a Bounds object describing the shape's bounds. If the bounds cannot
+ * be computed, then return a Bounds object with noLongitudeBound,
+ * noTopLatitudeBound, and noBottomLatitudeBound.
+ */
+ @Override
+ public Bounds getBounds(Bounds bounds)
+ {
+ if (bounds == null)
+ bounds = new Bounds();
+ bounds.noLongitudeBound().addLatitudeZone(topLat).noBottomLatitudeBound();
+ return bounds;
+ }
+
+ @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
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof GeoSouthLatitudeZone))
+ return false;
+ GeoSouthLatitudeZone other = (GeoSouthLatitudeZone)o;
+ return other.topPlane.equals(topPlane);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = topPlane.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoSouthLatitudeZone: {toplat="+topLat+"("+topLat*180.0/Math.PI+")}";
+ }
+}
+