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 [5/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/GeoRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java Mon May 4 13:19:02 2015
@@ -17,250 +17,246 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Bounding box limited on four sides (top lat, bottom lat, left lon, right lon).
-* The left-right maximum extent for this shape is PI; for anything larger, use
-* GeoWideRectangle.
-*/
-public class GeoRectangle 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 GeoPoint[] edgePoints;
-
- /** Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI} */
- public GeoRectangle(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 great");
-
- 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.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)
- {
- return p.intersects(topPlane,notablePoints,topPlanePoints,bounds,bottomPlane,leftPlane,rightPlane) ||
- p.intersects(bottomPlane,notablePoints,bottomPlanePoints,bounds,topPlane,leftPlane,rightPlane) ||
- p.intersects(leftPlane,notablePoints,leftPlanePoints,bounds,rightPlane,topPlane,bottomPlane) ||
- p.intersects(rightPlane,notablePoints,rightPlanePoints,bounds,leftPlane,topPlane,bottomPlane);
- }
-
- /** Compute longitude/latitude bounds for the shape.
- *@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+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(ULHC);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane,topPlanePoints,bottomPlane,leftPlane,rightPlane) ||
- path.intersects(bottomPlane,bottomPlanePoints,topPlane,leftPlane,rightPlane) ||
- path.intersects(leftPlane,leftPlanePoints,topPlane,bottomPlane,rightPlane) ||
- path.intersects(rightPlane,rightPlanePoints,leftPlane,topPlane,bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE)
- {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoRectangle))
- return false;
- GeoRectangle other = (GeoRectangle)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 "GeoRectangle: {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+")}";
- }
+/**
+ * Bounding box limited on four sides (top lat, bottom lat, left lon, right lon).
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * GeoWideRectangle.
+ */
+public class GeoRectangle 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 GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ */
+ public GeoRectangle(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 great");
+
+ 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.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) {
+ return p.intersects(topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, leftPlane, rightPlane) ||
+ p.intersects(bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, leftPlane, rightPlane) ||
+ p.intersects(leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane, bottomPlane) ||
+ p.intersects(rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
+ }
+
+ /**
+ * Compute longitude/latitude bounds for the shape.
+ *
+ * @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+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(ULHC);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
+ path.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
+ path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane, rightPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoRectangle))
+ return false;
+ GeoRectangle other = (GeoRectangle) 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 "GeoRectangle: {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 + ")}";
+ }
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java Mon May 4 13:19:02 2015
@@ -17,44 +17,53 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Generic shape. This describes methods that help GeoAreas figure out
-* how they interact with a shape, for the purposes of coming up with a
-* set of geo hash values.
-*/
+/**
+ * Generic shape. This describes methods that help GeoAreas figure out
+ * how they interact with a shape, for the purposes of coming up with a
+ * set of geo hash values.
+ */
public interface GeoShape extends Membership {
- /** Return a sample point that is on the outside edge/boundary of the shape.
- *@return samples of all edge points from distinct edge sections. Typically one point
- * is returned, but zero or two are also possible.
- */
- public GeoPoint[] getEdgePoints();
-
- /** Assess whether a plane, within the provided bounds, intersects
- * with the shape. Note well that this method is allowed to return "true"
- * if there are internal edges of a composite shape which intersect the plane.
- * Doing this can cause getRelationship() for most GeoBBox shapes to return
- * OVERLAPS rather than the more correct CONTAINS, but that cannot be
- * helped for some complex shapes that are built out of overlapping parts.
- *@param plane is the plane to assess for intersection with the shape's edges or
- * bounding curves.
- *@param notablePoints represents the intersections of the plane with the supplied
- * bounds. These are used to disambiguate when two planes are identical and it needs
- * to be determined whether any points exist that fulfill all the bounds.
- *@param bounds are a set of bounds that define an area that an
- * intersection must be within in order to qualify (provided by a GeoArea).
- *@return true if there's such an intersection, false if not.
- */
- public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds);
+ /**
+ * Return a sample point that is on the outside edge/boundary of the shape.
+ *
+ * @return samples of all edge points from distinct edge sections. Typically one point
+ * is returned, but zero or two are also possible.
+ */
+ public GeoPoint[] getEdgePoints();
+
+ /**
+ * Assess whether a plane, within the provided bounds, intersects
+ * with the shape. Note well that this method is allowed to return "true"
+ * if there are internal edges of a composite shape which intersect the plane.
+ * Doing this can cause getRelationship() for most GeoBBox shapes to return
+ * OVERLAPS rather than the more correct CONTAINS, but that cannot be
+ * helped for some complex shapes that are built out of overlapping parts.
+ *
+ * @param plane is the plane to assess for intersection with the shape's edges or
+ * bounding curves.
+ * @param notablePoints represents the intersections of the plane with the supplied
+ * bounds. These are used to disambiguate when two planes are identical and it needs
+ * to be determined whether any points exist that fulfill all the bounds.
+ * @param bounds are a set of bounds that define an area that an
+ * intersection must be within in order to qualify (provided by a GeoArea).
+ * @return true if there's such an intersection, false if not.
+ */
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds);
- /** Compute longitude/latitude bounds for the shape.
- *@param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- *@return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
- public Bounds getBounds(final Bounds bounds);
+ /**
+ * Compute longitude/latitude bounds for the shape.
+ *
+ * @param bounds is the optional input bounds object. If this is null,
+ * a bounds object will be created. Otherwise, the input object will be modified.
+ * @return a Bounds object describing the shape's bounds. If the bounds cannot
+ * be computed, then return a Bounds object with noLongitudeBound,
+ * noTopLatitudeBound, and noBottomLatitudeBound.
+ */
+ public Bounds getBounds(final Bounds bounds);
- /** Equals */
- public boolean equals(Object o);
+ /**
+ * Equals
+ */
+ public boolean equals(Object o);
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSizeable.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSizeable.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSizeable.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSizeable.java Mon May 4 13:19:02 2015
@@ -17,19 +17,23 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Some shapes can compute radii of a geocircle in which they are inscribed.
-*/
-public interface GeoSizeable
-{
- /** Returns the radius of a circle into which the GeoSizeable area can
- * be inscribed.
- *@return the radius.
- */
- public double getRadius();
+/**
+ * Some shapes can compute radii of a geocircle in which they are inscribed.
+ */
+public interface GeoSizeable {
+ /**
+ * Returns the radius of a circle into which the GeoSizeable area can
+ * be inscribed.
+ *
+ * @return the radius.
+ */
+ public double getRadius();
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ public GeoPoint getCenter();
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- public GeoPoint getCenter();
-
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java Mon May 4 13:19:02 2015
@@ -17,159 +17,154 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** This GeoBBox represents an area rectangle limited only in north latitude.
-*/
-public class GeoSouthLatitudeZone extends GeoBBoxBase
-{
- public final double topLat;
- public final double cosTopLat;
- public final SidedPlane topPlane;
- public final GeoPoint interiorPoint;
- public final static GeoPoint[] planePoints = new GeoPoint[0];
-
- public final GeoPoint topBoundaryPoint;
-
- // Edge points
- public final GeoPoint[] edgePoints;
-
- public GeoSouthLatitudeZone(final double topLat)
- {
- this.topLat = topLat;
-
- final double sinTopLat = Math.sin(topLat);
- this.cosTopLat = Math.cos(topLat);
-
- // Construct sample points, so we get our sidedness right
- final Vector topPoint = new Vector(0.0,0.0,sinTopLat);
-
- // Compute an interior point. Pick one whose lat is between top and bottom.
- final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.interiorPoint = new GeoPoint(Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat),0.0,sinMiddleLat);
- this.topBoundaryPoint = new GeoPoint(Math.sqrt(1.0 - sinTopLat * sinTopLat),0.0,sinTopLat);
-
- this.topPlane = new SidedPlane(interiorPoint,sinTopLat);
-
- this.edgePoints = new GeoPoint[]{topBoundaryPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- final double newTopLat = topLat + angle;
- final double newBottomLat = -Math.PI * 0.5;
- return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
- }
-
- @Override
- public boolean isWithin(final Vector point)
- {
- return topPlane.isWithin(point);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return topPlane.isWithin(x,y,z);
- }
-
- @Override
- public double getRadius()
- {
- // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
- // would contain all the bounding box points, when starting in the "center".
- if (topLat > 0.0)
- return Math.PI;
- double maxCosLat = cosTopLat;
- return maxCosLat * Math.PI;
- }
-
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints()
- {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
- {
- return p.intersects(topPlane,notablePoints,planePoints,bounds);
- }
-
- /** Compute longitude/latitude bounds for the shape.
- *@param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- *@return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
- @Override
- public Bounds getBounds(Bounds bounds)
- {
- if (bounds == null)
- bounds = new Bounds();
- bounds.noLongitudeBound().addLatitudeZone(topLat).noBottomLatitudeBound();
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(topBoundaryPoint);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(topPlane,planePoints))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoSouthLatitudeZone))
- return false;
- GeoSouthLatitudeZone other = (GeoSouthLatitudeZone)o;
- return other.topPlane.equals(topPlane);
- }
-
- @Override
- public int hashCode() {
- int result = topPlane.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoSouthLatitudeZone: {toplat="+topLat+"("+topLat*180.0/Math.PI+")}";
- }
+/**
+ * This GeoBBox represents an area rectangle limited only in north latitude.
+ */
+public class GeoSouthLatitudeZone extends GeoBBoxBase {
+ public final double topLat;
+ public final double cosTopLat;
+ public final SidedPlane topPlane;
+ public final GeoPoint interiorPoint;
+ public final static GeoPoint[] planePoints = new GeoPoint[0];
+
+ public final GeoPoint topBoundaryPoint;
+
+ // Edge points
+ public final GeoPoint[] edgePoints;
+
+ public GeoSouthLatitudeZone(final double topLat) {
+ this.topLat = topLat;
+
+ final double sinTopLat = Math.sin(topLat);
+ this.cosTopLat = Math.cos(topLat);
+
+ // Construct sample points, so we get our sidedness right
+ final Vector topPoint = new Vector(0.0, 0.0, sinTopLat);
+
+ // Compute an interior point. Pick one whose lat is between top and bottom.
+ final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.interiorPoint = new GeoPoint(Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 0.0, sinMiddleLat);
+ this.topBoundaryPoint = new GeoPoint(Math.sqrt(1.0 - sinTopLat * sinTopLat), 0.0, sinTopLat);
+
+ this.topPlane = new SidedPlane(interiorPoint, sinTopLat);
+
+ this.edgePoints = new GeoPoint[]{topBoundaryPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return topPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
+ // would contain all the bounding box points, when starting in the "center".
+ if (topLat > 0.0)
+ return Math.PI;
+ double maxCosLat = cosTopLat;
+ return maxCosLat * Math.PI;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(topPlane, notablePoints, planePoints, bounds);
+ }
+
+ /**
+ * Compute longitude/latitude bounds for the shape.
+ *
+ * @param bounds is the optional input bounds object. If this is null,
+ * a bounds object will be created. Otherwise, the input object will be modified.
+ * @return a Bounds object describing the shape's bounds. If the bounds cannot
+ * be computed, then return a Bounds object with noLongitudeBound,
+ * noTopLatitudeBound, and noBottomLatitudeBound.
+ */
+ @Override
+ public Bounds getBounds(Bounds bounds) {
+ if (bounds == null)
+ bounds = new Bounds();
+ bounds.noLongitudeBound().addLatitudeZone(topLat).noBottomLatitudeBound();
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean insideShape = path.isWithin(topBoundaryPoint);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ // Second, the shortcut of seeing whether endpoints are in/out is not going to
+ // work with no area endpoints. So we rely entirely on intersections.
+
+ if (path.intersects(topPlane, planePoints))
+ return OVERLAPS;
+
+ // There is another case for latitude zones only. This is when the boundaries of the shape all fit
+ // within the zone, but the shape includes areas outside the zone crossing a pole.
+ // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
+ // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
+ // one such point is within, then OVERLAPS is the right answer.
+
+ if (insideShape)
+ return CONTAINS;
+
+ if (insideRectangle == ALL_INSIDE)
+ return WITHIN;
+
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoSouthLatitudeZone))
+ return false;
+ GeoSouthLatitudeZone other = (GeoSouthLatitudeZone) o;
+ return other.topPlane.equals(topPlane);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = topPlane.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoSouthLatitudeZone: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + ")}";
+ }
}
Modified: 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=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java Mon May 4 13:19:02 2015
@@ -17,230 +17,225 @@ package org.apache.lucene.spatial.spatia
* 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;
- }
-
- /** 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)
- {
- 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+")}";
- }
+/**
+ * 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;
+ }
+
+ /**
+ * 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) {
+ 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=1677595&r1=1677594&r2=1677595&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 Mon May 4 13:19:02 2015
@@ -17,219 +17,215 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Degenerate bounding box wider than PI and limited on two sides (left lon, right lon).
-*/
-public class GeoWideDegenerateHorizontalLine extends GeoBBoxBase
-{
- public final double latitude;
- public final double leftLon;
- public final double rightLon;
-
- public final GeoPoint LHC;
- public final GeoPoint RHC;
-
- public final Plane plane;
- public final SidedPlane leftPlane;
- public final SidedPlane rightPlane;
-
- public final GeoPoint[] planePoints;
-
- 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 GeoWideDegenerateHorizontalLine(final double latitude, final double leftLon, double rightLon)
- {
- // Argument checking
- if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
- throw new IllegalArgumentException("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.latitude = latitude;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinLatitude = Math.sin(latitude);
- final double cosLatitude = Math.cos(latitude);
- 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 two points
- this.LHC = new GeoPoint(sinLatitude,sinLeftLon,cosLatitude,cosLeftLon);
- this.RHC = new GeoPoint(sinLatitude,sinRightLon,cosLatitude,cosRightLon);
-
- this.plane = new Plane(sinLatitude);
-
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- double middleLon = (leftLon + rightLon) * 0.5;
- double sinMiddleLon = Math.sin(middleLon);
- double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(sinLatitude,sinMiddleLon,cosLatitude,cosMiddleLon);
-
- 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};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- final double newTopLat = latitude + angle;
- final double newBottomLat = latitude - 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)
- {
- if (point == null)
- return false;
- return plane.evaluateIsZero(point) &&
- (leftPlane.isWithin(point) ||
- rightPlane.isWithin(point));
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return plane.evaluateIsZero(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 topAngle = centerPoint.arcDistance(RHC);
- final double bottomAngle = centerPoint.arcDistance(LHC);
- return Math.max(topAngle,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(plane,notablePoints,planePoints,bounds,eitherBound);
- }
-
- /** 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(latitude)
- .addLongitudeSlice(leftLon,rightLon);
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- if (path.intersects(plane,planePoints,eitherBound)) {
- return OVERLAPS;
- }
-
- if (path.isWithin(centerPoint)) {
- return CONTAINS;
- }
-
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoWideDegenerateHorizontalLine))
- return false;
- GeoWideDegenerateHorizontalLine other = (GeoWideDegenerateHorizontalLine)o;
- return other.LHC.equals(LHC) && other.RHC.equals(RHC);
- }
-
- @Override
- public int hashCode() {
- int result = LHC.hashCode();
- result = 31 * result + RHC.hashCode();
- return result;
+/**
+ * Degenerate bounding box wider than PI and limited on two sides (left lon, right lon).
+ */
+public class GeoWideDegenerateHorizontalLine extends GeoBBoxBase {
+ public final double latitude;
+ public final double leftLon;
+ public final double rightLon;
+
+ public final GeoPoint LHC;
+ public final GeoPoint RHC;
+
+ public final Plane plane;
+ public final SidedPlane leftPlane;
+ public final SidedPlane rightPlane;
+
+ public final GeoPoint[] planePoints;
+
+ 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 GeoWideDegenerateHorizontalLine(final double latitude, final double leftLon, double rightLon) {
+ // Argument checking
+ if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
+ throw new IllegalArgumentException("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.latitude = latitude;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinLatitude = Math.sin(latitude);
+ final double cosLatitude = Math.cos(latitude);
+ 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 two points
+ this.LHC = new GeoPoint(sinLatitude, sinLeftLon, cosLatitude, cosLeftLon);
+ this.RHC = new GeoPoint(sinLatitude, sinRightLon, cosLatitude, cosRightLon);
+
+ this.plane = new Plane(sinLatitude);
+
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ double middleLon = (leftLon + rightLon) * 0.5;
+ double sinMiddleLon = Math.sin(middleLon);
+ double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
+
+ 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};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = latitude + angle;
+ final double newBottomLat = latitude - 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) {
+ if (point == null)
+ return false;
+ return plane.evaluateIsZero(point) &&
+ (leftPlane.isWithin(point) ||
+ rightPlane.isWithin(point));
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(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 topAngle = centerPoint.arcDistance(RHC);
+ final double bottomAngle = centerPoint.arcDistance(LHC);
+ return Math.max(topAngle, 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(plane, notablePoints, planePoints, bounds, eitherBound);
+ }
+
+ /**
+ * 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(latitude)
+ .addLongitudeSlice(leftLon, rightLon);
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ if (path.intersects(plane, planePoints, eitherBound)) {
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(centerPoint)) {
+ return CONTAINS;
+ }
+
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideDegenerateHorizontalLine))
+ return false;
+ GeoWideDegenerateHorizontalLine other = (GeoWideDegenerateHorizontalLine) o;
+ return other.LHC.equals(LHC) && other.RHC.equals(RHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = LHC.hashCode();
+ result = 31 * result + RHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideDegenerateHorizontalLine: {latitude=" + latitude + "(" + latitude * 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 "GeoWideDegenerateHorizontalLine: {latitude="+latitude+"("+latitude*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/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=1677595&r1=1677594&r2=1677595&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 Mon May 4 13:19:02 2015
@@ -17,186 +17,182 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Bounding box wider than PI but limited on left and right sides (
-* left lon, right lon).
-*/
-public class GeoWideLongitudeSlice extends GeoBBoxBase
-{
- public final double leftLon;
- public final double rightLon;
-
- 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 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.
- */
- public GeoWideLongitudeSlice(final double leftLon, double rightLon)
- {
- // Argument checking
- 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.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- this.centerPoint = new GeoPoint(0.0,middleLon);
-
- this.leftPlane = new SidedPlane(centerPoint,cosLeftLon,sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint,cosRightLon,sinRightLon);
- }
-
- @Override
- public GeoBBox expand(final double 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(Math.PI * 0.5,-Math.PI * 0.5,newLeftLon,newRightLon);
- }
-
- @Override
- public boolean isWithin(final Vector point)
- {
- return leftPlane.isWithin(point) ||
- rightPlane.isWithin(point);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return leftPlane.isWithin(x,y,z) ||
- rightPlane.isWithin(x,y,z);
- }
-
- @Override
- public double getRadius()
- {
- // Compute the extent and divide by two
- double extent = rightLon - leftLon;
- if (extent < 0.0)
- extent += Math.PI * 2.0;
- return Math.max(Math.PI * 0.5, extent * 0.5);
- }
-
- /** 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(leftPlane,notablePoints,planePoints,bounds) ||
- p.intersects(rightPlane,notablePoints,planePoints,bounds);
- }
-
- /** Compute longitude/latitude bounds for the shape.
- *@param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- *@return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
- @Override
- public Bounds getBounds(Bounds bounds)
- {
- if (bounds == null)
- bounds = new Bounds();
- bounds.noTopLatitudeBound().noBottomLatitudeBound();
- bounds.addLongitudeSlice(leftLon,rightLon);
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- if (path.intersects(leftPlane,planePoints) ||
- path.intersects(rightPlane,planePoints))
- return OVERLAPS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- if (insideShape)
- return CONTAINS;
-
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoWideLongitudeSlice))
- return false;
- GeoWideLongitudeSlice other = (GeoWideLongitudeSlice)o;
- return other.leftLon == leftLon && other.rightLon == rightLon;
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- temp = Double.doubleToLongBits(leftLon);
- result = (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(rightLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoWideLongitudeSlice: {leftlon="+leftLon+"("+leftLon*180.0/Math.PI+"), rightlon="+rightLon+"("+rightLon*180.0/Math.PI+")}";
- }
+/**
+ * Bounding box wider than PI but limited on left and right sides (
+ * left lon, right lon).
+ */
+public class GeoWideLongitudeSlice extends GeoBBoxBase {
+ public final double leftLon;
+ public final double rightLon;
+
+ 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 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.
+ */
+ public GeoWideLongitudeSlice(final double leftLon, double rightLon) {
+ // Argument checking
+ 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.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ this.centerPoint = new GeoPoint(0.0, middleLon);
+
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+ }
+
+ @Override
+ public GeoBBox expand(final double 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(Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return leftPlane.isWithin(point) ||
+ rightPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) ||
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Compute the extent and divide by two
+ double extent = rightLon - leftLon;
+ if (extent < 0.0)
+ extent += Math.PI * 2.0;
+ return Math.max(Math.PI * 0.5, extent * 0.5);
+ }
+
+ /**
+ * 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(leftPlane, notablePoints, planePoints, bounds) ||
+ p.intersects(rightPlane, notablePoints, planePoints, bounds);
+ }
+
+ /**
+ * Compute longitude/latitude bounds for the shape.
+ *
+ * @param bounds is the optional input bounds object. If this is null,
+ * a bounds object will be created. Otherwise, the input object will be modified.
+ * @return a Bounds object describing the shape's bounds. If the bounds cannot
+ * be computed, then return a Bounds object with noLongitudeBound,
+ * noTopLatitudeBound, and noBottomLatitudeBound.
+ */
+ @Override
+ public Bounds getBounds(Bounds bounds) {
+ if (bounds == null)
+ bounds = new Bounds();
+ bounds.noTopLatitudeBound().noBottomLatitudeBound();
+ bounds.addLongitudeSlice(leftLon, rightLon);
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean insideShape = path.isWithin(NORTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ if (path.intersects(leftPlane, planePoints) ||
+ path.intersects(rightPlane, planePoints))
+ return OVERLAPS;
+
+ if (insideRectangle == ALL_INSIDE)
+ return WITHIN;
+
+ if (insideShape)
+ return CONTAINS;
+
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideLongitudeSlice))
+ return false;
+ GeoWideLongitudeSlice other = (GeoWideLongitudeSlice) o;
+ return other.leftLon == leftLon && other.rightLon == rightLon;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(leftLon);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(rightLon);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideLongitudeSlice: {leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
}