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 [2/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/GeoConvexPolygon.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java Mon May 4 13:19:02 2015
@@ -21,250 +21,251 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
-/** GeoConvexPolygon objects are generic building blocks of more complex structures.
-* The only restrictions on these objects are: (1) they must be convex; (2) they must have
-* a maximum extent no larger than PI. Violating either one of these limits will
-* cause the logic to fail.
-*/
-public class GeoConvexPolygon extends GeoBaseExtendedShape implements GeoMembershipShape
-{
- protected final List<GeoPoint> points;
- protected final BitSet isInternalEdges;
-
- protected SidedPlane[] edges = null;
- protected boolean[] internalEdges = null;
- protected GeoPoint[][] notableEdgePoints = null;
-
- protected GeoPoint[] edgePoints = null;
-
- protected double fullDistance = 0.0;
-
- /** Create a convex polygon from a list of points. The first point must be on the
- * external edge.
- */
- public GeoConvexPolygon(final List<GeoPoint> pointList) {
- this.points = pointList;
- this.isInternalEdges = null;
- donePoints(false);
- }
-
- /** Create a convex polygon from a list of points, keeping track of which boundaries
- * are internal. This is used when creating a polygon as a building block for another shape.
- */
- public GeoConvexPolygon(final List<GeoPoint> pointList, final BitSet internalEdgeFlags, final boolean returnEdgeInternal) {
- this.points = pointList;
- this.isInternalEdges = internalEdgeFlags;
- donePoints(returnEdgeInternal);
- }
-
- /** Create a convex polygon, with a starting latitude and longitude.
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- */
- public GeoConvexPolygon(final double startLatitude, final double startLongitude)
- {
- points = new ArrayList<GeoPoint>();
- isInternalEdges = new BitSet();
- // Argument checking
- if (startLatitude > Math.PI * 0.5 || startLatitude < -Math.PI * 0.5)
- throw new IllegalArgumentException("Latitude out of range");
- if (startLongitude < -Math.PI || startLongitude > Math.PI)
- throw new IllegalArgumentException("Longitude out of range");
-
- final GeoPoint p = new GeoPoint(startLatitude, startLongitude);
- points.add(p);
- }
-
- /** Add a point to the polygon.
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *@param latitude is the latitude of the next point.
- *@param longitude is the longitude of the next point.
- *@param isInternalEdge is true if the edge just added should be considered "internal", and not
- * intersected as part of the intersects() operation.
- */
- public void addPoint(final double latitude, final double longitude, final boolean isInternalEdge) {
- // Argument checking
- if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
- throw new IllegalArgumentException("Latitude out of range");
- if (longitude < -Math.PI || longitude > Math.PI)
- throw new IllegalArgumentException("Longitude out of range");
-
- final GeoPoint p = new GeoPoint(latitude, longitude);
- isInternalEdges.set(points.size(),isInternalEdge);
- points.add(p);
- }
-
- /** Finish the polygon, by connecting the last added point with the starting point.
- */
- public void donePoints(final boolean isInternalReturnEdge) {
- // If fewer than 3 points, can't do it.
- if (points.size() < 3)
- throw new IllegalArgumentException("Polygon needs at least three points.");
- // Time to construct the planes. If the polygon is truly convex, then any adjacent point
- // to a segment can provide an interior measurement.
- edges = new SidedPlane[points.size()];
- notableEdgePoints = new GeoPoint[points.size()][];
- internalEdges = new boolean[points.size()];
- for (int i = 0; i < points.size(); i++) {
- final GeoPoint start = points.get(i);
- final boolean isInternalEdge = (isInternalEdges!=null?(i == isInternalEdges.size()?isInternalReturnEdge:isInternalEdges.get(i)):false);
- final GeoPoint end = points.get(legalIndex(i+1));
- final double distance = start.arcDistance(end);
- if (distance > fullDistance)
- fullDistance = distance;
- final GeoPoint check = points.get(legalIndex(i+2));
- final SidedPlane sp = new SidedPlane(check,start,end);
- //System.out.println("Created edge "+sp+" using start="+start+" end="+end+" check="+check);
- edges[i] = sp;
- notableEdgePoints[i] = new GeoPoint[]{start,end};
- internalEdges[i] = isInternalEdge;
- }
- createCenterPoint();
- }
-
- protected void createCenterPoint() {
- // In order to naively confirm that the polygon is convex, I would need to
- // check every edge, and verify that every point (other than the edge endpoints)
- // is within the edge's sided plane. This is an order n^2 operation. That's still
- // not wrong, though, because everything else about polygons has a similar cost.
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final SidedPlane edge = edges[edgeIndex];
- for (int pointIndex =0; pointIndex < points.size(); pointIndex++) {
- if (pointIndex != edgeIndex && pointIndex != legalIndex(edgeIndex+1)) {
- if (!edge.isWithin(points.get(pointIndex)))
- throw new IllegalArgumentException("Polygon is not convex: Point "+points.get(pointIndex)+" Edge "+edge);
- }
- }
- }
- edgePoints = new GeoPoint[]{points.get(0)};
- }
-
- protected int legalIndex(int index) {
- while (index >= points.size())
- index -= points.size();
- return index;
- }
-
- @Override
- public boolean isWithin(final Vector point)
- {
- for (final SidedPlane edge : edges) {
- if (!edge.isWithin(point))
- return false;
- }
- return true;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- for (final SidedPlane edge : edges) {
- if (!edge.isWithin(x,y,z))
- return false;
- }
- return true;
- }
-
- @Override
- public GeoPoint[] getEdgePoints()
- {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
- {
- //System.err.println("Checking for polygon intersection with plane "+p+"...");
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final SidedPlane edge = edges[edgeIndex];
- final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
- if (!internalEdges[edgeIndex]) {
- //System.err.println(" non-internal edge "+edge);
- // Edges flagged as 'internal only' are excluded from the matching
- // Construct boundaries
- final Membership[] membershipBounds = new Membership[edges.length-1];
- int count = 0;
- for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
- if (otherIndex != edgeIndex) {
- membershipBounds[count++] = edges[otherIndex];
- }
- }
- if (edge.intersects(p,notablePoints, points, bounds,membershipBounds)) {
- //System.err.println(" intersects!");
- return true;
- }
- }
- }
- //System.err.println(" no intersection");
+/**
+ * GeoConvexPolygon objects are generic building blocks of more complex structures.
+ * The only restrictions on these objects are: (1) they must be convex; (2) they must have
+ * a maximum extent no larger than PI. Violating either one of these limits will
+ * cause the logic to fail.
+ */
+public class GeoConvexPolygon extends GeoBaseExtendedShape implements GeoMembershipShape {
+ protected final List<GeoPoint> points;
+ protected final BitSet isInternalEdges;
+
+ protected SidedPlane[] edges = null;
+ protected boolean[] internalEdges = null;
+ protected GeoPoint[][] notableEdgePoints = null;
+
+ protected GeoPoint[] edgePoints = null;
+
+ protected double fullDistance = 0.0;
+
+ /**
+ * Create a convex polygon from a list of points. The first point must be on the
+ * external edge.
+ */
+ public GeoConvexPolygon(final List<GeoPoint> pointList) {
+ this.points = pointList;
+ this.isInternalEdges = null;
+ donePoints(false);
+ }
+
+ /**
+ * Create a convex polygon from a list of points, keeping track of which boundaries
+ * are internal. This is used when creating a polygon as a building block for another shape.
+ */
+ public GeoConvexPolygon(final List<GeoPoint> pointList, final BitSet internalEdgeFlags, final boolean returnEdgeInternal) {
+ this.points = pointList;
+ this.isInternalEdges = internalEdgeFlags;
+ donePoints(returnEdgeInternal);
+ }
+
+ /**
+ * Create a convex polygon, with a starting latitude and longitude.
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ */
+ public GeoConvexPolygon(final double startLatitude, final double startLongitude) {
+ points = new ArrayList<GeoPoint>();
+ isInternalEdges = new BitSet();
+ // Argument checking
+ if (startLatitude > Math.PI * 0.5 || startLatitude < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Latitude out of range");
+ if (startLongitude < -Math.PI || startLongitude > Math.PI)
+ throw new IllegalArgumentException("Longitude out of range");
+
+ final GeoPoint p = new GeoPoint(startLatitude, startLongitude);
+ points.add(p);
+ }
+
+ /**
+ * Add a point to the polygon.
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *
+ * @param latitude is the latitude of the next point.
+ * @param longitude is the longitude of the next point.
+ * @param isInternalEdge is true if the edge just added should be considered "internal", and not
+ * intersected as part of the intersects() operation.
+ */
+ public void addPoint(final double latitude, final double longitude, final boolean isInternalEdge) {
+ // Argument checking
+ if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Latitude out of range");
+ if (longitude < -Math.PI || longitude > Math.PI)
+ throw new IllegalArgumentException("Longitude out of range");
+
+ final GeoPoint p = new GeoPoint(latitude, longitude);
+ isInternalEdges.set(points.size(), isInternalEdge);
+ points.add(p);
+ }
+
+ /**
+ * Finish the polygon, by connecting the last added point with the starting point.
+ */
+ public void donePoints(final boolean isInternalReturnEdge) {
+ // If fewer than 3 points, can't do it.
+ if (points.size() < 3)
+ throw new IllegalArgumentException("Polygon needs at least three points.");
+ // Time to construct the planes. If the polygon is truly convex, then any adjacent point
+ // to a segment can provide an interior measurement.
+ edges = new SidedPlane[points.size()];
+ notableEdgePoints = new GeoPoint[points.size()][];
+ internalEdges = new boolean[points.size()];
+ for (int i = 0; i < points.size(); i++) {
+ final GeoPoint start = points.get(i);
+ final boolean isInternalEdge = (isInternalEdges != null ? (i == isInternalEdges.size() ? isInternalReturnEdge : isInternalEdges.get(i)) : false);
+ final GeoPoint end = points.get(legalIndex(i + 1));
+ final double distance = start.arcDistance(end);
+ if (distance > fullDistance)
+ fullDistance = distance;
+ final GeoPoint check = points.get(legalIndex(i + 2));
+ final SidedPlane sp = new SidedPlane(check, start, end);
+ //System.out.println("Created edge "+sp+" using start="+start+" end="+end+" check="+check);
+ edges[i] = sp;
+ notableEdgePoints[i] = new GeoPoint[]{start, end};
+ internalEdges[i] = isInternalEdge;
+ }
+ createCenterPoint();
+ }
+
+ protected void createCenterPoint() {
+ // In order to naively confirm that the polygon is convex, I would need to
+ // check every edge, and verify that every point (other than the edge endpoints)
+ // is within the edge's sided plane. This is an order n^2 operation. That's still
+ // not wrong, though, because everything else about polygons has a similar cost.
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) {
+ if (pointIndex != edgeIndex && pointIndex != legalIndex(edgeIndex + 1)) {
+ if (!edge.isWithin(points.get(pointIndex)))
+ throw new IllegalArgumentException("Polygon is not convex: Point " + points.get(pointIndex) + " Edge " + edge);
+ }
+ }
+ }
+ edgePoints = new GeoPoint[]{points.get(0)};
+ }
+
+ protected int legalIndex(int index) {
+ while (index >= points.size())
+ index -= points.size();
+ return index;
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ for (final SidedPlane edge : edges) {
+ if (!edge.isWithin(point))
return false;
}
+ return true;
+ }
- /** 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)
- {
- bounds = super.getBounds(bounds);
-
- // Add all the points
- for (final GeoPoint point : points) {
- bounds.addPoint(point);
- }
-
- // Add planes with membership.
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final SidedPlane edge = edges[edgeIndex];
- // Construct boundaries
- final Membership[] membershipBounds = new Membership[edges.length-1];
- int count = 0;
- for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
- if (otherIndex != edgeIndex) {
- membershipBounds[count++] = edges[otherIndex];
- }
- }
- edge.recordBounds(bounds,membershipBounds);
- }
-
- if (fullDistance >= Math.PI) {
- // We can't reliably assume that bounds did its longitude calculation right, so we force it to be unbounded.
- bounds.noLongitudeBound();
- }
- return bounds;
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (final SidedPlane edge : edges) {
+ if (!edge.isWithin(x, y, z))
+ return false;
}
+ return true;
+ }
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoConvexPolygon))
- return false;
- GeoConvexPolygon other = (GeoConvexPolygon)o;
- if (other.points.size() != points.size())
- return false;
-
- for (int i = 0; i < points.size(); i++) {
- if (!other.points.get(i).equals(points.get(i)))
- return false;
- }
- return true;
- }
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ //System.err.println("Checking for polygon intersection with plane "+p+"...");
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
+ if (!internalEdges[edgeIndex]) {
+ //System.err.println(" non-internal edge "+edge);
+ // Edges flagged as 'internal only' are excluded from the matching
+ // Construct boundaries
+ final Membership[] membershipBounds = new Membership[edges.length - 1];
+ int count = 0;
+ for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
+ if (otherIndex != edgeIndex) {
+ membershipBounds[count++] = edges[otherIndex];
+ }
+ }
+ if (edge.intersects(p, notablePoints, points, bounds, membershipBounds)) {
+ //System.err.println(" intersects!");
+ return true;
+ }
+ }
+ }
+ //System.err.println(" no intersection");
+ 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) {
+ bounds = super.getBounds(bounds);
+
+ // Add all the points
+ for (final GeoPoint point : points) {
+ bounds.addPoint(point);
+ }
+
+ // Add planes with membership.
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ // Construct boundaries
+ final Membership[] membershipBounds = new Membership[edges.length - 1];
+ int count = 0;
+ for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
+ if (otherIndex != edgeIndex) {
+ membershipBounds[count++] = edges[otherIndex];
+ }
+ }
+ edge.recordBounds(bounds, membershipBounds);
+ }
+
+ if (fullDistance >= Math.PI) {
+ // We can't reliably assume that bounds did its longitude calculation right, so we force it to be unbounded.
+ bounds.noLongitudeBound();
+ }
+ return bounds;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoConvexPolygon))
+ return false;
+ GeoConvexPolygon other = (GeoConvexPolygon) o;
+ if (other.points.size() != points.size())
+ return false;
- @Override
- public int hashCode() {
- return points.hashCode();
+ for (int i = 0; i < points.size(); i++) {
+ if (!other.points.get(i).equals(points.get(i)))
+ return false;
}
+ return true;
+ }
- @Override
- public String toString() {
- StringBuilder edgeString = new StringBuilder("{");
- for (int i = 0; i < edges.length; i++) {
- edgeString.append(edges[i]).append(" internal? ").append(internalEdges[i]).append("; ");
- }
- edgeString.append("}");
- return "GeoConvexPolygon: {points=" + points + " edges="+edgeString+"}";
- }
+ @Override
+ public int hashCode() {
+ return points.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder edgeString = new StringBuilder("{");
+ for (int i = 0; i < edges.length; i++) {
+ edgeString.append(edges[i]).append(" internal? ").append(internalEdges[i]).append("; ");
+ }
+ edgeString.append("}");
+ return "GeoConvexPolygon: {points=" + points + " edges=" + edgeString + "}";
+ }
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java Mon May 4 13:19:02 2015
@@ -17,188 +17,185 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Degenerate bounding box limited on two sides (left lon, right lon).
-* The left-right maximum extent for this shape is PI; for anything larger, use
-* GeoWideDegenerateHorizontalLine.
-*/
-public class GeoDegenerateHorizontalLine 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 GeoPoint[] edgePoints;
-
- /** Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI} */
- public GeoDegenerateHorizontalLine(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 great");
-
- 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;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final 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.edgePoints = new GeoPoint[]{centerPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- double newTopLat = latitude + angle;
- 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)
- {
- 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()
- {
- double topAngle = centerPoint.arcDistance(RHC);
- 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)
- {
- return p.intersects(plane,notablePoints,planePoints,bounds,leftPlane,rightPlane);
- }
-
- /** 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,leftPlane,rightPlane))
- return OVERLAPS;
-
- if (path.isWithin(centerPoint))
- return CONTAINS;
-
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoDegenerateHorizontalLine))
- return false;
- GeoDegenerateHorizontalLine other = (GeoDegenerateHorizontalLine)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 "GeoDegenerateHorizontalLine: {latitude="+latitude+"("+latitude*180.0/Math.PI+"), leftlon="+leftLon+"("+leftLon*180.0/Math.PI+"), rightLon="+rightLon+"("+rightLon*180.0/Math.PI+")}";
- }
+/**
+ * Degenerate bounding box limited on two sides (left lon, right lon).
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * GeoWideDegenerateHorizontalLine.
+ */
+public class GeoDegenerateHorizontalLine 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 GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ */
+ public GeoDegenerateHorizontalLine(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 great");
+
+ 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;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final 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.edgePoints = new GeoPoint[]{centerPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ double newTopLat = latitude + angle;
+ 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) {
+ 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() {
+ double topAngle = centerPoint.arcDistance(RHC);
+ 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) {
+ return p.intersects(plane, notablePoints, planePoints, bounds, leftPlane, rightPlane);
+ }
+
+ /**
+ * 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, leftPlane, rightPlane))
+ return OVERLAPS;
+
+ if (path.isWithin(centerPoint))
+ return CONTAINS;
+
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateHorizontalLine))
+ return false;
+ GeoDegenerateHorizontalLine other = (GeoDegenerateHorizontalLine) 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 "GeoDegenerateHorizontalLine: {latitude=" + latitude + "(" + latitude * 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/GeoDegenerateLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java Mon May 4 13:19:02 2015
@@ -17,130 +17,125 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** This GeoBBox represents an area rectangle of one specific latitude with
-* no longitude bounds.
-*/
-public class GeoDegenerateLatitudeZone extends GeoBBoxBase
-{
- public final double latitude;
-
- public final double sinLatitude;
- public final Plane plane;
- public final GeoPoint interiorPoint;
- public final GeoPoint[] edgePoints;
- public final static GeoPoint[] planePoints = new GeoPoint[0];
-
- public GeoDegenerateLatitudeZone(final double latitude)
- {
- this.latitude = latitude;
-
- this.sinLatitude = Math.sin(latitude);
- double cosLatitude = Math.cos(latitude);
- this.plane = new Plane(sinLatitude);
- // Compute an interior point.
- interiorPoint = new GeoPoint(cosLatitude,0.0,sinLatitude);
- edgePoints = new GeoPoint[]{interiorPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- double newTopLat = latitude + angle;
- double newBottomLat = latitude - angle;
- return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
- }
-
- @Override
- public boolean isWithin(final Vector point)
- {
- return Math.abs(point.z - this.sinLatitude) < 1e-10;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return Math.abs(z - this.sinLatitude) < 1e-10;
- }
-
- @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 interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints()
- {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds)
- {
- return p.intersects(plane,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(latitude);
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- // 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.
- //System.out.println("Got here! latitude="+latitude+" path="+path);
-
- if (path.intersects(plane,planePoints)) {
- return OVERLAPS;
- }
-
- if (path.isWithin(interiorPoint)) {
- return CONTAINS;
- }
-
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoDegenerateLatitudeZone))
- return false;
- GeoDegenerateLatitudeZone other = (GeoDegenerateLatitudeZone)o;
- return other.latitude == latitude;
- }
+/**
+ * This GeoBBox represents an area rectangle of one specific latitude with
+ * no longitude bounds.
+ */
+public class GeoDegenerateLatitudeZone extends GeoBBoxBase {
+ public final double latitude;
- @Override
- public int hashCode() {
- long temp = Double.doubleToLongBits(latitude);
- int result = (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateLatitudeZone: {lat="+latitude+"("+latitude*180.0/Math.PI+")}";
- }
+ public final double sinLatitude;
+ public final Plane plane;
+ public final GeoPoint interiorPoint;
+ public final GeoPoint[] edgePoints;
+ public final static GeoPoint[] planePoints = new GeoPoint[0];
+
+ public GeoDegenerateLatitudeZone(final double latitude) {
+ this.latitude = latitude;
+
+ this.sinLatitude = Math.sin(latitude);
+ double cosLatitude = Math.cos(latitude);
+ this.plane = new Plane(sinLatitude);
+ // Compute an interior point.
+ interiorPoint = new GeoPoint(cosLatitude, 0.0, sinLatitude);
+ edgePoints = new GeoPoint[]{interiorPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ double newTopLat = latitude + angle;
+ double newBottomLat = latitude - angle;
+ return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return Math.abs(point.z - this.sinLatitude) < 1e-10;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return Math.abs(z - this.sinLatitude) < 1e-10;
+ }
+
+ @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 interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(plane, 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(latitude);
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ // 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.
+ //System.out.println("Got here! latitude="+latitude+" path="+path);
+
+ if (path.intersects(plane, planePoints)) {
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(interiorPoint)) {
+ return CONTAINS;
+ }
+
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateLatitudeZone))
+ return false;
+ GeoDegenerateLatitudeZone other = (GeoDegenerateLatitudeZone) o;
+ return other.latitude == latitude;
+ }
+
+ @Override
+ public int hashCode() {
+ long temp = Double.doubleToLongBits(latitude);
+ int result = (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateLatitudeZone: {lat=" + latitude + "(" + latitude * 180.0 / Math.PI + ")}";
+ }
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java Mon May 4 13:19:02 2015
@@ -17,144 +17,141 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Degenerate longitude slice.
-*/
-public class GeoDegenerateLongitudeSlice extends GeoBBoxBase
-{
- public final double longitude;
-
- public final double sinLongitude;
- public final double cosLongitude;
- public final SidedPlane boundingPlane;
- public final Plane plane;
- public final GeoPoint interiorPoint;
- public final GeoPoint[] edgePoints;
-
- public final static GeoPoint[] planePoints = new GeoPoint[]{NORTH_POLE,SOUTH_POLE};
-
- /** Accepts only values in the following ranges: lon: {@code -PI -> PI} */
- public GeoDegenerateLongitudeSlice(final double longitude)
- {
- // Argument checking
- if (longitude < -Math.PI || longitude > Math.PI)
- throw new IllegalArgumentException("Longitude out of range");
- this.longitude = longitude;
-
- this.sinLongitude = Math.sin(longitude);
- this.cosLongitude = Math.cos(longitude);
-
- this.plane = new Plane(cosLongitude, sinLongitude);
- // We need a bounding plane too, which is perpendicular to the longitude plane and sided so that the point (0.0, longitude) is inside.
- this.interiorPoint = new GeoPoint(cosLongitude, sinLongitude, 0.0);
- this.boundingPlane = new SidedPlane(interiorPoint, -sinLongitude, cosLongitude);
- this.edgePoints = new GeoPoint[]{interiorPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- // Figuring out when we escalate to a special case requires some prefiguring
- double newLeftLon = longitude - angle;
- double newRightLon = longitude + angle;
- double currentLonSpan = 2.0 * 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 plane.evaluateIsZero(point) &&
- boundingPlane.isWithin(point);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return plane.evaluateIsZero(x,y,z) &&
- boundingPlane.isWithin(x,y,z);
- }
-
- @Override
- public double getRadius()
- {
- return Math.PI * 0.5;
- }
-
- /** 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(plane,notablePoints,planePoints,bounds,boundingPlane);
- }
-
- /** 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(longitude,longitude);
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- // Look for intersections.
- if (path.intersects(plane,planePoints,boundingPlane))
- return OVERLAPS;
-
- if (path.isWithin(interiorPoint))
- return CONTAINS;
-
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoDegenerateLongitudeSlice))
- return false;
- GeoDegenerateLongitudeSlice other = (GeoDegenerateLongitudeSlice)o;
- return other.longitude == longitude;
- }
+/**
+ * Degenerate longitude slice.
+ */
+public class GeoDegenerateLongitudeSlice extends GeoBBoxBase {
+ public final double longitude;
- @Override
- public int hashCode() {
- int result;
- long temp;
- temp = Double.doubleToLongBits(longitude);
- result = (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateLongitudeSlice: {longitude="+longitude+"("+longitude*180.0/Math.PI+")}";
- }
+ public final double sinLongitude;
+ public final double cosLongitude;
+ public final SidedPlane boundingPlane;
+ public final Plane plane;
+ public final GeoPoint interiorPoint;
+ public final GeoPoint[] edgePoints;
+
+ public final static GeoPoint[] planePoints = new GeoPoint[]{NORTH_POLE, SOUTH_POLE};
+
+ /**
+ * Accepts only values in the following ranges: lon: {@code -PI -> PI}
+ */
+ public GeoDegenerateLongitudeSlice(final double longitude) {
+ // Argument checking
+ if (longitude < -Math.PI || longitude > Math.PI)
+ throw new IllegalArgumentException("Longitude out of range");
+ this.longitude = longitude;
+
+ this.sinLongitude = Math.sin(longitude);
+ this.cosLongitude = Math.cos(longitude);
+
+ this.plane = new Plane(cosLongitude, sinLongitude);
+ // We need a bounding plane too, which is perpendicular to the longitude plane and sided so that the point (0.0, longitude) is inside.
+ this.interiorPoint = new GeoPoint(cosLongitude, sinLongitude, 0.0);
+ this.boundingPlane = new SidedPlane(interiorPoint, -sinLongitude, cosLongitude);
+ this.edgePoints = new GeoPoint[]{interiorPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double newLeftLon = longitude - angle;
+ double newRightLon = longitude + angle;
+ double currentLonSpan = 2.0 * 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 plane.evaluateIsZero(point) &&
+ boundingPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(x, y, z) &&
+ boundingPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ return Math.PI * 0.5;
+ }
+
+ /**
+ * 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(plane, notablePoints, planePoints, bounds, boundingPlane);
+ }
+
+ /**
+ * 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(longitude, longitude);
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ // Look for intersections.
+ if (path.intersects(plane, planePoints, boundingPlane))
+ return OVERLAPS;
+
+ if (path.isWithin(interiorPoint))
+ return CONTAINS;
+
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateLongitudeSlice))
+ return false;
+ GeoDegenerateLongitudeSlice other = (GeoDegenerateLongitudeSlice) o;
+ return other.longitude == longitude;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(longitude);
+ result = (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateLongitudeSlice: {longitude=" + longitude + "(" + longitude * 180.0 / Math.PI + ")}";
+ }
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java Mon May 4 13:19:02 2015
@@ -17,156 +17,175 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** This class represents a degenerate point bounding box.
-* It is not a simple GeoPoint because we must have the latitude and longitude.
-*/
-public class GeoDegeneratePoint extends GeoPoint implements GeoBBox
-{
- public final double latitude;
- public final double longitude;
- public final GeoPoint[] edgePoints;
-
- public GeoDegeneratePoint(final double lat, final double lon)
- {
- super(lat,lon);
- this.latitude = lat;
- this.longitude = lon;
- this.edgePoints = new GeoPoint[]{this};
- }
-
- /** Expand box by specified angle.
- *@param angle is the angle amount to expand the GeoBBox by.
- *@return a new GeoBBox.
- */
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = latitude + angle;
- final double newBottomLat = latitude - angle;
- final double newLeftLon = longitude - angle;
- final double newRightLon = longitude + angle;
- return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- /** Return a sample point that is on the edge of the shape.
- *@return an interior point.
- */
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- /** Assess whether a plane, within the provided bounds, intersects
- * with the shape.
- *@param plane is the plane to assess for intersection with the shape's edges or
- * bounding curves.
- *@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.
- */
- @Override
- public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
- if (plane.evaluate(this) == 0.0)
- return false;
-
- for (Membership m : bounds) {
- if (!m.isWithin(this))
- return false;
- }
- return true;
- }
-
- /** 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.addPoint(latitude,longitude);
- return bounds;
- }
-
- /** Equals */
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoDegeneratePoint))
- return false;
- GeoDegeneratePoint other = (GeoDegeneratePoint)o;
- return other.latitude == latitude && other.longitude == longitude;
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- temp = Double.doubleToLongBits(latitude);
- result = (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(longitude);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegeneratePoint: {lat="+latitude+"("+latitude*180.0/Math.PI+"), lon="+longitude+"("+longitude*180.0/Math.PI+")}";
- }
-
- /** Check if a point is within this shape.
- *@param point is the point to check.
- *@return true if the point is within this shape
- */
- @Override
- public boolean isWithin(final Vector point) {
- return isWithin(point.x,point.y,point.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
- */
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return x == this.x && y == this.y && z == this.z;
- }
-
- /** Returns the radius of a circle into which the GeoSizeable area can
- * be inscribed.
- *@return the radius.
- */
- @Override
- public double getRadius() {
- return 0.0;
- }
-
- /** Returns the center of a circle into which the area will be inscribed.
- *@return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return this;
- }
-
- /** Find the spatial relationship between a shape and the current geo area.
- * Note: return value is how the GeoShape relates to the GeoArea, not the
- * other way around. For example, if this GeoArea is entirely within the
- * shape, then CONTAINS should be returned. If the shape is entirely enclosed
- * by this GeoArea, then WITHIN should be returned.
- *@param shape is the shape to consider.
- *@return the relationship, from the perspective of the shape.
- */
- @Override
- public int getRelationship(final GeoShape shape) {
- if (shape.isWithin(this))
- return CONTAINS;
+/**
+ * This class represents a degenerate point bounding box.
+ * It is not a simple GeoPoint because we must have the latitude and longitude.
+ */
+public class GeoDegeneratePoint extends GeoPoint implements GeoBBox {
+ public final double latitude;
+ public final double longitude;
+ public final GeoPoint[] edgePoints;
+
+ public GeoDegeneratePoint(final double lat, final double lon) {
+ super(lat, lon);
+ this.latitude = lat;
+ this.longitude = lon;
+ this.edgePoints = new GeoPoint[]{this};
+ }
+
+ /**
+ * Expand box by specified angle.
+ *
+ * @param angle is the angle amount to expand the GeoBBox by.
+ * @return a new GeoBBox.
+ */
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = latitude + angle;
+ final double newBottomLat = latitude - angle;
+ final double newLeftLon = longitude - angle;
+ final double newRightLon = longitude + angle;
+ return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ /**
+ * Return a sample point that is on the edge of the shape.
+ *
+ * @return an interior point.
+ */
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ /**
+ * Assess whether a plane, within the provided bounds, intersects
+ * with the shape.
+ *
+ * @param plane is the plane to assess for intersection with the shape's edges or
+ * bounding curves.
+ * @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.
+ */
+ @Override
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
+ if (plane.evaluate(this) == 0.0)
+ return false;
+
+ for (Membership m : bounds) {
+ if (!m.isWithin(this))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 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.addPoint(latitude, longitude);
+ return bounds;
+ }
+
+ /**
+ * Equals
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegeneratePoint))
+ return false;
+ GeoDegeneratePoint other = (GeoDegeneratePoint) o;
+ return other.latitude == latitude && other.longitude == longitude;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(latitude);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(longitude);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegeneratePoint: {lat=" + latitude + "(" + latitude * 180.0 / Math.PI + "), lon=" + longitude + "(" + longitude * 180.0 / Math.PI + ")}";
+ }
+
+ /**
+ * Check if a point is within this shape.
+ *
+ * @param point is the point to check.
+ * @return true if the point is within this shape
+ */
+ @Override
+ public boolean isWithin(final Vector point) {
+ return isWithin(point.x, point.y, point.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
+ */
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return x == this.x && y == this.y && z == this.z;
+ }
+
+ /**
+ * Returns the radius of a circle into which the GeoSizeable area can
+ * be inscribed.
+ *
+ * @return the radius.
+ */
+ @Override
+ public double getRadius() {
+ return 0.0;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return this;
+ }
+
+ /**
+ * Find the spatial relationship between a shape and the current geo area.
+ * Note: return value is how the GeoShape relates to the GeoArea, not the
+ * other way around. For example, if this GeoArea is entirely within the
+ * shape, then CONTAINS should be returned. If the shape is entirely enclosed
+ * by this GeoArea, then WITHIN should be returned.
+ *
+ * @param shape is the shape to consider.
+ * @return the relationship, from the perspective of the shape.
+ */
+ @Override
+ public int getRelationship(final GeoShape shape) {
+ if (shape.isWithin(this))
+ return CONTAINS;
- return DISJOINT;
- }
+ return DISJOINT;
+ }
}
Modified: lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java?rev=1677595&r1=1677594&r2=1677595&view=diff
==============================================================================
--- lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java (original)
+++ lucene/dev/branches/lucene6196/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java Mon May 4 13:19:02 2015
@@ -17,191 +17,188 @@ package org.apache.lucene.spatial.spatia
* limitations under the License.
*/
-/** Degenerate bounding box limited on two sides (top lat, bottom lat).
-*/
-public class GeoDegenerateVerticalLine extends GeoBBoxBase
-{
- public final double topLat;
- public final double bottomLat;
- public final double longitude;
-
- public final GeoPoint UHC;
- public final GeoPoint LHC;
-
- public final SidedPlane topPlane;
- public final SidedPlane bottomPlane;
- public final SidedPlane boundingPlane;
- public final Plane plane;
-
- public final GeoPoint[] planePoints;
-
- public final GeoPoint centerPoint;
- public final GeoPoint[] edgePoints;
-
- /** Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, longitude: {@code -PI -> PI} */
- public GeoDegenerateVerticalLine(final double topLat, final double bottomLat, final double longitude)
- {
- // 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 (longitude < -Math.PI || longitude > Math.PI)
- throw new IllegalArgumentException("Longitude out of range");
-
- this.topLat = topLat;
- this.bottomLat = bottomLat;
- this.longitude = longitude;
-
- 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 sinLongitude = Math.sin(longitude);
- final double cosLongitude = Math.cos(longitude);
-
- // Now build the two points
- this.UHC = new GeoPoint(sinTopLat,sinLongitude,cosTopLat,cosLongitude);
- this.LHC = new GeoPoint(sinBottomLat,sinLongitude,cosBottomLat,cosLongitude);
-
- this.plane = new Plane(cosLongitude,sinLongitude);
-
- final double middleLat = (topLat + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- final double cosMiddleLat = Math.cos(middleLat);
-
- this.centerPoint = new GeoPoint(sinMiddleLat,sinLongitude,cosMiddleLat,cosLongitude);
-
- this.topPlane = new SidedPlane(centerPoint,sinTopLat);
- this.bottomPlane = new SidedPlane(centerPoint,sinBottomLat);
-
- this.boundingPlane = new SidedPlane(centerPoint,-sinLongitude,cosLongitude);
-
- this.planePoints = new GeoPoint[]{UHC,LHC};
-
- this.edgePoints = new GeoPoint[]{centerPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle)
- {
- final double newTopLat = topLat + angle;
- final double newBottomLat = bottomLat - angle;
- double newLeftLon = longitude - angle;
- double newRightLon = longitude + angle;
- double currentLonSpan = 2.0 * 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 plane.evaluateIsZero(point) &&
- boundingPlane.isWithin(point) &&
- topPlane.isWithin(point) &&
- bottomPlane.isWithin(point);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z)
- {
- return plane.evaluateIsZero(x,y,z) &&
- boundingPlane.isWithin(x,y,z) &&
- topPlane.isWithin(x,y,z) &&
- bottomPlane.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(UHC);
- 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)
- {
- return p.intersects(plane,notablePoints,planePoints,bounds,boundingPlane,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(longitude,longitude);
- return bounds;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" relationship to "+path);
- if (path.intersects(plane,planePoints,boundingPlane,topPlane,bottomPlane)) {
- //System.err.println(" overlaps");
- return OVERLAPS;
- }
-
- if (path.isWithin(centerPoint)) {
- //System.err.println(" contains");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (!(o instanceof GeoDegenerateVerticalLine))
- return false;
- GeoDegenerateVerticalLine other = (GeoDegenerateVerticalLine)o;
- return other.UHC.equals(UHC) && other.LHC.equals(LHC);
- }
-
- @Override
- public int hashCode() {
- int result = UHC.hashCode();
- result = 31 * result + LHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateVerticalLine: {longitude="+longitude+"("+longitude*180.0/Math.PI+"), toplat="+topLat+"("+topLat*180.0/Math.PI+"), bottomlat="+bottomLat+"("+bottomLat*180.0/Math.PI+")}";
- }
+/**
+ * Degenerate bounding box limited on two sides (top lat, bottom lat).
+ */
+public class GeoDegenerateVerticalLine extends GeoBBoxBase {
+ public final double topLat;
+ public final double bottomLat;
+ public final double longitude;
+
+ public final GeoPoint UHC;
+ public final GeoPoint LHC;
+
+ public final SidedPlane topPlane;
+ public final SidedPlane bottomPlane;
+ public final SidedPlane boundingPlane;
+ public final Plane plane;
+
+ public final GeoPoint[] planePoints;
+
+ public final GeoPoint centerPoint;
+ public final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, longitude: {@code -PI -> PI}
+ */
+ public GeoDegenerateVerticalLine(final double topLat, final double bottomLat, final double longitude) {
+ // 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 (longitude < -Math.PI || longitude > Math.PI)
+ throw new IllegalArgumentException("Longitude out of range");
+
+ this.topLat = topLat;
+ this.bottomLat = bottomLat;
+ this.longitude = longitude;
+
+ 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 sinLongitude = Math.sin(longitude);
+ final double cosLongitude = Math.cos(longitude);
+
+ // Now build the two points
+ this.UHC = new GeoPoint(sinTopLat, sinLongitude, cosTopLat, cosLongitude);
+ this.LHC = new GeoPoint(sinBottomLat, sinLongitude, cosBottomLat, cosLongitude);
+
+ this.plane = new Plane(cosLongitude, sinLongitude);
+
+ final double middleLat = (topLat + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ final double cosMiddleLat = Math.cos(middleLat);
+
+ this.centerPoint = new GeoPoint(sinMiddleLat, sinLongitude, cosMiddleLat, cosLongitude);
+
+ this.topPlane = new SidedPlane(centerPoint, sinTopLat);
+ this.bottomPlane = new SidedPlane(centerPoint, sinBottomLat);
+
+ this.boundingPlane = new SidedPlane(centerPoint, -sinLongitude, cosLongitude);
+
+ this.planePoints = new GeoPoint[]{UHC, LHC};
+
+ this.edgePoints = new GeoPoint[]{centerPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = bottomLat - angle;
+ double newLeftLon = longitude - angle;
+ double newRightLon = longitude + angle;
+ double currentLonSpan = 2.0 * 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 plane.evaluateIsZero(point) &&
+ boundingPlane.isWithin(point) &&
+ topPlane.isWithin(point) &&
+ bottomPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(x, y, z) &&
+ boundingPlane.isWithin(x, y, z) &&
+ topPlane.isWithin(x, y, z) &&
+ bottomPlane.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(UHC);
+ 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) {
+ return p.intersects(plane, notablePoints, planePoints, bounds, boundingPlane, 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(longitude, longitude);
+ return bounds;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" relationship to "+path);
+ if (path.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane)) {
+ //System.err.println(" overlaps");
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(centerPoint)) {
+ //System.err.println(" contains");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateVerticalLine))
+ return false;
+ GeoDegenerateVerticalLine other = (GeoDegenerateVerticalLine) o;
+ return other.UHC.equals(UHC) && other.LHC.equals(LHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = UHC.hashCode();
+ result = 31 * result + LHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateVerticalLine: {longitude=" + longitude + "(" + longitude * 180.0 / Math.PI + "), toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
+ }
}