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 [2/2] - in
/lucene/dev/branches/lucene6196/lucene/spatial/src:
java/org/apache/lucene/spatial/spatial4j/geo3d/
test/org/apache/lucene/spatial/spatial4j/
Added: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java?rev=1675374&view=auto
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java (added)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java Wed Apr 22 14:47:00 2015
@@ -0,0 +1,238 @@
+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 (top lat, left lon, right lon). The
+* other corner is the south pole.
+* The left-right maximum extent for this shape is PI; for anything larger, use
+* GeoWideSouthRectangle.
+*/
+public class GeoSouthRectangle extends GeoBBoxBase
+{
+ public final double topLat;
+ public final double leftLon;
+ public final double rightLon;
+
+ public final double cosMiddleLat;
+
+ public final GeoPoint ULHC;
+ public final GeoPoint URHC;
+
+ public final SidedPlane topPlane;
+ public final SidedPlane leftPlane;
+ public final SidedPlane rightPlane;
+
+ public final GeoPoint[] topPlanePoints;
+ public final GeoPoint[] leftPlanePoints;
+ public final GeoPoint[] rightPlanePoints;
+
+ public final GeoPoint centerPoint;
+
+ public final GeoPoint[] edgePoints = new GeoPoint[]{SOUTH_POLE};
+
+ /** Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI} */
+ public GeoSouthRectangle(final double topLat, final double leftLon, double rightLon)
+ {
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top 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.topLat = topLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ 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 four points
+ this.ULHC = new GeoPoint(sinTopLat,sinLeftLon,cosTopLat,cosLeftLon);
+ this.URHC = new GeoPoint(sinTopLat,sinRightLon,cosTopLat,cosRightLon);
+
+ final double middleLat = (topLat - Math.PI * 0.5) * 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.topPlane = new SidedPlane(centerPoint,sinTopLat);
+ this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
+
+ this.topPlanePoints = new GeoPoint[]{ULHC,URHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC,SOUTH_POLE};
+ this.rightPlanePoints = new GeoPoint[]{URHC,SOUTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle)
+ {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ // 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 topPlane.isWithin(point) &&
+ leftPlane.isWithin(point) &&
+ rightPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z)
+ {
+ return topPlane.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 topAngle = centerPoint.arcDistance(URHC);
+ return Math.max(centerAngle,topAngle);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints()
+ {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
+ {
+ return p.intersects(topPlane,notablePoints,topPlanePoints,bounds,leftPlane,rightPlane) ||
+ p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,rightPlane,topPlane) ||
+ p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,leftPlane,topPlane);
+ }
+
+ /** 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.addLatitudeZone(topLat).noBottomLatitudeBound()
+ .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(SOUTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane,topPlanePoints,leftPlane,rightPlane) ||
+ path.intersects(leftPlane,leftPlanePoints,topPlane,rightPlane) ||
+ path.intersects(rightPlane,rightPlanePoints,leftPlane,topPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE)
+ {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof GeoSouthRectangle))
+ return false;
+ GeoSouthRectangle other = (GeoSouthRectangle)o;
+ return other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ULHC.hashCode();
+ result = 31 * result + URHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoSouthRectangle: {toplat="+topLat+"("+topLat*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/GeoWideDegenerateHorizontalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java Wed Apr 22 14:47:00 2015
@@ -31,7 +31,9 @@ public class GeoWideDegenerateHorizontal
public final Plane plane;
public final SidedPlane leftPlane;
public final SidedPlane rightPlane;
-
+
+ public final GeoPoint[] planePoints;
+
public final GeoPoint centerPoint;
public final EitherBound eitherBound;
@@ -87,6 +89,8 @@ public class GeoWideDegenerateHorizontal
this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
+ this.planePoints = new GeoPoint[]{LHC,RHC};
+
this.eitherBound = new EitherBound();
this.edgePoints = new GeoPoint[]{centerPoint};
@@ -115,7 +119,7 @@ public class GeoWideDegenerateHorizontal
{
if (point == null)
return false;
- return plane.evaluate(point) == 0.0 &&
+ return plane.evaluateIsZero(point) &&
(leftPlane.isWithin(point) ||
rightPlane.isWithin(point));
}
@@ -123,7 +127,7 @@ public class GeoWideDegenerateHorizontal
@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));
}
@@ -146,11 +150,11 @@ public class GeoWideDegenerateHorizontal
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
// Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
// requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(plane,bounds,eitherBound);
+ return p.intersects(plane,notablePoints,planePoints,bounds,eitherBound);
}
/** Compute longitude/latitude bounds for the shape.
@@ -172,7 +176,7 @@ public class GeoWideDegenerateHorizontal
@Override
public int getRelationship(final GeoShape path) {
- if (path.intersects(plane,eitherBound)) {
+ if (path.intersects(plane,planePoints,eitherBound)) {
return OVERLAPS;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java Wed Apr 22 14:47:00 2015
@@ -27,10 +27,12 @@ public class GeoWideLongitudeSlice exten
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}.
* Horizantal angle must be greater than or equal to PI.
@@ -115,12 +117,12 @@ public class GeoWideLongitudeSlice exten
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
// Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
// requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(leftPlane,bounds) ||
- p.intersects(rightPlane,bounds);
+ return p.intersects(leftPlane,notablePoints,planePoints,bounds) ||
+ p.intersects(rightPlane,notablePoints,planePoints,bounds);
}
/** Compute longitude/latitude bounds for the shape.
@@ -146,13 +148,13 @@ public class GeoWideLongitudeSlice exten
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) ||
- path.intersects(rightPlane))
+ if (path.intersects(leftPlane,planePoints) ||
+ path.intersects(rightPlane,planePoints))
return OVERLAPS;
if (insideRectangle == ALL_INSIDE)
Added: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java?rev=1675374&view=auto
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java (added)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java Wed Apr 22 14:47:00 2015
@@ -0,0 +1,263 @@
+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 wider than PI but limited on three sides (
+* bottom lat, left lon, right lon).
+*/
+public class GeoWideNorthRectangle 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 EitherBound eitherBound;
+
+ 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}.
+ * Horizontal angle must be greater than or equal to PI.
+ */
+ public GeoWideNorthRectangle(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 small");
+
+ 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 four 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};
+
+ this.eitherBound = new EitherBound();
+ }
+
+ @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)
+ {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return
+ p.intersects(bottomPlane,notablePoints,bottomPlanePoints,bounds,eitherBound) ||
+ p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,bottomPlane) ||
+ p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,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+" comparing to "+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(" both inside each other");
+ return OVERLAPS;
+ }
+
+ if (
+ path.intersects(bottomPlane,bottomPlanePoints,eitherBound) ||
+ path.intersects(leftPlane,leftPlanePoints,bottomPlane) ||
+ path.intersects(rightPlane,rightPlanePoints,bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" rectangle inside shape");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof GeoWideNorthRectangle))
+ return false;
+ GeoWideNorthRectangle other = (GeoWideNorthRectangle)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 "GeoWideNorthRectangle: {bottomlat="+bottomLat+"("+bottomLat*180.0/Math.PI+"), leftlon="+leftLon+"("+leftLon*180.0/Math.PI+"), rightlon="+rightLon+"("+rightLon*180.0/Math.PI+")}";
+ }
+
+ protected class EitherBound implements Membership {
+ public EitherBound() {
+ }
+
+ @Override
+ public boolean isWithin(final Vector v) {
+ return leftPlane.isWithin(v) || rightPlane.isWithin(v);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x,y,z) || rightPlane.isWithin(x,y,z);
+ }
+ }
+}
+
+
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java Wed Apr 22 14:47:00 2015
@@ -38,7 +38,12 @@ public class GeoWideRectangle extends Ge
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 EitherBound eitherBound;
@@ -105,7 +110,12 @@ public class GeoWideRectangle extends Ge
this.bottomPlane = new SidedPlane(centerPoint,sinBottomLat);
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.eitherBound = new EitherBound();
this.edgePoints = new GeoPoint[]{ULHC};
@@ -166,14 +176,14 @@ public class GeoWideRectangle extends Ge
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
// Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
// requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(topPlane,bounds,bottomPlane,eitherBound) ||
- p.intersects(bottomPlane,bounds,topPlane,eitherBound) ||
- p.intersects(leftPlane,bounds,topPlane,bottomPlane) ||
- p.intersects(rightPlane,bounds,topPlane,bottomPlane);
+ return p.intersects(topPlane,notablePoints,topPlanePoints,bounds,bottomPlane,eitherBound) ||
+ p.intersects(bottomPlane,notablePoints,bottomPlanePoints,bounds,topPlane,eitherBound) ||
+ p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,topPlane,bottomPlane) ||
+ p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,topPlane,bottomPlane);
}
/** Compute longitude/latitude bounds for the shape.
@@ -195,30 +205,40 @@ public class GeoWideRectangle extends Ge
@Override
public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" comparing to "+path);
final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
return OVERLAPS;
+ }
final boolean insideShape = path.isWithin(ULHC);
if (insideRectangle == ALL_INSIDE && insideShape)
+ {
+ //System.err.println(" both inside each other");
return OVERLAPS;
+ }
- if (path.intersects(topPlane,bottomPlane,eitherBound) ||
- path.intersects(bottomPlane,topPlane,eitherBound) ||
- path.intersects(leftPlane,topPlane,bottomPlane) ||
- path.intersects(rightPlane,topPlane,bottomPlane)) {
+ if (path.intersects(topPlane,topPlanePoints,bottomPlane,eitherBound) ||
+ path.intersects(bottomPlane,bottomPlanePoints,topPlane,eitherBound) ||
+ path.intersects(leftPlane,leftPlanePoints,topPlane,bottomPlane) ||
+ path.intersects(rightPlane,rightPlanePoints,topPlane,bottomPlane)) {
+ //System.err.println(" edges intersect");
return OVERLAPS;
}
if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
return WITHIN;
}
if (insideShape) {
+ //System.err.println(" rectangle inside shape");
return CONTAINS;
}
+ //System.err.println(" disjoint");
return DISJOINT;
}
Added: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java?rev=1675374&view=auto
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java (added)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java Wed Apr 22 14:47:00 2015
@@ -0,0 +1,259 @@
+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 wider than PI but limited on three sides (top lat,
+* left lon, right lon).
+*/
+public class GeoWideSouthRectangle extends GeoBBoxBase
+{
+ public final double topLat;
+ public final double leftLon;
+ public final double rightLon;
+
+ public final double cosMiddleLat;
+
+ public final GeoPoint ULHC;
+ public final GeoPoint URHC;
+
+ public final SidedPlane topPlane;
+ public final SidedPlane leftPlane;
+ public final SidedPlane rightPlane;
+
+ public final GeoPoint[] topPlanePoints;
+ public final GeoPoint[] leftPlanePoints;
+ public final GeoPoint[] rightPlanePoints;
+
+ public final GeoPoint centerPoint;
+
+ public final EitherBound eitherBound;
+
+ public final GeoPoint[] edgePoints = new GeoPoint[]{SOUTH_POLE};
+
+ /** Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
+ * Horizontal angle must be greater than or equal to PI.
+ */
+ public GeoWideSouthRectangle(final double topLat, final double leftLon, double rightLon)
+ {
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top 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 small");
+
+ this.topLat = topLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ 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 four points
+ this.ULHC = new GeoPoint(sinTopLat,sinLeftLon,cosTopLat,cosLeftLon);
+ this.URHC = new GeoPoint(sinTopLat,sinRightLon,cosTopLat,cosRightLon);
+
+ final double middleLat = (topLat - Math.PI * 0.5) * 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.topPlane = new SidedPlane(centerPoint,sinTopLat);
+ this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
+
+ this.topPlanePoints = new GeoPoint[]{ULHC,URHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC,SOUTH_POLE};
+ this.rightPlanePoints = new GeoPoint[]{URHC,SOUTH_POLE};
+
+ this.eitherBound = new EitherBound();
+ }
+
+ @Override
+ public GeoBBox expand(final double angle)
+ {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ // 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 topPlane.isWithin(point) &&
+ (leftPlane.isWithin(point) ||
+ rightPlane.isWithin(point));
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z)
+ {
+ return topPlane.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 topAngle = centerPoint.arcDistance(URHC);
+ return Math.max(centerAngle,topAngle);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints()
+ {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
+ {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return p.intersects(topPlane,notablePoints,topPlanePoints,bounds,eitherBound) ||
+ p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,topPlane) ||
+ p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,topPlane);
+ }
+
+ /** 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.addLatitudeZone(topLat).noBottomLatitudeBound()
+ .addLongitudeSlice(leftLon,rightLon);
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" comparing to "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(SOUTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ {
+ //System.err.println(" both inside each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane,topPlanePoints,eitherBound) ||
+ path.intersects(leftPlane,leftPlanePoints,topPlane) ||
+ path.intersects(rightPlane,rightPlanePoints,topPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" rectangle inside shape");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof GeoWideSouthRectangle))
+ return false;
+ GeoWideSouthRectangle other = (GeoWideSouthRectangle)o;
+ return other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ULHC.hashCode();
+ result = 31 * result + URHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideSouthRectangle: {toplat="+topLat+"("+topLat*180.0/Math.PI+"), leftlon="+leftLon+"("+leftLon*180.0/Math.PI+"), rightlon="+rightLon+"("+rightLon*180.0/Math.PI+")}";
+ }
+
+ protected class EitherBound implements Membership {
+ public EitherBound() {
+ }
+
+ @Override
+ public boolean isWithin(final Vector v) {
+ return leftPlane.isWithin(v) || rightPlane.isWithin(v);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x,y,z) || rightPlane.isWithin(x,y,z);
+ }
+ }
+}
+
+
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java Wed Apr 22 14:47:00 2015
@@ -59,7 +59,7 @@ public class GeoWorld extends GeoBBoxBas
}
@Override
- public boolean intersects(final Plane p, final Membership... bounds)
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
{
return false;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java Wed Apr 22 14:47:00 2015
@@ -216,7 +216,7 @@ public class Plane extends Vector
// Now compute latitude min/max points
if (!boundsInfo.checkNoTopLatitudeBound() || !boundsInfo.checkNoBottomLatitudeBound()) {
- if ((Math.abs(A) >= 1e-10 || Math.abs(B) >= 1e-10)) {
+ if ((Math.abs(A) >= MINIMUM_RESOLUTION || Math.abs(B) >= MINIMUM_RESOLUTION)) {
//System.out.println("A = "+A+" B = "+B+" C = "+C+" D = "+D);
// sin (phi) = z
// cos (theta - phi) = D
@@ -359,11 +359,11 @@ public class Plane extends Vector
double b;
double c;
- if (Math.abs(C) < 1e-10) {
+ if (Math.abs(C) < MINIMUM_RESOLUTION) {
// Degenerate; the equation describes a line
//System.out.println("It's a zero-width ellipse");
// Ax + By + D = 0
- if (Math.abs(D) >= 1e-10) {
+ if (Math.abs(D) >= MINIMUM_RESOLUTION) {
if (Math.abs(A) > Math.abs(B)) {
// Use equation suitable for A != 0
// We need to find the endpoints of the zero-width ellipse.
@@ -432,7 +432,6 @@ public class Plane extends Vector
double sqrtClause = b * b - 4.0 * a * c;
if (sqrtClause >= 0.0) {
-
if (sqrtClause == 0.0) {
double x0 = -b / (2.0 * a);
double y0 = (- D - A * x0) / B;
@@ -560,7 +559,7 @@ public class Plane extends Vector
addPoint(boundsInfo, bounds, x0a, y0a, z0a);
addPoint(boundsInfo, bounds, x0b, y0b, z0b);
}
- }
+ }
} else {
//System.out.println("Using the x quadratic");
@@ -588,7 +587,6 @@ public class Plane extends Vector
//System.out.println("sqrtClause="+sqrtClause);
if (sqrtClause >= 0.0) {
-
if (sqrtClause == 0.0) {
//System.out.println("One solution");
double x0 = -b / (2.0 * a);
@@ -634,13 +632,44 @@ public class Plane extends Vector
/** Determine whether the plane intersects another plane within the
* bounds provided.
*@param q is the other plane.
+ *@param notablePoints are points to look at to disambiguate cases when the two planes are identical.
+ *@param moreNotablePoints are additional points to look at to disambiguate cases when the two planes are identical.
*@param bounds is one part of the bounds.
*@param moreBounds are more bounds.
*@return true if there's an intersection.
*/
- public boolean intersects(final Plane q, final Membership[] bounds, final Membership... moreBounds) {
+ public boolean intersects(final Plane q, final GeoPoint[] notablePoints, final GeoPoint[] moreNotablePoints, final Membership[] bounds, final Membership... moreBounds) {
+ // If the two planes are identical, then the math will find no points of intersection.
+ // So a special case of this is to check for plane equality. But that is not enough, because
+ // what we really need at that point is to determine whether overlap occurs between the two parts of the intersection
+ // of plane and circle. That is, are there *any* points on the plane that are within the bounds described?
+ if (equals(q)) {
+ // The only way to efficiently figure this out will be to have a list of trial points available to evaluate.
+ // We look for any point that fulfills all the bounds.
+ for (GeoPoint p : notablePoints) {
+ if (meetsAllBounds(p,bounds,moreBounds))
+ return true;
+ }
+ for (GeoPoint p : moreNotablePoints) {
+ if (meetsAllBounds(p,bounds,moreBounds))
+ return true;
+ }
+ return false;
+ }
return findIntersections(q,bounds,moreBounds).length > 0;
}
+
+ protected static boolean meetsAllBounds(final GeoPoint p, final Membership[] bounds, final Membership[] moreBounds) {
+ for (final Membership bound : bounds) {
+ if (!bound.isWithin(p))
+ return false;
+ }
+ for (final Membership bound : moreBounds) {
+ if (!bound.isWithin(p))
+ return false;
+ }
+ return true;
+ }
/** Find a sample point on the intersection between two planes and the unit sphere.
*/
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java Wed Apr 22 14:47:00 2015
@@ -79,9 +79,10 @@ public class SidedPlane extends Plane im
@Override
public boolean isWithin(Vector point)
{
- double sigNum = Math.signum(evaluate(point));
- if (sigNum == 0.0)
+ double evalResult = evaluate(point);
+ if (Math.abs(evalResult) < MINIMUM_RESOLUTION)
return true;
+ double sigNum = Math.signum(evalResult);
return sigNum == this.sigNum;
}
@@ -94,7 +95,10 @@ public class SidedPlane extends Plane im
@Override
public boolean isWithin(double x, double y, double z)
{
- double sigNum = Math.signum(this.x * x + this.y * y + this.z * z);
+ double evalResult = this.x * x + this.y * y + this.z * z;
+ if (Math.abs(evalResult) < MINIMUM_RESOLUTION)
+ return true;
+ double sigNum = Math.signum(evalResult);
return sigNum == this.sigNum;
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java Wed Apr 22 14:47:00 2015
@@ -21,6 +21,10 @@ package org.apache.lucene.spatial.spatia
* going through the origin. */
public class Vector
{
+ /** Values that are all considered to be essentially zero have a magnitude
+ * less than this. */
+ public static final double MINIMUM_RESOLUTION = 1e-15;
+
public final double x;
public final double y;
public final double z;
@@ -56,13 +60,31 @@ public class Vector
*/
public Vector normalize() {
double denom = magnitude();
- if (denom < 1e-10)
+ if (denom < MINIMUM_RESOLUTION)
// Degenerate, can't normalize
return null;
double normFactor = 1.0/denom;
return new Vector(x*normFactor,y*normFactor,z*normFactor);
}
+ /** Evaluate a vector (dot product) and check for "zero".
+ *@param v is the vector to evaluate.
+ *@return true if the evaluation yielded zero.
+ */
+ public boolean evaluateIsZero(final Vector v) {
+ return Math.abs(evaluate(v)) < MINIMUM_RESOLUTION;
+ }
+
+ /** Evaluate a vector (do a dot product) snd check for "zero".
+ *@param x is the x value of the vector to evaluate.
+ *@param y is the x value of the vector to evaluate.
+ *@param z is the x value of the vector to evaluate.
+ *@return true if the evaluation yielded zero.
+ */
+ public boolean evaluateIsZero(final double x, final double y, final double z) {
+ return Math.abs(evaluate(x,y,z)) < MINIMUM_RESOLUTION;
+ }
+
/** Evaluate a vector (do a dot product).
*@param v is the vector to evaluate.
*@return the result.
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java?rev=1675374&r1=1675373&r2=1675374&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java Wed Apr 22 14:47:00 2015
@@ -21,12 +21,10 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import com.carrotsearch.randomizedtesting.annotations.Seed;
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
@@ -34,7 +32,6 @@ import org.apache.lucene.spatial.prefix.
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBox;
import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBoxFactory;
import org.apache.lucene.spatial.spatial4j.geo3d.GeoCircle;
import org.apache.lucene.spatial.spatial4j.geo3d.GeoPath;
@@ -80,42 +77,14 @@ public class Geo3dRptTest extends Random
}
@Test
- //@Repeat(iterations = 2000)
- @Seed("B808B88D6F8E285C")
+ @Repeat(iterations = 2000)
+ //@Seed("B808B88D6F8E285C")
public void testOperations() throws IOException {
setupStrategy();
testOperationRandomShapes(SpatialOperation.Intersects);
}
- @Test
- public void testBigCircleFailure() throws IOException {
- Rectangle rect = ctx.makeRectangle(-162, 89, -46, 38);
- GeoCircle rawShape = new GeoCircle(-9 * DEGREES_TO_RADIANS, 134 * DEGREES_TO_RADIANS, 159 * DEGREES_TO_RADIANS);
- Shape shape = new Geo3dShape(rawShape, ctx);
- assertTrue(rect.relate(shape).intersects() == false); //DWS: unsure if this is correct or not but passes
- //since they don't intersect, then the following cell rect can't be WITHIN the circle
- final Rectangle cellRect = ctx.makeRectangle(-11.25, 0, 0, 5.625);
- assert cellRect.relate(rect).intersects();
- assertTrue(cellRect.relate(shape) != SpatialRelation.WITHIN);
- }
-
- @Test
- public void testWideRectFailure() throws IOException {
- Rectangle rect = ctx.makeRectangle(-29, 9, 16, 25);
- final GeoBBox geoBBox = GeoBBoxFactory.makeGeoBBox(
- 74 * DEGREES_TO_RADIANS, -31 * DEGREES_TO_RADIANS, -29 * DEGREES_TO_RADIANS, -45 * DEGREES_TO_RADIANS);
- Shape shape = new Geo3dShape(geoBBox, ctx);
- //Rect(minX=-22.5,maxX=-11.25,minY=11.25,maxY=16.875)
- //since they don't intersect, then the following cell rect can't be WITHIN the geo3d shape
- final Rectangle cellRect = ctx.makeRectangle(-22.5, -11.25, 11.25, 16.875);
- assert cellRect.relate(rect).intersects();
- assertTrue(rect.relate(shape).intersects() == false);
- assertTrue(cellRect.relate(shape) != SpatialRelation.WITHIN);
-// setupStrategy();
-// testOperation(rect, SpatialOperation.Intersects, shape, false);
- }
-
private Shape makeTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
final List<GeoPoint> geoPoints = new ArrayList<>();
geoPoints.add(new GeoPoint(y1 * DEGREES_TO_RADIANS, x1 * DEGREES_TO_RADIANS));
@@ -159,7 +128,7 @@ public class Geo3dRptTest extends Random
case 1: {
// Circles
while (true) {
- final int circleRadius = random().nextInt(180);
+ final int circleRadius = random().nextInt(179) + 1;
final Point point = randomPoint();
try {
final GeoShape shape = new GeoCircle(point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
@@ -188,6 +157,7 @@ public class Geo3dRptTest extends Random
lrhcPoint.getY() * DEGREES_TO_RADIANS,
ulhcPoint.getX() * DEGREES_TO_RADIANS,
lrhcPoint.getX() * DEGREES_TO_RADIANS);
+ //System.err.println("Trial rectangle shape: "+shape);
return new Geo3dShape(shape, ctx);
} catch (IllegalArgumentException e) {
// This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where