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/07/01 04:03:44 UTC

svn commit: r1688545 [1/2] - in /lucene/dev/trunk/lucene: ./ spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/ spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/

Author: dsmiley
Date: Wed Jul  1 02:03:43 2015
New Revision: 1688545

URL: http://svn.apache.org/r1688545
Log:
LUCENE-6578: Geo3D: compute the distance from a point to a shape.

Added:
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/ArcDistance.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/BasePlanetObject.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/DistanceStyle.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseDistanceShape.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseMembershipShape.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoOutsideDistance.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearDistance.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearSquaredDistance.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalDistance.java   (with props)
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalSquaredDistance.java   (with props)
Removed:
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseExtendedShape.java
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseBBox.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseShape.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDistance.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoMembershipShape.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircleTest.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygonTest.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPathTest.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed Jul  1 02:03:43 2015
@@ -109,6 +109,10 @@ New Features
   near-real-time or non-NRT reader.  (Boaz Leskes, Robert Muir, Mike
   McCandless)
 
+* LUCENE-6578: Geo3D can now compute the distance from a point to a shape, both
+  inner distance and to an outside edge. Multiple distance algorithms are
+  available.  (Karl Wright, David Smiley)
+
 API Changes
 
 * LUCENE-6508: Simplify Lock api, there is now just 

Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/ArcDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/ArcDistance.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/ArcDistance.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/ArcDistance.java Wed Jul  1 02:03:43 2015
@@ -0,0 +1,51 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Arc distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class ArcDistance implements DistanceStyle {
+  
+  public final static ArcDistance INSTANCE = new ArcDistance();
+  
+  @Override
+  public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+    return point1.arcDistance(point2);
+  }
+  
+  @Override
+  public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+    return point1.arcDistance(x2,y2,z2);
+  }
+
+  @Override
+  public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+    return plane.arcDistance(planetModel, point, bounds);
+  }
+  
+  @Override
+  public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+    return plane.arcDistance(planetModel, x,y,z, bounds);
+  }
+
+}
+
+

Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/BasePlanetObject.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/BasePlanetObject.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/BasePlanetObject.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/BasePlanetObject.java Wed Jul  1 02:03:43 2015
@@ -0,0 +1,48 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * All Geo3D shapes can derive from this base class, which furnishes
+ * some common code
+ *
+ * @lucene.internal
+ */
+public abstract class BasePlanetObject {
+
+  protected final PlanetModel planetModel;
+  
+  public BasePlanetObject(final PlanetModel planetModel) {
+    this.planetModel = planetModel;
+  }
+  
+  @Override
+  public int hashCode() {
+    return planetModel.hashCode();
+  }
+  
+  @Override
+  public boolean equals(final Object o) {
+    if (!(o instanceof BasePlanetObject))
+      return false;
+    return planetModel.equals(((BasePlanetObject)o).planetModel);
+  }
+}
+
+
+

Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/DistanceStyle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/DistanceStyle.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/DistanceStyle.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/DistanceStyle.java Wed Jul  1 02:03:43 2015
@@ -0,0 +1,79 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Distance computation styles, supporting various ways of computing
+ * distance to shapes.
+ *
+ * @lucene.experimental
+ */
+public interface DistanceStyle {
+
+  // convenient access to built-in styles:
+
+  public static final ArcDistance ARC = ArcDistance.INSTANCE;
+  public static final LinearDistance LINEAR = LinearDistance.INSTANCE;
+  public static final LinearSquaredDistance LINEAR_SQUARED = LinearSquaredDistance.INSTANCE;
+  public static final NormalDistance NORMAL = NormalDistance.INSTANCE;
+  public static final NormalSquaredDistance NORMAL_SQUARED = NormalSquaredDistance.INSTANCE;
+
+  /** Compute the distance from a point to another point.
+   * @param point1 Starting point
+   * @param point2 Final point
+   * @return the distance
+   */
+  public default double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+    return computeDistance(point1, point2.x, point2.y, point2.z);
+  }
+  
+  /** Compute the distance from a point to another point.
+   * @param point1 Starting point
+   * @param x2 Final point x
+   * @param y2 Final point y
+   * @param z2 Final point z
+   * @return the distance
+   */
+  public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2);
+
+  /** Compute the distance from a plane to a point.
+   * @param planetModel The planet model
+   * @param plane The plane
+   * @param point The point
+   * @param bounds are the plane bounds
+   * @return the distance
+   */
+  public default double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point,
+                                        final Membership... bounds) {
+    return computeDistance(planetModel, plane, point.x, point.y, point.z, bounds);
+  }
+  
+  /** Compute the distance from a plane to a point.
+   * @param planetModel The planet model
+   * @param plane The plane
+   * @param x The point x
+   * @param y The point y
+   * @param z The point z
+   * @param bounds are the plane bounds
+   * @return the distance
+   */
+  public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds);
+
+}
+
+

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseBBox.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseBBox.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseBBox.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseBBox.java Wed Jul  1 02:03:43 2015
@@ -23,14 +23,11 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public abstract class GeoBaseBBox extends GeoBaseShape implements GeoBBox {
+public abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
 
   public GeoBaseBBox(final PlanetModel planetModel) {
     super(planetModel);
   }
-  
-  @Override
-  public abstract boolean isWithin(final Vector point);
 
   protected final static int ALL_INSIDE = 0;
   protected final static int SOME_INSIDE = 1;
@@ -58,15 +55,6 @@ public abstract class GeoBaseBBox extend
       return NONE_INSIDE;
     return SOME_INSIDE;
   }
-  
-  @Override
-  public int hashCode() {
-    return super.hashCode();
-  }
-  
-  @Override
-  public boolean equals(final Object o) {
-    return super.equals(o);
-  }
+
 }
 

Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseDistanceShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseDistanceShape.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseDistanceShape.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseDistanceShape.java Wed Jul  1 02:03:43 2015
@@ -0,0 +1,54 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Distance shapes have capabilities of both geohashing and distance
+ * computation (which also includes point membership determination).
+ *
+ * @lucene.experimental
+ */
+public abstract class GeoBaseDistanceShape extends GeoBaseMembershipShape implements GeoDistanceShape {
+
+  public GeoBaseDistanceShape(final PlanetModel planetModel) {
+    super(planetModel);
+  }
+
+  @Override
+  public boolean isWithin(Vector point) {
+    return isWithin(point.x, point.y, point.z);
+  }
+
+  @Override
+  public double computeDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+    return computeDistance(distanceStyle, point.x, point.y, point.z);
+  }
+
+  @Override
+  public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    if (!isWithin(x,y,z)) {
+      return Double.MAX_VALUE;
+    }
+    return distance(distanceStyle, x, y, z);
+  }
+
+  /** Called by a {@code computeDistance} method if X/Y/Z is not within this shape. */
+  protected abstract double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
+

Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseMembershipShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseMembershipShape.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseMembershipShape.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseMembershipShape.java Wed Jul  1 02:03:43 2015
@@ -0,0 +1,54 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Membership shapes have capabilities of both geohashing and membership
+ * determination.  This is a useful baseclass for them.
+ *
+ * @lucene.experimental
+ */
+public abstract class GeoBaseMembershipShape extends GeoBaseShape implements GeoMembershipShape {
+
+  public GeoBaseMembershipShape(final PlanetModel planetModel) {
+    super(planetModel);
+  }
+
+  @Override
+  public boolean isWithin(Vector point) {
+    return isWithin(point.x, point.y, point.z);
+  }
+
+  @Override
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+    return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
+  }
+
+  @Override
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    if (isWithin(x,y,z)) {
+      return 0.0;
+    }
+    return outsideDistance(distanceStyle, x,y,z);
+  }
+
+  /** Called by a {@code computeOutsideDistance} method if X/Y/Z is not within this shape. */
+  protected abstract double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
+

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseShape.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseShape.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoBaseShape.java Wed Jul  1 02:03:43 2015
@@ -18,30 +18,29 @@ package org.apache.lucene.spatial.spatia
  */
 
 /**
- * All bounding box shapes can derive from this base class, which furnishes
- * some common code
+ * Base extended shape object.
  *
  * @lucene.internal
  */
-public abstract class GeoBaseShape {
+public abstract class GeoBaseShape extends BasePlanetObject implements GeoShape {
 
-  protected final PlanetModel planetModel;
-  
   public GeoBaseShape(final PlanetModel planetModel) {
-    this.planetModel = planetModel;
+    super(planetModel);
   }
-  
-  @Override
-  public int hashCode() {
-    return planetModel.hashCode();
-  }
-  
+
   @Override
-  public boolean equals(final Object o) {
-    if (!(o instanceof GeoBaseShape))
-      return false;
-    return planetModel.equals(((GeoBaseShape)o).planetModel);
+  public Bounds getBounds(Bounds bounds) {
+    if (bounds == null)
+      bounds = new Bounds();
+    if (isWithin(planetModel.NORTH_POLE)) {
+      bounds.noTopLatitudeBound().noLongitudeBound();
+    }
+    if (isWithin(planetModel.SOUTH_POLE)) {
+      bounds.noBottomLatitudeBound().noLongitudeBound();
+    }
+    return bounds;
   }
+
 }
 
 

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircle.java Wed Jul  1 02:03:43 2015
@@ -22,7 +22,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.experimental
  */
-public class GeoCircle extends GeoBaseExtendedShape implements GeoDistanceShape, GeoSizeable {
+public class GeoCircle extends GeoBaseDistanceShape implements GeoSizeable {
   public final GeoPoint center;
   public final double cutoffAngle;
   public final SidedPlane circlePlane;
@@ -81,124 +81,19 @@ public class GeoCircle extends GeoBaseEx
     return cutoffAngle;
   }
 
-  /**
-   * Returns the center of a circle into which the area will be inscribed.
-   *
-   * @return the center.
-   */
   @Override
   public GeoPoint getCenter() {
     return center;
   }
 
-  /**
-   * Compute an estimate of "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   */
   @Override
-  public double computeNormalDistance(final GeoPoint point) {
-    if (!isWithin(point))
-      return Double.MAX_VALUE;
-    return this.center.normalDistance(point);
+  protected double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    return distanceStyle.computeDistance(this.center, x, y, z);
   }
 
-  /**
-   * Compute an estimate of "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   */
   @Override
-  public double computeNormalDistance(final double x, final double y, final double z) {
-    if (!isWithin(x,y,z))
-      return Double.MAX_VALUE;
-    return this.center.normalDistance(x, y, z);
-  }
-
-  /**
-   * Compute a squared estimate of the "distance" to the
-   * GeoPoint.  Double.MAX_VALUE indicates a point outside of the
-   * shape.
-   */
-  @Override
-  public double computeSquaredNormalDistance(final GeoPoint point) {
-    if (!isWithin(point))
-      return Double.MAX_VALUE;
-    return this.center.normalDistanceSquared(point);
-  }
-
-  /**
-   * Compute a squared estimate of the "distance" to the
-   * GeoPoint.  Double.MAX_VALUE indicates a point outside of the
-   * shape.
-   */
-  @Override
-  public double computeSquaredNormalDistance(final double x, final double y, final double z) {
-    if (!isWithin(x,y,z))
-      return Double.MAX_VALUE;
-    return this.center.normalDistanceSquared(x, y, z);
-  }
-
-  /**
-   * Compute a linear distance to the vector.
-   * return Double.MAX_VALUE for points outside the shape.
-   */
-  @Override
-  public double computeLinearDistance(final GeoPoint point) {
-    if (!isWithin(point))
-      return Double.MAX_VALUE;
-    return this.center.linearDistance(point);
-  }
-
-  /**
-   * Compute a linear distance to the vector.
-   * return Double.MAX_VALUE for points outside the shape.
-   */
-  @Override
-  public double computeLinearDistance(final double x, final double y, final double z) {
-    if (!isWithin(x,y,z))
-      return Double.MAX_VALUE;
-    return this.center.linearDistance(x, y, z);
-  }
-
-  /**
-   * Compute a squared linear distance to the vector.
-   */
-  @Override
-  public double computeSquaredLinearDistance(final GeoPoint point) {
-    if (!isWithin(point))
-      return Double.MAX_VALUE;
-    return this.center.linearDistanceSquared(point);
-  }
-
-  /**
-   * Compute a squared linear distance to the vector.
-   */
-  @Override
-  public double computeSquaredLinearDistance(final double x, final double y, final double z) {
-    if (!isWithin(x,y,z))
-      return Double.MAX_VALUE;
-    return this.center.linearDistanceSquared(x, y, z);
-  }
-
-  /**
-   * Compute a true, accurate, great-circle distance.
-   * Double.MAX_VALUE indicates a point is outside of the shape.
-   */
-  @Override
-  public double computeArcDistance(final GeoPoint point) {
-    if (!isWithin(point))
-      return Double.MAX_VALUE;
-    return this.center.arcDistance(point);
-  }
-
-  @Override
-  public boolean isWithin(final Vector point) {
-    if (circlePlane == null) {
-      return true;
-    }
-    // Fastest way of determining membership
-    return circlePlane.isWithin(point);
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    return distanceStyle.computeDistance(planetModel, circlePlane, x, y, z);
   }
 
   @Override
@@ -223,15 +118,6 @@ public class GeoCircle extends GeoBaseEx
     return circlePlane.intersects(planetModel, p, notablePoints, circlePoints, 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) {
     bounds = super.getBounds(bounds);

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoCompositeMembershipShape.java Wed Jul  1 02:03:43 2015
@@ -40,14 +40,7 @@ public class GeoCompositeMembershipShape
 
   @Override
   public boolean isWithin(final Vector point) {
-    //System.err.println("Checking whether point "+point+" is within Composite");
-    for (GeoMembershipShape shape : shapes) {
-      if (shape.isWithin(point)) {
-        //System.err.println(" Point is within "+shape);
-        return true;
-      }
-    }
-    return false;
+    return isWithin(point.x, point.y, point.z);
   }
 
   @Override
@@ -73,15 +66,6 @@ public class GeoCompositeMembershipShape
     return false;
   }
 
-  /**
-   * Compute longitude/latitude bounds for the shape.
-   *
-   * @param bounds is the optional input bounds object.  If this is null,
-   *               a bounds object will be created.  Otherwise, the input object will be modified.
-   * @return a Bounds object describing the shape's bounds.  If the bounds cannot
-   * be computed, then return a Bounds object with noLongitudeBound,
-   * noTopLatitudeBound, and noBottomLatitudeBound.
-   */
   @Override
   public Bounds getBounds(Bounds bounds) {
     if (bounds == null)
@@ -93,23 +77,36 @@ public class GeoCompositeMembershipShape
   }
 
   @Override
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+    return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
+  }
+
+  @Override
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    if (isWithin(x,y,z))
+      return 0.0;
+    double distance = Double.MAX_VALUE;
+    for (GeoMembershipShape shape : shapes) {
+      final double normalDistance = shape.computeOutsideDistance(distanceStyle, x, y, z);
+      if (normalDistance < distance) {
+        distance = normalDistance;
+      }
+    }
+    return distance;
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoCompositeMembershipShape))
       return false;
     GeoCompositeMembershipShape other = (GeoCompositeMembershipShape) o;
-    if (other.shapes.size() != shapes.size())
-      return false;
 
-    for (int i = 0; i < shapes.size(); i++) {
-      if (!other.shapes.get(i).equals(shapes.get(i)))
-        return false;
-    }
-    return true;
+    return super.equals(o) && shapes.equals(other.shapes);
   }
 
   @Override
   public int hashCode() {
-    return shapes.hashCode();//TODO cache
+    return super.hashCode() * 31 + shapes.hashCode();//TODO cache
   }
 
   @Override

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygon.java Wed Jul  1 02:03:43 2015
@@ -29,7 +29,7 @@ import java.util.List;
  *
  * @lucene.experimental
  */
-public class GeoConvexPolygon extends GeoBaseExtendedShape implements GeoMembershipShape {
+public class GeoConvexPolygon extends GeoBaseMembershipShape {
   protected final List<GeoPoint> points;
   protected final BitSet isInternalEdges;
 
@@ -152,15 +152,6 @@ public class GeoConvexPolygon extends Ge
   }
 
   @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))
@@ -201,15 +192,6 @@ public class GeoConvexPolygon extends Ge
     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);
@@ -241,6 +223,32 @@ public class GeoConvexPolygon extends Ge
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    double minimumDistance = Double.MAX_VALUE;
+    for (final GeoPoint edgePoint : points) {
+      final double newDist = distanceStyle.computeDistance(edgePoint, x,y,z);
+      if (newDist < minimumDistance) {
+        minimumDistance = newDist;
+      }
+    }
+    for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+      final Plane edgePlane = edges[edgeIndex];
+      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];
+        }
+      }
+      final double newDist = distanceStyle.computeDistance(planetModel, edgePlane, x, y, z, membershipBounds);
+      if (newDist < minimumDistance) {
+        minimumDistance = newDist;
+      }
+    }
+    return minimumDistance;
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoConvexPolygon))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateHorizontalLine.java Wed Jul  1 02:03:43 2015
@@ -112,13 +112,6 @@ public class GeoDegenerateHorizontalLine
   }
 
   @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) &&
@@ -132,11 +125,6 @@ public class GeoDegenerateHorizontalLine
     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;
@@ -152,15 +140,6 @@ public class GeoDegenerateHorizontalLine
     return p.intersects(planetModel, 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)
@@ -187,6 +166,18 @@ public class GeoDegenerateHorizontalLine
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, leftPlane, rightPlane);
+    
+    final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
+    final double RHCDistance = distanceStyle.computeDistance(RHC, x,y,z);
+    
+    return Math.min(
+      distance,
+      Math.min(LHCDistance, RHCDistance));
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoDegenerateHorizontalLine))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLatitudeZone.java Wed Jul  1 02:03:43 2015
@@ -52,11 +52,6 @@ public class GeoDegenerateLatitudeZone e
   }
 
   @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;
   }
@@ -66,11 +61,6 @@ public class GeoDegenerateLatitudeZone e
     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
@@ -122,6 +112,11 @@ public class GeoDegenerateLatitudeZone e
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    return distanceStyle.computeDistance(planetModel, plane, x,y,z);
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoDegenerateLatitudeZone))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateLongitudeSlice.java Wed Jul  1 02:03:43 2015
@@ -69,12 +69,6 @@ public class GeoDegenerateLongitudeSlice
   }
 
   @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);
@@ -85,11 +79,6 @@ public class GeoDegenerateLongitudeSlice
     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;
@@ -105,15 +94,6 @@ public class GeoDegenerateLongitudeSlice
     return p.intersects(planetModel, 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)
@@ -136,6 +116,18 @@ public class GeoDegenerateLongitudeSlice
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, boundingPlane);
+    
+    final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
+    final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
+    
+    return Math.min(
+      distance,
+      Math.min(northDistance, southDistance));
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoDegenerateLongitudeSlice))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegeneratePoint.java Wed Jul  1 02:03:43 2015
@@ -37,12 +37,6 @@ public class GeoDegeneratePoint extends
     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;
@@ -52,26 +46,11 @@ public class GeoDegeneratePoint extends
     return GeoBBoxFactory.makeGeoBBox(planetModel, 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 not on the plane, no intersection
@@ -85,15 +64,6 @@ public class GeoDegeneratePoint extends
     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)
@@ -102,9 +72,16 @@ public class GeoDegeneratePoint extends
     return bounds;
   }
 
-  /**
-   * Equals
-   */
+  @Override
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+    return distanceStyle.computeDistance(this, point);
+  }
+
+  @Override
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    return distanceStyle.computeDistance(this, x,y,z);
+  }
+
   @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoDegeneratePoint))
@@ -128,61 +105,26 @@ public class GeoDegeneratePoint extends
     return "GeoDegeneratePoint: {planetmodel="+planetModel+", 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)) {

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDegenerateVerticalLine.java Wed Jul  1 02:03:43 2015
@@ -103,14 +103,6 @@ public class GeoDegenerateVerticalLine e
   }
 
   @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) &&
@@ -128,11 +120,6 @@ public class GeoDegenerateVerticalLine e
     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;
@@ -148,15 +135,6 @@ public class GeoDegenerateVerticalLine e
     return p.intersects(planetModel, 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)
@@ -184,6 +162,18 @@ public class GeoDegenerateVerticalLine e
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, topPlane, bottomPlane, boundingPlane);
+    
+    final double UHCDistance = distanceStyle.computeDistance(UHC, x,y,z);
+    final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
+    
+    return Math.min(
+      distance,
+      Math.min(UHCDistance, LHCDistance));
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoDegenerateVerticalLine))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDistance.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDistance.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoDistance.java Wed Jul  1 02:03:43 2015
@@ -18,136 +18,43 @@ package org.apache.lucene.spatial.spatia
  */
 
 /**
- * Generic geo-distance-capable shape class description.  An implementer
- * of this interface is capable of computing the described "distance" values,
+ * An implementer of this interface is capable of computing the described "distance" values,
  * which are meant to provide both actual distance values, as well as
  * distance estimates that can be computed more cheaply.
  *
  * @lucene.experimental
  */
 public interface GeoDistance extends Membership {
-  /**
-   * Compute this shape's normal "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   *
-   * @param point is the point to compute the distance to.
-   * @return the normal distance, defined as the perpendicular distance from
-   * from the point to one of the shape's bounding plane.  Normal
-   * distances can therefore typically only go up to PI/2, except
-   * when they represent the sum of a sequence of normal distances.
-   */
-  public double computeNormalDistance(GeoPoint point);
-
-  /**
-   * Compute this shape's normal "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   *
-   * @param x is the point's unit x coordinate (using U.S. convention).
-   * @param y is the point's unit y coordinate (using U.S. convention).
-   * @param z is the point's unit z coordinate (using U.S. convention).
-   * @return the normal distance, defined as the perpendicular distance from
-   * from the point to one of the shape's bounding plane.  Normal
-   * distances can therefore typically only go up to PI/2, except
-   * when they represent the sum of a sequence of normal distances.
-   */
-  public double computeNormalDistance(double x, double y, double z);
-
-  /**
-   * Compute the square of this shape's normal "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   *
-   * @param point is the point to compute the distance to.
-   * @return the square of the normal distance, defined as the perpendicular
-   * distance from
-   * from the point to one of the shape's bounding plane.  Normal
-   * distances can therefore typically only go up to PI/2, except
-   * when they represent the sum of a sequence of normal distances.
-   */
-  public double computeSquaredNormalDistance(GeoPoint point);
-
-  /**
-   * Compute the square of this shape's normal "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   *
-   * @param x is the point's unit x coordinate (using U.S. convention).
-   * @param y is the point's unit y coordinate (using U.S. convention).
-   * @param z is the point's unit z coordinate (using U.S. convention).
-   * @return the square of the  normal distance, defined as the perpendicular
-   * distance from
-   * from the point to one of the shape's bounding plane.  Normal
-   * distances can therefore typically only go up to PI/2, except
-   * when they represent the sum of a sequence of normal distances.
-   */
-  public double computeSquaredNormalDistance(double x, double y, double z);
-
-  /**
-   * Compute this shape's linear "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   *
-   * @param point is the point to compute the distance to.
-   * @return the linear (or chord) distance, defined as the distance from
-   * from the point to the nearest point on the unit sphere and on one of the shape's
-   * bounding planes.  Linear distances can therefore typically go up to PI,
-   * except when they represent the sum of a sequence of linear distances.
-   */
-  public double computeLinearDistance(GeoPoint point);
-
-  /**
-   * Compute this shape's linear "distance" to the GeoPoint.
-   * A return value of Double.MAX_VALUE should be returned for
-   * points outside of the shape.
-   *
-   * @param x is the point's unit x coordinate (using U.S. convention).
-   * @param y is the point's unit y coordinate (using U.S. convention).
-   * @param z is the point's unit z coordinate (using U.S. convention).
-   * @return the linear (or chord) distance, defined as the distance from
-   * from the point to the nearest point on the unit sphere and on one of the shape's
-   * bounding planes.  Linear distances can therefore typically go up to PI,
-   * except when they represent the sum of a sequence of linear distances.
-   */
-  public double computeLinearDistance(double x, double y, double z);
+  
+  // The following methods compute distances from the shape to a point
+  // expected to be INSIDE the shape.  Typically a value of Double.MAX_VALUE
+  // is returned for points that happen to be outside the shape.
 
   /**
-   * Compute the square of this shape's linear "distance" to the GeoPoint.
+   * Compute this shape's <em>internal</em> "distance" to the GeoPoint.
+   * Implementations should clarify how this is computed when it's non-obvious.
    * A return value of Double.MAX_VALUE should be returned for
    * points outside of the shape.
    *
+   * @param distanceStyle is the distance style.
    * @param point is the point to compute the distance to.
-   * @return the square of the linear (or chord) distance, defined as the
-   * distance from
-   * from the point to the nearest point on the unit sphere and on one of the shape's
-   * bounding planes.  Linear distances can therefore typically go up to PI,
-   * except when they represent the sum of a sequence of linear distances.
+   * @return the distance.
    */
-  public double computeSquaredLinearDistance(GeoPoint point);
+  public default double computeDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+    return computeDistance(distanceStyle, point.x, point.y, point.z);
+  }
 
   /**
-   * Compute the square of this shape's linear "distance" to the GeoPoint.
+   * Compute this shape's <em>internal</em> "distance" to the GeoPoint.
+   * Implementations should clarify how this is computed when it's non-obvious.
    * A return value of Double.MAX_VALUE should be returned for
    * points outside of the shape.
    *
    * @param x is the point's unit x coordinate (using U.S. convention).
    * @param y is the point's unit y coordinate (using U.S. convention).
    * @param z is the point's unit z coordinate (using U.S. convention).
-   * @return the square of the linear (or chord) distance, defined as the distance from
-   * from the point to the nearest point on the unit sphere and on one of the shape's
-   * bounding planes.  Linear distances can therefore typically go up to PI,
-   * except when they represent the sum of a sequence of linear distances.
-   */
-  public double computeSquaredLinearDistance(double x, double y, double z);
-
-  /**
-   * Compute a true, accurate, great-circle distance to a point.
-   * Double.MAX_VALUE indicates a point is outside of the shape.
-   *
-   * @param point is the point.
    * @return the distance.
    */
-  public double computeArcDistance(GeoPoint point);
+  public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
 
 }

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLatitudeZone.java Wed Jul  1 02:03:43 2015
@@ -71,12 +71,6 @@ public class GeoLatitudeZone extends Geo
   }
 
   @Override
-  public boolean isWithin(final Vector point) {
-    return topPlane.isWithin(point) &&
-        bottomPlane.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);
@@ -94,11 +88,6 @@ public class GeoLatitudeZone extends Geo
     return maxCosLat * Math.PI;
   }
 
-  /**
-   * Returns the center of a circle into which the area will be inscribed.
-   *
-   * @return the center.
-   */
   @Override
   public GeoPoint getCenter() {
     // This is totally arbitrary and only a cartesian could agree with it.
@@ -116,15 +105,6 @@ public class GeoLatitudeZone extends Geo
         p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds, topPlane);
   }
 
-  /**
-   * Compute longitude/latitude bounds for the shape.
-   *
-   * @param bounds is the optional input bounds object.  If this is null,
-   *               a bounds object will be created.  Otherwise, the input object will be modified.
-   * @return a Bounds object describing the shape's bounds.  If the bounds cannot
-   * be computed, then return a Bounds object with noLongitudeBound,
-   * noTopLatitudeBound, and noBottomLatitudeBound.
-   */
   @Override
   public Bounds getBounds(Bounds bounds) {
     if (bounds == null)
@@ -174,6 +154,14 @@ public class GeoLatitudeZone extends Geo
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane);
+    final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane);
+
+    return Math.min(topDistance, bottomDistance);
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoLatitudeZone))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoLongitudeSlice.java Wed Jul  1 02:03:43 2015
@@ -20,7 +20,7 @@ package org.apache.lucene.spatial.spatia
 /**
  * Bounding box limited on left and right.
  * The left-right maximum extent for this shape is PI; for anything larger, use
- * GeoWideLongitudeSlice.
+ * {@link GeoWideLongitudeSlice}.
  *
  * @lucene.internal
  */
@@ -92,12 +92,6 @@ public class GeoLongitudeSlice extends G
   }
 
   @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);
@@ -112,11 +106,6 @@ public class GeoLongitudeSlice extends G
     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;
@@ -133,15 +122,6 @@ public class GeoLongitudeSlice extends G
         p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds, leftPlane);
   }
 
-  /**
-   * 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)
@@ -179,6 +159,20 @@ public class GeoLongitudeSlice extends G
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane);
+    final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane);
+    
+    final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
+    final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
+    
+    return
+      Math.min(
+        Math.min(northDistance, southDistance),
+        Math.min(leftDistance, rightDistance));
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoLongitudeSlice))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoMembershipShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoMembershipShape.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoMembershipShape.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoMembershipShape.java Wed Jul  1 02:03:43 2015
@@ -23,6 +23,6 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.experimental
  */
-public interface GeoMembershipShape extends GeoShape, Membership {
+public interface GeoMembershipShape extends GeoShape, GeoOutsideDistance, Membership {
 
 }

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthLatitudeZone.java Wed Jul  1 02:03:43 2015
@@ -60,12 +60,6 @@ public class GeoNorthLatitudeZone extend
   }
 
   @Override
-  public boolean isWithin(final Vector point) {
-    return
-        bottomPlane.isWithin(point);
-  }
-
-  @Override
   public boolean isWithin(final double x, final double y, final double z) {
     return
         bottomPlane.isWithin(x, y, z);
@@ -81,11 +75,6 @@ public class GeoNorthLatitudeZone extend
     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;
@@ -102,15 +91,6 @@ public class GeoNorthLatitudeZone extend
         p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds);
   }
 
-  /**
-   * Compute longitude/latitude bounds for the shape.
-   *
-   * @param bounds is the optional input bounds object.  If this is null,
-   *               a bounds object will be created.  Otherwise, the input object will be modified.
-   * @return a Bounds object describing the shape's bounds.  If the bounds cannot
-   * be computed, then return a Bounds object with noLongitudeBound,
-   * noTopLatitudeBound, and noBottomLatitudeBound.
-   */
   @Override
   public Bounds getBounds(Bounds bounds) {
     if (bounds == null)
@@ -133,8 +113,7 @@ public class GeoNorthLatitudeZone extend
     // Second, the shortcut of seeing whether endpoints are in/out is not going to
     // work with no area endpoints.  So we rely entirely on intersections.
 
-    if (
-        path.intersects(bottomPlane, planePoints))
+    if (path.intersects(bottomPlane, planePoints))
       return OVERLAPS;
 
     // There is another case for latitude zones only.  This is when the boundaries of the shape all fit
@@ -153,6 +132,11 @@ public class GeoNorthLatitudeZone extend
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    return distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z);
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoNorthLatitudeZone))
       return false;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoNorthRectangle.java Wed Jul  1 02:03:43 2015
@@ -21,7 +21,7 @@ package org.apache.lucene.spatial.spatia
  * Bounding box limited on three sides (bottom lat, left lon, right lon), including
  * the north pole.
  * The left-right maximum extent for this shape is PI; for anything larger, use
- * GeoWideNorthRectangle.
+ * {@link GeoWideNorthRectangle}.
  *
  * @lucene.internal
  */
@@ -123,14 +123,6 @@ public class GeoNorthRectangle extends G
   }
 
   @Override
-  public boolean isWithin(final Vector point) {
-    return
-        bottomPlane.isWithin(point) &&
-            leftPlane.isWithin(point) &&
-            rightPlane.isWithin(point);
-  }
-
-  @Override
   public boolean isWithin(final double x, final double y, final double z) {
     return
         bottomPlane.isWithin(x, y, z) &&
@@ -171,15 +163,6 @@ public class GeoNorthRectangle extends G
             p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, bottomPlane);
   }
 
-  /**
-   * Compute longitude/latitude bounds for the shape.
-   *
-   * @param bounds is the optional input bounds object.  If this is null,
-   *               a bounds object will be created.  Otherwise, the input object will be modified.
-   * @return a Bounds object describing the shape's bounds.  If the bounds cannot
-   * be computed, then return a Bounds object with noLongitudeBound,
-   * noTopLatitudeBound, and noBottomLatitudeBound.
-   */
   @Override
   public Bounds getBounds(Bounds bounds) {
     if (bounds == null)
@@ -227,6 +210,23 @@ public class GeoNorthRectangle extends G
   }
 
   @Override
+  protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+    final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, leftPlane, rightPlane);
+    final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, bottomPlane);
+    final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, bottomPlane);
+    
+    final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+    final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+    
+    return
+      Math.min(
+        bottomDistance,
+        Math.min(
+          Math.min(leftDistance, rightDistance),
+          Math.min(LRHCDistance, LLHCDistance)));
+  }
+
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof GeoNorthRectangle))
       return false;

Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoOutsideDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoOutsideDistance.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoOutsideDistance.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoOutsideDistance.java Wed Jul  1 02:03:43 2015
@@ -0,0 +1,56 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implemented by Geo3D shapes that can compute the distance from a point to the closest outside edge.
+ *
+ * @lucene.experimental
+ */
+public interface GeoOutsideDistance extends Membership {
+  
+  // The following methods compute distances from the shape to a point
+  // expected to be OUTSIDE the shape.  Typically a value of 0.0
+  // is returned for points that happen to be within the shape.
+  
+  /**
+   * Compute this shape's distance to the GeoPoint.
+   * A return value of 0.0 should be returned for
+   * points inside of the shape.
+   * @param distanceStyle is the distance style.
+   * @param point is the point to compute the distance to.
+   * @return the distance.
+   */
+  public default double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+    return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
+  }
+
+  /**
+   * Compute this shape's distance to the GeoPoint.
+   * A return value of 0.0 should be returned for
+   * points inside of the shape.
+   * @param distanceStyle is the distance style.
+   * @param x is the point's unit x coordinate (using U.S. convention).
+   * @param y is the point's unit y coordinate (using U.S. convention).
+   * @param z is the point's unit z coordinate (using U.S. convention).
+   * @return the distance.
+   */
+  public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
+