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/05/04 15:19:03 UTC
svn commit: r1677595 [6/9] - in
/lucene/dev/branches/lucene6196/lucene/spatial/src:
java/org/apache/lucene/spatial/spatial4j/geo3d/
test/org/apache/lucene/spatial/spatial4j/
test/org/apache/lucene/spatial/spatial4j/geo3d/
Modified: 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=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java Mon May 4 13:19:02 2015
@@ -17,255 +17,250 @@ package org.apache.lucene.spatial.spatia
* 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);
- }
-
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @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;
+/**
+ * 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);
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @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 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);
- }
+ 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=1677595&r1=1677594&r2=1677595&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 Mon May 4 13:19:02 2015
@@ -17,273 +17,268 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Bounding box wider than PI but limited on four sides (top lat,
-* bottom lat, left lon, right lon).
-*/
-public class GeoWideRectangle extends GeoBBoxBase
-{
- public final double topLat;
- public final double bottomLat;
- public final double leftLon;
- public final double rightLon;
-
- public final double cosMiddleLat;
-
- public final GeoPoint ULHC;
- public final GeoPoint URHC;
- public final GeoPoint LRHC;
- public final GeoPoint LLHC;
-
- public final SidedPlane topPlane;
- 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;
-
- public final GeoPoint[] edgePoints;
-
- /** 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 GeoWideRectangle(final double topLat, final double bottomLat, 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 (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Bottom latitude out of range");
- if (topLat < bottomLat)
- throw new IllegalArgumentException("Top latitude less than bottom latitude");
- 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.bottomLat = bottomLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinTopLat = Math.sin(topLat);
- final double cosTopLat = Math.cos(topLat);
- 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.ULHC = new GeoPoint(sinTopLat,sinLeftLon,cosTopLat,cosLeftLon);
- this.URHC = new GeoPoint(sinTopLat,sinRightLon,cosTopLat,cosRightLon);
- this.LRHC = new GeoPoint(sinBottomLat,sinRightLon,cosBottomLat,cosRightLon);
- this.LLHC = new GeoPoint(sinBottomLat,sinLeftLon,cosBottomLat,cosLeftLon);
-
- final double middleLat = (topLat + 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.topPlane = new SidedPlane(centerPoint,sinTopLat);
- 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};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- final double newTopLat = topLat + angle;
- 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 topPlane.isWithin(point) &&
- bottomPlane.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) &&
- 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 topAngle = centerPoint.arcDistance(URHC);
- final double bottomAngle = centerPoint.arcDistance(LLHC);
- return Math.max(centerAngle,Math.max(topAngle,bottomAngle));
- }
-
- @Override
- public GeoPoint[] getEdgePoints()
- {
- return edgePoints;
- }
-
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @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,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.
- *@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).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(ULHC);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane,topPlanePoints,bottomPlane,eitherBound) ||
- path.intersects(bottomPlane,bottomPlanePoints,topPlane,eitherBound) ||
- path.intersects(leftPlane,leftPlanePoints,topPlane,bottomPlane) ||
- path.intersects(rightPlane,rightPlanePoints,topPlane,bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoWideRectangle))
- return false;
- GeoWideRectangle other = (GeoWideRectangle)o;
- return other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
- }
-
- @Override
- public int hashCode() {
- int result = ULHC.hashCode();
- result = 31 * result + LRHC.hashCode();
- return result;
+/**
+ * Bounding box wider than PI but limited on four sides (top lat,
+ * bottom lat, left lon, right lon).
+ */
+public class GeoWideRectangle extends GeoBBoxBase {
+ public final double topLat;
+ public final double bottomLat;
+ public final double leftLon;
+ public final double rightLon;
+
+ public final double cosMiddleLat;
+
+ public final GeoPoint ULHC;
+ public final GeoPoint URHC;
+ public final GeoPoint LRHC;
+ public final GeoPoint LLHC;
+
+ public final SidedPlane topPlane;
+ 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;
+
+ public final GeoPoint[] edgePoints;
+
+ /**
+ * 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 GeoWideRectangle(final double topLat, final double bottomLat, 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 (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (topLat < bottomLat)
+ throw new IllegalArgumentException("Top latitude less than bottom latitude");
+ 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.bottomLat = bottomLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ 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.ULHC = new GeoPoint(sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
+ this.URHC = new GeoPoint(sinTopLat, sinRightLon, cosTopLat, cosRightLon);
+ this.LRHC = new GeoPoint(sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
+ this.LLHC = new GeoPoint(sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
+
+ final double middleLat = (topLat + 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.topPlane = new SidedPlane(centerPoint, sinTopLat);
+ 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};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ 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 topPlane.isWithin(point) &&
+ bottomPlane.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) &&
+ 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 topAngle = centerPoint.arcDistance(URHC);
+ final double bottomAngle = centerPoint.arcDistance(LLHC);
+ return Math.max(centerAngle, Math.max(topAngle, bottomAngle));
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @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, 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.
+ *
+ * @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).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(ULHC);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" both inside each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
+ path.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
+ path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" rectangle inside shape");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideRectangle))
+ return false;
+ GeoWideRectangle other = (GeoWideRectangle) o;
+ return other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ULHC.hashCode();
+ result = 31 * result + LRHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideRectangle: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), 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 String toString() {
- return "GeoWideRectangle: {toplat="+topLat+"("+topLat*180.0/Math.PI+"), 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);
- }
+ 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/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=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java Mon May 4 13:19:02 2015
@@ -17,251 +17,246 @@ package org.apache.lucene.spatial.spatia
* 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);
- }
-
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @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;
+/**
+ * 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);
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @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 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);
- }
+ 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=1677595&r1=1677594&r2=1677595&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 Mon May 4 13:19:02 2015
@@ -17,102 +17,97 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Bounding box including the entire world.
-*/
-public class GeoWorld extends GeoBBoxBase
-{
- protected final static GeoPoint originPoint = new GeoPoint(1.0,0.0,0.0);
- protected final static GeoPoint[] edgePoints = new GeoPoint[0];
-
- public GeoWorld()
- {
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- return this;
- }
-
- @Override
- public double getRadius()
- {
- return Math.PI;
- }
-
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- @Override
- public GeoPoint getCenter() {
- // Totally arbitrary
- return originPoint;
- }
-
- @Override
- public boolean isWithin(final Vector point)
- {
- return true;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return true;
- }
-
- @Override
- public GeoPoint[] getEdgePoints()
- {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
- {
- return false;
- }
-
- /** 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().noBottomLatitudeBound();
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- if (path.getEdgePoints().length > 0)
- // Path is always within the world
- return WITHIN;
-
- return OVERLAPS;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoWorld))
- return false;
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- @Override
- public String toString() {
- return "GeoWorld";
- }
+/**
+ * Bounding box including the entire world.
+ */
+public class GeoWorld extends GeoBBoxBase {
+ protected final static GeoPoint originPoint = new GeoPoint(1.0, 0.0, 0.0);
+ protected final static GeoPoint[] edgePoints = new GeoPoint[0];
+
+ public GeoWorld() {
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ return this;
+ }
+
+ @Override
+ public double getRadius() {
+ return Math.PI;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ // Totally arbitrary
+ return originPoint;
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return true;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return true;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return false;
+ }
+
+ /**
+ * 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().noBottomLatitudeBound();
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ if (path.getEdgePoints().length > 0)
+ // Path is always within the world
+ return WITHIN;
+
+ return OVERLAPS;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWorld))
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWorld";
+ }
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java Mon May 4 13:19:02 2015
@@ -17,22 +17,27 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Interface describing 3d shape membership methods.
-*/
+/**
+ * Interface describing 3d shape membership methods.
+ */
public interface Membership {
- /** Check if a point is within this shape.
- *@param point is the point to check.
- *@return true if the point is within this shape
- */
- public boolean isWithin(final Vector point);
+ /**
+ * Check if a point is within this shape.
+ *
+ * @param point is the point to check.
+ * @return true if the point is within this shape
+ */
+ public boolean isWithin(final Vector point);
- /** Check if a point is within this shape.
- *@param x is x coordinate of point to check.
- *@param y is y coordinate of point to check.
- *@param z is z coordinate of point to check.
- *@return true if the point is within this shape
- */
- public boolean isWithin(final double x, final double y, final double z);
+ /**
+ * Check if a point is within this shape.
+ *
+ * @param x is x coordinate of point to check.
+ * @param y is y coordinate of point to check.
+ * @param z is z coordinate of point to check.
+ * @return true if the point is within this shape
+ */
+ public boolean isWithin(final double x, final double y, final double z);
}