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 2016/03/08 02:19:51 UTC

[10/32] lucene-solr git commit: LUCENE-7056: Geo3D package re-org (cherry picked from commit 0093e26)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java
deleted file mode 100644
index f6a2fa3..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Y
- *
- * @lucene.internal
- */
-public class XdYZSolid extends BaseXYZSolid {
-
-  /** Min-X plane */
-  protected final SidedPlane minXPlane;
-  /** Max-X plane */
-  protected final SidedPlane maxXPlane;
-  /** Y plane */
-  protected final Plane yPlane;
-  /** Min-Z plane */
-  protected final SidedPlane minZPlane;
-  /** Max-Z plane */
-  protected final SidedPlane maxZPlane;
-  
-  /** These are the edge points of the shape, which are defined to be at least one point on
-   * each surface area boundary.  In the case of a solid, this includes points which represent
-   * the intersection of XYZ bounding planes and the planet, as well as points representing
-   * the intersection of single bounding planes with the planet itself.
-   */
-  protected final GeoPoint[] edgePoints;
-
-  /** Notable points for YPlane */
-  protected final GeoPoint[] notableYPoints;
-
-  /**
-   * Sole constructor
-   *
-   *@param planetModel is the planet model.
-   *@param minX is the minimum X value.
-   *@param maxX is the maximum X value.
-   *@param Y is the Y value.
-   *@param minZ is the minimum Z value.
-   *@param maxZ is the maximum Z value.
-   */
-  public XdYZSolid(final PlanetModel planetModel,
-    final double minX,
-    final double maxX,
-    final double Y,
-    final double minZ,
-    final double maxZ) {
-    super(planetModel);
-    // Argument checking
-    if (maxX - minX < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("X values in wrong order or identical");
-    if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("Z values in wrong order or identical");
-
-    final double worldMinY = planetModel.getMinimumYValue();
-    final double worldMaxY = planetModel.getMaximumYValue();
-    
-    // Construct the planes
-    minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
-    maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
-    yPlane = new Plane(yUnitVector,-Y);
-    minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
-    maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
-      
-    // We need at least one point on the planet surface for each manifestation of the shape.
-    // There can be up to 2 (on opposite sides of the world).  But we have to go through
-    // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
-    // Typically, this requires 4 square root operations. 
-    final GeoPoint[] minXY = minXPlane.findIntersections(planetModel,yPlane,maxXPlane,minZPlane,maxZPlane);
-    final GeoPoint[] maxXY = maxXPlane.findIntersections(planetModel,yPlane,minXPlane,minZPlane,maxZPlane);
-    final GeoPoint[] YminZ = yPlane.findIntersections(planetModel,minZPlane,maxZPlane,minXPlane,maxXPlane);
-    final GeoPoint[] YmaxZ = yPlane.findIntersections(planetModel,maxZPlane,minZPlane,minXPlane,maxXPlane);
-      
-    notableYPoints = glueTogether(minXY, maxXY, YminZ, YmaxZ);
-
-    // Now, compute the edge points.
-    // This is the trickiest part of setting up an XYZSolid.  We've computed intersections already, so
-    // we'll start there.  We know that at most there will be two disconnected shapes on the planet surface.
-    // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
-    // intersections do.  Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
-      
-    // We need to look at single-plane/world intersections.
-    // We detect these by looking at the world model and noting its x, y, and z bounds.
-    // The cases we are looking for are when the four corner points for any given
-    // plane are all outside of the world, AND that plane intersects the world.
-    // There are four corner points all told; we must evaluate these WRT the planet surface.
-    final boolean minXYminZ = planetModel.pointOutside(minX, Y, minZ);
-    final boolean minXYmaxZ = planetModel.pointOutside(minX, Y, maxZ);
-    final boolean maxXYminZ = planetModel.pointOutside(maxX, Y, minZ);
-    final boolean maxXYmaxZ = planetModel.pointOutside(maxX, Y, maxZ);
-
-    final GeoPoint[] yEdges;
-    if (Y - worldMinY >= -Vector.MINIMUM_RESOLUTION && Y - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
-      minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
-      minXYminZ && minXYmaxZ && maxXYminZ && maxXYmaxZ) {
-      // Find any point on the minY plane that intersects the world
-      // First construct a perpendicular plane that will allow us to find a sample point.
-      // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
-      // Then use it to compute a sample point.
-      final GeoPoint intPoint = yPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
-      if (intPoint != null) {
-        yEdges = new GeoPoint[]{intPoint};
-      } else {
-        yEdges = EMPTY_POINTS;
-      }
-    } else {
-      yEdges = EMPTY_POINTS;
-    }
-
-    this.edgePoints = glueTogether(minXY, maxXY, YminZ, YmaxZ, yEdges);
-  }
-
-  @Override
-  protected GeoPoint[] getEdgePoints() {
-    return edgePoints;
-  }
-  
-  @Override
-  public boolean isWithin(final double x, final double y, final double z) {
-    return minXPlane.isWithin(x, y, z) &&
-      maxXPlane.isWithin(x, y, z) &&
-      yPlane.evaluateIsZero(x, y, z) &&
-      minZPlane.isWithin(x, y, z) &&
-      maxZPlane.isWithin(x, y, z);
-  }
-
-  @Override
-  public int getRelationship(final GeoShape path) {
-    //System.err.println(this+" getrelationship with "+path);
-    final int insideRectangle = isShapeInsideArea(path);
-    if (insideRectangle == SOME_INSIDE) {
-      //System.err.println(" some inside");
-      return OVERLAPS;
-    }
-
-    // Figure out if the entire XYZArea is contained by the shape.
-    final int insideShape = isAreaInsideShape(path);
-    if (insideShape == SOME_INSIDE) {
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
-      //System.err.println(" inside of each other");
-      return OVERLAPS;
-    }
-
-    if (path.intersects(yPlane, notableYPoints, minXPlane, maxXPlane, minZPlane, maxZPlane)) {
-      //System.err.println(" edges intersect");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE) {
-      //System.err.println(" shape inside rectangle");
-      return WITHIN;
-    }
-
-    if (insideShape == ALL_INSIDE) {
-      //System.err.println(" shape contains rectangle");
-      return CONTAINS;
-    }
-    //System.err.println(" disjoint");
-    return DISJOINT;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof XdYZSolid))
-      return false;
-    XdYZSolid other = (XdYZSolid) o;
-    if (!super.equals(other)) {
-      return false;
-    }
-    return other.minXPlane.equals(minXPlane) &&
-      other.maxXPlane.equals(maxXPlane) &&
-      other.yPlane.equals(yPlane) &&
-      other.minZPlane.equals(minZPlane) &&
-      other.maxZPlane.equals(maxZPlane);
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result  + minXPlane.hashCode();
-    result = 31 * result  + maxXPlane.hashCode();
-    result = 31 * result  + yPlane.hashCode();
-    result = 31 * result  + minZPlane.hashCode();
-    result = 31 * result  + maxZPlane.hashCode();
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    return "XdYZSolid: {planetmodel="+planetModel+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", yplane="+yPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
-  }
-  
-}
-  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java
deleted file mode 100644
index 562e5a6..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Y and Z.
- * This figure, in fact, represents either zero, one, or two points, so the
- * actual data stored is minimal.
- *
- * @lucene.internal
- */
-public class XdYdZSolid extends BaseXYZSolid {
-
-  /** The points in this figure on the planet surface; also doubles for edge points */
-  protected final GeoPoint[] surfacePoints;
-  
-  /**
-   * Sole constructor
-   *
-   *@param planetModel is the planet model.
-   *@param minX is the minimum X value.
-   *@param maxX is the maximum X value.
-   *@param Y is the Y value.
-   *@param Z is the Z value.
-   */
-  public XdYdZSolid(final PlanetModel planetModel,
-    final double minX,
-    final double maxX,
-    final double Y,
-    final double Z) {
-    super(planetModel);
-    // Argument checking
-    if (maxX - minX < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("X values in wrong order or identical");
-
-    // Build the planes and intersect them.
-    final Plane yPlane = new Plane(yUnitVector,-Y);
-    final Plane zPlane = new Plane(zUnitVector,-Z);
-    final SidedPlane minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
-    final SidedPlane maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
-    surfacePoints = yPlane.findIntersections(planetModel,zPlane,minXPlane,maxXPlane);
-  }
-
-  @Override
-  protected GeoPoint[] getEdgePoints() {
-    return surfacePoints;
-  }
-  
-  @Override
-  public boolean isWithin(final double x, final double y, final double z) {
-    for (final GeoPoint p : surfacePoints) {
-      if (p.isIdentical(x,y,z))
-        return true;
-    }
-    return false;
-  }
-
-  @Override
-  public int getRelationship(final GeoShape path) {
-    //System.err.println(this+" getrelationship with "+path);
-    final int insideRectangle = isShapeInsideArea(path);
-    if (insideRectangle == SOME_INSIDE) {
-      //System.err.println(" some inside");
-      return OVERLAPS;
-    }
-
-    // Figure out if the entire XYZArea is contained by the shape.
-    final int insideShape = isAreaInsideShape(path);
-    if (insideShape == SOME_INSIDE) {
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
-      //System.err.println(" inside of each other");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE) {
-      return WITHIN;
-    }
-    
-    if (insideShape == ALL_INSIDE) {
-      //System.err.println(" shape contains rectangle");
-      return CONTAINS;
-    }
-    //System.err.println(" disjoint");
-    return DISJOINT;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof XdYdZSolid))
-      return false;
-    XdYdZSolid other = (XdYdZSolid) o;
-    if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
-      return false;
-    }
-    for (int i = 0; i < surfacePoints.length; i++) {
-      if (!surfacePoints[i].equals(other.surfacePoints[i]))
-        return false;
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    for (final GeoPoint p : surfacePoints) {
-      result = 31 * result  + p.hashCode();
-    }
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    final StringBuilder sb = new StringBuilder();
-    for (final GeoPoint p : surfacePoints) {
-      sb.append(" ").append(p).append(" ");
-    }
-    return "XdYdZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
-  }
-  
-}
-  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java
deleted file mode 100644
index 5a2a006..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X.
- *
- * @lucene.internal
- */
-public class dXYZSolid extends BaseXYZSolid {
-
-  /** X plane */
-  protected final Plane xPlane;
-  /** Min-Y plane */
-  protected final SidedPlane minYPlane;
-  /** Max-Y plane */
-  protected final SidedPlane maxYPlane;
-  /** Min-Z plane */
-  protected final SidedPlane minZPlane;
-  /** Max-Z plane */
-  protected final SidedPlane maxZPlane;
-  
-  /** These are the edge points of the shape, which are defined to be at least one point on
-   * each surface area boundary.  In the case of a solid, this includes points which represent
-   * the intersection of XYZ bounding planes and the planet, as well as points representing
-   * the intersection of single bounding planes with the planet itself.
-   */
-  protected final GeoPoint[] edgePoints;
-
-  /** Notable points for XPlane */
-  protected final GeoPoint[] notableXPoints;
-
-  /**
-   * Sole constructor
-   *
-   *@param planetModel is the planet model.
-   *@param X is the X value.
-   *@param minY is the minimum Y value.
-   *@param maxY is the maximum Y value.
-   *@param minZ is the minimum Z value.
-   *@param maxZ is the maximum Z value.
-   */
-  public dXYZSolid(final PlanetModel planetModel,
-    final double X,
-    final double minY,
-    final double maxY,
-    final double minZ,
-    final double maxZ) {
-    super(planetModel);
-    // Argument checking
-    if (maxY - minY < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("Y values in wrong order or identical");
-    if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("Z values in wrong order or identical");
-
-    final double worldMinX = planetModel.getMinimumXValue();
-    final double worldMaxX = planetModel.getMaximumXValue();
-    
-    // Construct the planes
-    xPlane = new Plane(xUnitVector,-X);
-    minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
-    maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
-    minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
-    maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
-      
-    // We need at least one point on the planet surface for each manifestation of the shape.
-    // There can be up to 2 (on opposite sides of the world).  But we have to go through
-    // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
-    // Typically, this requires 4 square root operations. 
-    final GeoPoint[] XminY = xPlane.findIntersections(planetModel,minYPlane,maxYPlane,minZPlane,maxZPlane);
-    final GeoPoint[] XmaxY = xPlane.findIntersections(planetModel,maxYPlane,minYPlane,minZPlane,maxZPlane);
-    final GeoPoint[] XminZ = xPlane.findIntersections(planetModel,minZPlane,maxZPlane,minYPlane,maxYPlane);
-    final GeoPoint[] XmaxZ = xPlane.findIntersections(planetModel,maxZPlane,minZPlane,minYPlane,maxYPlane);
-
-    notableXPoints = glueTogether(XminY, XmaxY, XminZ, XmaxZ);
-
-    // Now, compute the edge points.
-    // This is the trickiest part of setting up an XYZSolid.  We've computed intersections already, so
-    // we'll start there.  We know that at most there will be two disconnected shapes on the planet surface.
-    // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
-    // intersections do.  Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
-      
-    // We need to look at single-plane/world intersections.
-    // We detect these by looking at the world model and noting its x, y, and z bounds.
-    // For the single-dimension degenerate case, there's really only one plane that can possibly intersect the world.
-    // The cases we are looking for are when the four corner points for any given
-    // plane are all outside of the world, AND that plane intersects the world.
-    // There are four corner points all told; we must evaluate these WRT the planet surface.
-    final boolean XminYminZ = planetModel.pointOutside(X, minY, minZ);
-    final boolean XminYmaxZ = planetModel.pointOutside(X, minY, maxZ);
-    final boolean XmaxYminZ = planetModel.pointOutside(X, maxY, minZ);
-    final boolean XmaxYmaxZ = planetModel.pointOutside(X, maxY, maxZ);
-
-    final GeoPoint[] xEdges;
-    if (X - worldMinX >= -Vector.MINIMUM_RESOLUTION && X - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
-      minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
-      XminYminZ && XminYmaxZ && XmaxYminZ && XmaxYmaxZ) {
-      // Find any point on the X plane that intersects the world
-      // First construct a perpendicular plane that will allow us to find a sample point.
-      // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
-      // Then use it to compute a sample point.
-      final GeoPoint intPoint = xPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
-      if (intPoint != null) {
-        xEdges = new GeoPoint[]{intPoint};
-      } else {
-        xEdges = EMPTY_POINTS;
-      }
-    } else {
-      xEdges = EMPTY_POINTS;
-    }
-
-    this.edgePoints = glueTogether(XminY,XmaxY,XminZ,XmaxZ,xEdges);
-  }
-
-  @Override
-  protected GeoPoint[] getEdgePoints() {
-    return edgePoints;
-  }
-  
-  @Override
-  public boolean isWithin(final double x, final double y, final double z) {
-    return xPlane.evaluateIsZero(x, y, z) &&
-      minYPlane.isWithin(x, y, z) &&
-      maxYPlane.isWithin(x, y, z) &&
-      minZPlane.isWithin(x, y, z) &&
-      maxZPlane.isWithin(x, y, z);
-  }
-
-  @Override
-  public int getRelationship(final GeoShape path) {
-    //System.err.println(this+" getrelationship with "+path);
-    final int insideRectangle = isShapeInsideArea(path);
-    if (insideRectangle == SOME_INSIDE) {
-      //System.err.println(" some shape points inside area");
-      return OVERLAPS;
-    }
-
-    // Figure out if the entire XYZArea is contained by the shape.
-    final int insideShape = isAreaInsideShape(path);
-    if (insideShape == SOME_INSIDE) {
-      //System.err.println(" some area points inside shape");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
-      //System.err.println(" inside of each other");
-      return OVERLAPS;
-    }
-
-    // The entire locus of points in this shape is on a single plane, so we only need ot look for an intersection with that plane.
-    //System.err.println("xPlane = "+xPlane);
-    if (path.intersects(xPlane, notableXPoints, minYPlane, maxYPlane, minZPlane, maxZPlane)) {
-      //System.err.println(" edges intersect");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE) {
-      //System.err.println(" shape points inside area");
-      return WITHIN;
-    }
-
-    if (insideShape == ALL_INSIDE) {
-      //System.err.println(" shape contains all area");
-      return CONTAINS;
-    }
-    //System.err.println(" disjoint");
-    return DISJOINT;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof dXYZSolid))
-      return false;
-    dXYZSolid other = (dXYZSolid) o;
-    if (!super.equals(other)) {
-      return false;
-    }
-    return other.xPlane.equals(xPlane) &&
-      other.minYPlane.equals(minYPlane) &&
-      other.maxYPlane.equals(maxYPlane) &&
-      other.minZPlane.equals(minZPlane) &&
-      other.maxZPlane.equals(maxZPlane);
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result  + xPlane.hashCode();
-    result = 31 * result  + minYPlane.hashCode();
-    result = 31 * result  + maxYPlane.hashCode();
-    result = 31 * result  + minZPlane.hashCode();
-    result = 31 * result  + maxZPlane.hashCode();
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    return "dXYZSolid: {planetmodel="+planetModel+", xplane="+xPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
-  }
-  
-}
-  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java
deleted file mode 100644
index 96b3004..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X and Z.
- * This figure, in fact, represents either zero, one, or two points, so the
- * actual data stored is minimal.
- *
- * @lucene.internal
- */
-public class dXYdZSolid extends BaseXYZSolid {
-
-  /** The points in this figure on the planet surface; also doubles for edge points */
-  protected final GeoPoint[] surfacePoints;
-  
-  /**
-   * Sole constructor
-   *
-   *@param planetModel is the planet model.
-   *@param X is the X value.
-   *@param minY is the minimum Y value.
-   *@param maxY is the maximum Y value.
-   *@param Z is the Z value.
-   */
-  public dXYdZSolid(final PlanetModel planetModel,
-    final double X,
-    final double minY,
-    final double maxY,
-    final double Z) {
-    super(planetModel);
-    // Argument checking
-    if (maxY - minY < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("Y values in wrong order or identical");
-
-    // Build the planes and intersect them.
-    final Plane xPlane = new Plane(xUnitVector,-X);
-    final Plane zPlane = new Plane(zUnitVector,-Z);
-    final SidedPlane minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
-    final SidedPlane maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
-    surfacePoints = xPlane.findIntersections(planetModel,zPlane,minYPlane,maxYPlane);
-  }
-
-  @Override
-  protected GeoPoint[] getEdgePoints() {
-    return surfacePoints;
-  }
-  
-  @Override
-  public boolean isWithin(final double x, final double y, final double z) {
-    for (final GeoPoint p : surfacePoints) {
-      if (p.isIdentical(x,y,z))
-        return true;
-    }
-    return false;
-  }
-
-  @Override
-  public int getRelationship(final GeoShape path) {
-    //System.err.println(this+" getrelationship with "+path);
-    final int insideRectangle = isShapeInsideArea(path);
-    if (insideRectangle == SOME_INSIDE) {
-      //System.err.println(" some inside");
-      return OVERLAPS;
-    }
-
-    // Figure out if the entire XYZArea is contained by the shape.
-    final int insideShape = isAreaInsideShape(path);
-    if (insideShape == SOME_INSIDE) {
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
-      //System.err.println(" inside of each other");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE) {
-      return WITHIN;
-    }
-    
-    if (insideShape == ALL_INSIDE) {
-      //System.err.println(" shape contains rectangle");
-      return CONTAINS;
-    }
-    //System.err.println(" disjoint");
-    return DISJOINT;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof dXYdZSolid))
-      return false;
-    dXYdZSolid other = (dXYdZSolid) o;
-    if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
-      return false;
-    }
-    for (int i = 0; i < surfacePoints.length; i++) {
-      if (!surfacePoints[i].equals(other.surfacePoints[i]))
-        return false;
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    for (final GeoPoint p : surfacePoints) {
-      result = 31 * result  + p.hashCode();
-    }
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    final StringBuilder sb = new StringBuilder();
-    for (final GeoPoint p : surfacePoints) {
-      sb.append(" ").append(p).append(" ");
-    }
-    return "dXYdZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
-  }
-  
-}
-  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java
deleted file mode 100644
index b58cd92..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X and Y.
- * This figure, in fact, represents either zero, one, or two points, so the
- * actual data stored is minimal.
- *
- * @lucene.internal
- */
-public class dXdYZSolid extends BaseXYZSolid {
-
-  /** The points in this figure on the planet surface; also doubles for edge points */
-  protected final GeoPoint[] surfacePoints;
-  
-  /**
-   * Sole constructor
-   *
-   *@param planetModel is the planet model.
-   *@param X is the X value.
-   *@param Y is the Y value.
-   *@param minZ is the minimum Z value.
-   *@param maxZ is the maximum Z value.
-   */
-  public dXdYZSolid(final PlanetModel planetModel,
-    final double X,
-    final double Y,
-    final double minZ,
-    final double maxZ) {
-    super(planetModel);
-    // Argument checking
-    if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
-      throw new IllegalArgumentException("Z values in wrong order or identical");
-
-    // Build the planes and intersect them.
-    final Plane xPlane = new Plane(xUnitVector,-X);
-    final Plane yPlane = new Plane(yUnitVector,-Y);
-    final SidedPlane minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
-    final SidedPlane maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
-    surfacePoints = xPlane.findIntersections(planetModel,yPlane,minZPlane,maxZPlane);
-  }
-
-  @Override
-  protected GeoPoint[] getEdgePoints() {
-    return surfacePoints;
-  }
-  
-  @Override
-  public boolean isWithin(final double x, final double y, final double z) {
-    for (final GeoPoint p : surfacePoints) {
-      if (p.isIdentical(x,y,z))
-        return true;
-    }
-    return false;
-  }
-
-  @Override
-  public int getRelationship(final GeoShape path) {
-    //System.err.println(this+" getrelationship with "+path);
-    final int insideRectangle = isShapeInsideArea(path);
-    if (insideRectangle == SOME_INSIDE) {
-      //System.err.println(" some inside");
-      return OVERLAPS;
-    }
-
-    // Figure out if the entire XYZArea is contained by the shape.
-    final int insideShape = isAreaInsideShape(path);
-    if (insideShape == SOME_INSIDE) {
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
-      //System.err.println(" inside of each other");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE) {
-      return WITHIN;
-    }
-    
-    if (insideShape == ALL_INSIDE) {
-      //System.err.println(" shape contains rectangle");
-      return CONTAINS;
-    }
-    //System.err.println(" disjoint");
-    return DISJOINT;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof dXdYZSolid))
-      return false;
-    dXdYZSolid other = (dXdYZSolid) o;
-    if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
-      return false;
-    }
-    for (int i = 0; i < surfacePoints.length; i++) {
-      if (!surfacePoints[i].equals(other.surfacePoints[i]))
-        return false;
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    for (final GeoPoint p : surfacePoints) {
-      result = 31 * result  + p.hashCode();
-    }
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    final StringBuilder sb = new StringBuilder();
-    for (final GeoPoint p : surfacePoints) {
-      sb.append(" ").append(p).append(" ");
-    }
-    return "dXdYZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
-  }
-  
-}
-  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java
deleted file mode 100644
index b26cf63..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in all dimensions
- *
- * @lucene.internal
- */
-public class dXdYdZSolid extends BaseXYZSolid {
-
-  /** On surface? */
-  protected final boolean isOnSurface;
-  /** The point */
-  protected final GeoPoint thePoint;
-  
-  /** These are the edge points of the shape, which are defined to be at least one point on
-   * each surface area boundary.  In the case of a solid, this includes points which represent
-   * the intersection of XYZ bounding planes and the planet, as well as points representing
-   * the intersection of single bounding planes with the planet itself.
-   */
-  protected final GeoPoint[] edgePoints;
-
-  /** Empty array of {@link GeoPoint}. */
-  protected static final GeoPoint[] nullPoints = new GeoPoint[0];
-  
-  /**
-   * Sole constructor
-   *
-   *@param planetModel is the planet model.
-   *@param X is the X value.
-   *@param Y is the Y value.
-   *@param Z is the Z value.
-   */
-  public dXdYdZSolid(final PlanetModel planetModel,
-    final double X,
-    final double Y,
-    final double Z) {
-    super(planetModel);
-    isOnSurface = planetModel.pointOnSurface(X,Y,Z);
-    if (isOnSurface) {
-      thePoint = new GeoPoint(X,Y,Z);
-      edgePoints = new GeoPoint[]{thePoint};
-    } else {
-      thePoint = null;
-      edgePoints = nullPoints;
-    }
-  }
-
-  @Override
-  protected GeoPoint[] getEdgePoints() {
-    return edgePoints;
-  }
-  
-  @Override
-  public boolean isWithin(final double x, final double y, final double z) {
-    if (!isOnSurface) {
-      return false;
-    }
-    return thePoint.isIdentical(x,y,z);
-  }
-
-  @Override
-  public int getRelationship(final GeoShape path) {
-    if (!isOnSurface) {
-      return DISJOINT;
-    }
-    
-    //System.err.println(this+" getrelationship with "+path);
-    final int insideRectangle = isShapeInsideArea(path);
-    if (insideRectangle == SOME_INSIDE) {
-      //System.err.println(" some shape points inside area");
-      return OVERLAPS;
-    }
-
-    // Figure out if the entire XYZArea is contained by the shape.
-    final int insideShape = isAreaInsideShape(path);
-    if (insideShape == SOME_INSIDE) {
-      //System.err.println(" some area points inside shape");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
-      //System.err.println(" inside of each other");
-      return OVERLAPS;
-    }
-
-    if (insideRectangle == ALL_INSIDE) {
-      //System.err.println(" shape inside area entirely");
-      return WITHIN;
-    }
-
-    if (insideShape == ALL_INSIDE) {
-      //System.err.println(" shape contains area entirely");
-      return CONTAINS;
-    }
-    //System.err.println(" disjoint");
-    return DISJOINT;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!(o instanceof dXdYdZSolid))
-      return false;
-    dXdYdZSolid other = (dXdYdZSolid) o;
-    if (!super.equals(other) ||
-      other.isOnSurface != isOnSurface) {
-      return false;
-    }
-    if (isOnSurface) {
-      return other.thePoint.equals(thePoint);
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result + (isOnSurface?1:0);
-    if (isOnSurface) {
-      result = 31 * result  + thePoint.hashCode();
-    }
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    return "dXdYdZSolid: {planetmodel="+planetModel+", isOnSurface="+isOnSurface+", thePoint="+thePoint+"}";
-  }
-  
-}
-  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java
deleted file mode 100644
index 2b6af74..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Shapes implemented using 3D planar geometry.
- */
-package org.apache.lucene.geo3d;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
new file mode 100644
index 0000000..cd2c79a
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d;
+
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.NumericUtils;
+
+/**
+ * Add this to a document to index lat/lon or x/y/z point, indexed as a 3D point.
+ * Multiple values are allowed: just add multiple Geo3DPoint to the document with the
+ * same field name.
+ * <p>
+ * This field defines static factory methods for creating a shape query:
+ * <ul>
+ *   <li>{@link #newShapeQuery newShapeQuery()} for matching all points inside a specified shape
+ * </ul>
+ *
+ *  @lucene.experimental */
+public final class Geo3DPoint extends Field {
+
+  /** Indexing {@link FieldType}. */
+  public static final FieldType TYPE = new FieldType();
+  static {
+    TYPE.setDimensions(3, Integer.BYTES);
+    TYPE.freeze();
+  }
+
+  /** 
+   * Creates a new Geo3DPoint field with the specified lat, lon (in radians).
+   *
+   * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
+   */
+  public Geo3DPoint(String name, double lat, double lon) {
+    super(name, TYPE);
+    // Translate lat/lon to x,y,z:
+    final GeoPoint point = new GeoPoint(PlanetModel.WGS84, lat, lon);
+    fillFieldsData(point.x, point.y, point.z);
+  }
+
+  /** 
+   * Creates a new Geo3DPoint field with the specified x,y,z.
+   *
+   * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
+   */
+  public Geo3DPoint(String name, double x, double y, double z) {
+    super(name, TYPE);
+    fillFieldsData(x, y, z);
+  }
+
+  private void fillFieldsData(double x, double y, double z) {
+    byte[] bytes = new byte[12];
+    encodeDimension(x, bytes, 0);
+    encodeDimension(y, bytes, Integer.BYTES);
+    encodeDimension(z, bytes, 2*Integer.BYTES);
+    fieldsData = new BytesRef(bytes);
+  }
+
+  // public helper methods (e.g. for queries)
+  
+  /** Encode single dimension */
+  public static void encodeDimension(double value, byte bytes[], int offset) {
+    NumericUtils.intToSortableBytes(Geo3DUtil.encodeValue(PlanetModel.WGS84.getMaximumMagnitude(), value), bytes, offset);
+  }
+  
+  /** Decode single dimension */
+  public static double decodeDimension(byte value[], int offset) {
+    return Geo3DUtil.decodeValueCenter(PlanetModel.WGS84.getMaximumMagnitude(), NumericUtils.sortableBytesToInt(value, offset));
+  }
+
+  /** Returns a query matching all points inside the provided shape.
+   * 
+   * @param field field name. must not be {@code null}.
+   * @param shape Which {@link GeoShape} to match
+   */
+  public static Query newShapeQuery(String field, GeoShape shape) {
+    return new PointInGeo3DShapeQuery(field, shape);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder result = new StringBuilder();
+    result.append(getClass().getSimpleName());
+    result.append(" <");
+    result.append(name);
+    result.append(':');
+
+    BytesRef bytes = (BytesRef) fieldsData;
+    result.append(" x=" + decodeDimension(bytes.bytes, bytes.offset));
+    result.append(" y=" + decodeDimension(bytes.bytes, bytes.offset + Integer.BYTES));
+    result.append(" z=" + decodeDimension(bytes.bytes, bytes.offset + 2*Integer.BYTES));
+    result.append('>');
+    return result.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
new file mode 100644
index 0000000..0a0bf30
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d;
+
+class Geo3DUtil {
+
+  /** Clips the incoming value to the allowed min/max range before encoding, instead of throwing an exception. */
+  public static int encodeValueLenient(double planetMax, double x) {
+    if (x > planetMax) {
+      x = planetMax;
+    } else if (x < -planetMax) {
+      x = -planetMax;
+    }
+    return encodeValue(planetMax, x);
+  }
+
+  public static int encodeValue(double planetMax, double x) {
+    if (x > planetMax) {
+      throw new IllegalArgumentException("value=" + x + " is out-of-bounds (greater than planetMax=" + planetMax + ")");
+    }
+    if (x < -planetMax) {
+      throw new IllegalArgumentException("value=" + x + " is out-of-bounds (less than than -planetMax=" + -planetMax + ")");
+    }
+    long y = Math.round (x * (Integer.MAX_VALUE / planetMax));
+    assert y >= Integer.MIN_VALUE;
+    assert y <= Integer.MAX_VALUE;
+
+    return (int) y;
+  }
+
+  /** Center decode */
+  public static double decodeValueCenter(double planetMax, int x) {
+    return x * (planetMax / Integer.MAX_VALUE);
+  }
+
+  /** More negative decode, at bottom of cell */
+  public static double decodeValueMin(double planetMax, int x) {
+    return (((double)x) - 0.5) * (planetMax / Integer.MAX_VALUE);
+  }
+  
+  /** More positive decode, at top of cell  */
+  public static double decodeValueMax(double planetMax, int x) {
+    return (((double)x) + 0.5) * (planetMax / Integer.MAX_VALUE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
new file mode 100644
index 0000000..9df8752
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d;
+
+import java.io.IOException;
+
+import org.apache.lucene.spatial3d.geom.BasePlanetObject;
+import org.apache.lucene.spatial3d.geom.GeoArea;
+import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
+import org.apache.lucene.index.PointValues.IntersectVisitor;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.index.PointValues.Relation;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.util.DocIdSetBuilder;
+import org.apache.lucene.util.NumericUtils;
+
+/** Finds all previously indexed points that fall within the specified polygon.
+ *
+ * <p>The field must be indexed using {@link Geo3DPoint}.
+ *
+ * @lucene.experimental */
+
+class PointInGeo3DShapeQuery extends Query {
+  final String field;
+  final GeoShape shape;
+
+  /** The lats/lons must be clockwise or counter-clockwise. */
+  public PointInGeo3DShapeQuery(String field, GeoShape shape) {
+    this.field = field;
+    this.shape = shape;
+
+    if (shape instanceof BasePlanetObject) {
+      BasePlanetObject planetObject = (BasePlanetObject) shape;
+      if (planetObject.getPlanetModel().equals(PlanetModel.WGS84) == false) {
+        throw new IllegalArgumentException("this qurey requires PlanetModel.WGS84, but got: " + planetObject.getPlanetModel());
+      }
+    }
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+
+    // I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
+    // used in the first pass:
+
+    return new ConstantScoreWeight(this) {
+
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+        LeafReader reader = context.reader();
+        PointValues values = reader.getPointValues();
+        if (values == null) {
+          return null;
+        }
+
+        /*
+        XYZBounds bounds = new XYZBounds();
+        shape.getBounds(bounds);
+
+        final double planetMax = planetModel.getMaximumMagnitude();
+        if (planetMax != treeDV.planetMax) {
+          throw new IllegalStateException(planetModel + " is not the same one used during indexing: planetMax=" + planetMax + " vs indexing planetMax=" + treeDV.planetMax);
+        }
+        */
+
+        /*
+        GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(planetModel,
+                                                      bounds.getMinimumX(),
+                                                      bounds.getMaximumX(),
+                                                      bounds.getMinimumY(),
+                                                      bounds.getMaximumY(),
+                                                      bounds.getMinimumZ(),
+                                                      bounds.getMaximumZ());
+
+        assert xyzSolid.getRelationship(shape) == GeoArea.WITHIN || xyzSolid.getRelationship(shape) == GeoArea.OVERLAPS: "expected WITHIN (1) or OVERLAPS (2) but got " + xyzSolid.getRelationship(shape) + "; shape="+shape+"; XYZSolid="+xyzSolid;
+        */
+
+        double planetMax = PlanetModel.WGS84.getMaximumMagnitude();
+
+        DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
+
+        values.intersect(field,
+                         new IntersectVisitor() {
+
+                           @Override
+                           public void visit(int docID) {
+                             result.add(docID);
+                           }
+
+                           @Override
+                           public void visit(int docID, byte[] packedValue) {
+                             assert packedValue.length == 12;
+                             double x = Geo3DPoint.decodeDimension(packedValue, 0);
+                             double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES);
+                             double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES);
+                             if (shape.isWithin(x, y, z)) {
+                               result.add(docID);
+                             }
+                           }
+
+                           @Override
+                           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
+                             // Because the dimensional format operates in quantized (64 bit -> 32 bit) space, and the cell bounds
+                             // here are inclusive, we need to extend the bounds to the largest un-quantized values that
+                             // could quantize into these bounds.  The encoding (Geo3DUtil.encodeValue) does
+                             // a Math.round from double to long, so e.g. 1.4 -> 1, and -1.4 -> -1:
+                             double xMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 0));
+                             double xMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 0));
+                             double yMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 1 * Integer.BYTES));
+                             double yMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 1 * Integer.BYTES));
+                             double zMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 2 * Integer.BYTES));
+                             double zMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 2 * Integer.BYTES));
+
+                             //System.out.println("  compare: x=" + cellXMin + "-" + cellXMax + " y=" + cellYMin + "-" + cellYMax + " z=" + cellZMin + "-" + cellZMax);
+                             assert xMin <= xMax;
+                             assert yMin <= yMax;
+                             assert zMin <= zMax;
+
+                             GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, xMin, xMax, yMin, yMax, zMin, zMax);
+
+                             switch(xyzSolid.getRelationship(shape)) {
+                             case GeoArea.CONTAINS:
+                               // Shape fully contains the cell
+                               //System.out.println("    inside");
+                               return Relation.CELL_INSIDE_QUERY;
+                             case GeoArea.OVERLAPS:
+                               // They do overlap but neither contains the other:
+                               //System.out.println("    crosses1");
+                               return Relation.CELL_CROSSES_QUERY;
+                             case GeoArea.WITHIN:
+                               // Cell fully contains the shape:
+                               //System.out.println("    crosses2");
+                               // return Relation.SHAPE_INSIDE_CELL;
+                               return Relation.CELL_CROSSES_QUERY;
+                             case GeoArea.DISJOINT:
+                               // They do not overlap at all
+                               //System.out.println("    outside");
+                               return Relation.CELL_OUTSIDE_QUERY;
+                             default:
+                               assert false;
+                               return Relation.CELL_CROSSES_QUERY;
+                             }
+                           }
+                         });
+
+        return new ConstantScoreScorer(this, score(), result.build().iterator());
+      }
+    };
+  }
+
+  public String getField() {
+    return field;
+  }
+
+  public GeoShape getShape() {
+    return shape;
+  }
+
+  @Override
+  @SuppressWarnings({"unchecked","rawtypes"})
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    if (!super.equals(o)) return false;
+
+    PointInGeo3DShapeQuery that = (PointInGeo3DShapeQuery) o;
+
+    return shape.equals(that.shape);
+  }
+
+  @Override
+  public final int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + shape.hashCode();
+    return result;
+  }
+
+  @Override
+  public String toString(String field) {
+    final StringBuilder sb = new StringBuilder();
+    sb.append(getClass().getSimpleName());
+    sb.append(':');
+    if (this.field.equals(field) == false) {
+      sb.append(" field=");
+      sb.append(this.field);
+      sb.append(':');
+    }
+    sb.append(" Shape: ");
+    sb.append(shape);
+    return sb.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
new file mode 100644
index 0000000..bb60be0
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Arc distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class ArcDistance implements DistanceStyle {
+  
+  /** An instance of the ArcDistance DistanceStyle. */
+  public final static ArcDistance INSTANCE = new ArcDistance();
+  
+  /** Constructor.
+   */
+  public 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);
+  }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java
new file mode 100644
index 0000000..5cd5acc
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * All Geo3D shapes can derive from this base class, which furnishes
+ * some common code
+ *
+ * @lucene.internal
+ */
+public abstract class BasePlanetObject {
+
+  /** This is the planet model embedded in all objects derived from this
+   * class. */
+  protected final PlanetModel planetModel;
+  
+  /** Constructor creating class instance given a planet model.
+   * @param planetModel is the planet model.
+   */
+  public BasePlanetObject(final PlanetModel planetModel) {
+    this.planetModel = planetModel;
+  }
+
+  /** Returns the {@link PlanetModel} provided when this shape was created. */
+  public PlanetModel getPlanetModel() {
+    return 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);
+  }
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java
new file mode 100644
index 0000000..16b52cc
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Base class of a family of 3D rectangles, bounded on six sides by X,Y,Z limits
+ *
+ * @lucene.internal
+ */
+public abstract class BaseXYZSolid extends BasePlanetObject implements XYZSolid {
+
+  /** Unit vector in x */
+  protected static final Vector xUnitVector = new Vector(1.0, 0.0, 0.0);
+  /** Unit vector in y */
+  protected static final Vector yUnitVector = new Vector(0.0, 1.0, 0.0);
+  /** Unit vector in z */
+  protected static final Vector zUnitVector = new Vector(0.0, 0.0, 1.0);
+  
+  /** Vertical plane normal to x unit vector passing through origin */
+  protected static final Plane xVerticalPlane = new Plane(0.0, 1.0, 0.0, 0.0);
+  /** Vertical plane normal to y unit vector passing through origin */
+  protected static final Plane yVerticalPlane = new Plane(1.0, 0.0, 0.0, 0.0);
+
+  /** Empty point vector */
+  protected static final GeoPoint[] EMPTY_POINTS = new GeoPoint[0];
+  
+  /**
+   * Base solid constructor.
+   *@param planetModel is the planet model.
+   */
+  public BaseXYZSolid(final PlanetModel planetModel) {
+    super(planetModel);
+  }
+  
+  /** Construct a single array from a number of individual arrays.
+   * @param pointArrays is the array of point arrays.
+   * @return the single unified array.
+   */
+  protected static GeoPoint[] glueTogether(final GeoPoint[]... pointArrays) {
+    int count = 0;
+    for (final GeoPoint[] pointArray : pointArrays) {
+      count += pointArray.length;
+    }
+    final GeoPoint[] rval = new GeoPoint[count];
+    count = 0;
+    for (final GeoPoint[] pointArray : pointArrays) {
+      for (final GeoPoint point : pointArray) {
+        rval[count++] = point;
+      }
+    }
+    return rval;
+  }
+  
+  @Override
+  public boolean isWithin(final Vector point) {
+    return isWithin(point.x, point.y, point.z);
+  }
+  
+  @Override
+  public abstract boolean isWithin(final double x, final double y, final double z);
+  
+  // Signals for relationship of edge points to shape
+  
+  /** All edgepoints inside shape */
+  protected final static int ALL_INSIDE = 0;
+  /** Some edgepoints inside shape */
+  protected final static int SOME_INSIDE = 1;
+  /** No edgepoints inside shape */
+  protected final static int NONE_INSIDE = 2;
+  /** No edgepoints at all (means a shape that is the whole world) */
+  protected final static int NO_EDGEPOINTS = 3;
+
+  /** Determine the relationship between this area and the provided
+   * shape's edgepoints.
+   *@param path is the shape.
+   *@return the relationship.
+   */
+  protected int isShapeInsideArea(final GeoShape path) {
+    final GeoPoint[] pathPoints = path.getEdgePoints();
+    if (pathPoints.length == 0)
+      return NO_EDGEPOINTS;
+    boolean foundOutside = false;
+    boolean foundInside = false;
+    for (final GeoPoint p : pathPoints) {
+      if (isWithin(p)) {
+        foundInside = true;
+      } else {
+        foundOutside = true;
+      }
+      if (foundInside && foundOutside) {
+        return SOME_INSIDE;
+      }
+    }
+    if (!foundInside && !foundOutside)
+      return NONE_INSIDE;
+    if (foundInside && !foundOutside)
+      return ALL_INSIDE;
+    if (foundOutside && !foundInside)
+      return NONE_INSIDE;
+    return SOME_INSIDE;
+  }
+
+  /** Determine the relationship between a shape and this area's
+   * edgepoints.
+   *@param path is the shape.
+   *@return the relationship.
+   */
+  protected int isAreaInsideShape(final GeoShape path) {
+    final GeoPoint[] edgePoints = getEdgePoints();
+    if (edgePoints.length == 0) {
+      return NO_EDGEPOINTS;
+    }
+    boolean foundOutside = false;
+    boolean foundInside = false;
+    for (final GeoPoint p : edgePoints) {
+      if (path.isWithin(p)) {
+        foundInside = true;
+      } else {
+        foundOutside = true;
+      }
+      if (foundInside && foundOutside) {
+        return SOME_INSIDE;
+      }
+    }
+    if (!foundInside && !foundOutside)
+      return NONE_INSIDE;
+    if (foundInside && !foundOutside)
+      return ALL_INSIDE;
+    if (foundOutside && !foundInside)
+      return NONE_INSIDE;
+    return SOME_INSIDE;
+  }
+
+  /** Get the edge points for this shape.
+   *@return the edge points.
+   */
+  protected abstract GeoPoint[] getEdgePoints();
+  
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof BaseXYZSolid))
+      return false;
+    BaseXYZSolid other = (BaseXYZSolid) o;
+    return super.equals(other);
+  }
+
+  @Override
+  public int hashCode() {
+    return super.hashCode();
+  }
+
+}
+  

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java
new file mode 100755
index 0000000..4f7c663
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * An interface for accumulating bounds information.
+ * The bounds object is initially empty.  Bounding points
+ * are then applied by supplying (x,y,z) tuples.  It is also
+ * possible to indicate the following edge cases:
+ * (1) No longitude bound possible
+ * (2) No upper latitude bound possible
+ * (3) No lower latitude bound possible
+ * When any of these have been applied, further application of
+ * points cannot override that decision.
+ *
+ * @lucene.experimental
+ */
+public interface Bounds {
+
+  /** Add a general plane to the bounds description.
+   *@param planetModel is the planet model.
+   *@param plane is the plane.
+   *@param bounds are the membership bounds for points along the arc.
+   */
+  public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds);
+  
+  /** Add a horizontal plane to the bounds description.
+   * This method should EITHER use the supplied latitude, OR use the supplied
+   * plane, depending on what is most efficient.
+   *@param planetModel is the planet model.
+   *@param latitude is the latitude.
+   *@param horizontalPlane is the plane.
+   *@param bounds are the constraints on the plane.
+   *@return updated Bounds object.
+   */
+  public Bounds addHorizontalPlane(final PlanetModel planetModel,
+    final double latitude,
+    final Plane horizontalPlane,
+    final Membership... bounds);
+    
+  /** Add a vertical plane to the bounds description.
+   * This method should EITHER use the supplied longitude, OR use the supplied
+   * plane, depending on what is most efficient.
+   *@param planetModel is the planet model.
+   *@param longitude is the longitude.
+   *@param verticalPlane is the plane.
+   *@param bounds are the constraints on the plane.
+   *@return updated Bounds object.
+   */
+  public Bounds addVerticalPlane(final PlanetModel planetModel,
+    final double longitude,
+    final Plane verticalPlane,
+    final Membership... bounds);
+
+  /** Add a single point.
+   *@param point is the point.
+   *@return the updated Bounds object.
+   */
+  public Bounds addPoint(final GeoPoint point);
+
+  /** Add an X value.
+   *@param point is the point to take the x value from.
+   *@return the updated object.
+   */
+  public Bounds addXValue(final GeoPoint point);
+
+  /** Add a Y value.
+   *@param point is the point to take the y value from.
+   *@return the updated object.
+   */
+  public Bounds addYValue(final GeoPoint point);
+
+  /** Add a Z value.
+   *@param point is the point to take the z value from.
+   *@return the updated object.
+   */
+  public Bounds addZValue(final GeoPoint point);
+  
+  /** Signal that the shape exceeds Math.PI in longitude.
+   *@return the updated Bounds object.
+   */
+  public Bounds isWide();
+  
+  /** Signal that there is no longitude bound.
+   *@return the updated Bounds object.
+   */
+  public Bounds noLongitudeBound();
+
+  /** Signal that there is no top latitude bound.
+   *@return the updated Bounds object.
+   */
+  public Bounds noTopLatitudeBound();
+
+  /** Signal that there is no bottom latitude bound.
+   *@return the updated Bounds object.
+   */
+  public Bounds noBottomLatitudeBound();
+  
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
new file mode 100644
index 0000000..8c8658d
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Distance computation styles, supporting various ways of computing
+ * distance to shapes.
+ *
+ * @lucene.experimental
+ */
+public interface DistanceStyle {
+
+  // convenient access to built-in styles:
+
+  /** Arc distance calculator */
+  public static final ArcDistance ARC = ArcDistance.INSTANCE;
+  /** Linear distance calculator */
+  public static final LinearDistance LINEAR = LinearDistance.INSTANCE;
+  /** Linear distance squared calculator */
+  public static final LinearSquaredDistance LINEAR_SQUARED = LinearSquaredDistance.INSTANCE;
+  /** Normal distance calculator */
+  public static final NormalDistance NORMAL = NormalDistance.INSTANCE;
+  /** Normal distance squared calculator */
+  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);
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java
new file mode 100755
index 0000000..5a6db0d
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * A GeoArea represents a standard 2-D breakdown of a part of sphere.  It can
+ * be bounded in latitude, or bounded in both latitude and longitude, or not
+ * bounded at all.  The purpose of the interface is to describe bounding shapes used for
+ * computation of geo hashes.
+ *
+ * @lucene.experimental
+ */
+public interface GeoArea extends Membership {
+  // Since we don't know what each GeoArea's constraints are,
+  // we put the onus on the GeoArea implementation to do the right thing.
+  // This will, of course, rely heavily on methods provided by
+  // the underlying GeoShape class.
+
+  // Relationship values for "getRelationship()"
+  
+  /** The referenced shape CONTAINS this area */
+  public static final int CONTAINS = 0;
+  /** The referenced shape IS WITHIN this area */
+  public static final int WITHIN = 1;
+  /** The referenced shape OVERLAPS this area */
+  public static final int OVERLAPS = 2;
+  /** The referenced shape has no relation to this area */
+  public static final int DISJOINT = 3;
+
+  /**
+   * 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.
+   *
+   * It is permissible to return OVERLAPS instead of WITHIN if the shape
+   * intersects with the area at even a single point.  So, a circle inscribed in
+   * a rectangle could return either OVERLAPS or WITHIN, depending on
+   * implementation.  It is not permissible to return CONTAINS or DISJOINT
+   * in this circumstance, however.
+   *
+   * Similarly, it is permissible to return OVERLAPS instead of CONTAINS
+   * under conditions where the shape consists of multiple independent overlapping
+   * subshapes, and the area overlaps one of the subshapes.  It is not permissible
+   * to return WITHIN or DISJOINT in this circumstance, however.
+   *
+   * @param shape is the shape to consider.
+   * @return the relationship, from the perspective of the shape.
+   */
+  public int getRelationship(GeoShape shape);
+}
+

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java
new file mode 100755
index 0000000..0c3caa9
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Factory for {@link GeoArea}.
+ *
+ * @lucene.experimental
+ */
+public class GeoAreaFactory {
+  private GeoAreaFactory() {
+  }
+
+  /**
+   * Create a GeoArea of the right kind given the specified bounds.
+   * @param planetModel is the planet model
+   * @param topLat    is the top latitude
+   * @param bottomLat is the bottom latitude
+   * @param leftLon   is the left longitude
+   * @param rightLon  is the right longitude
+   * @return a GeoArea corresponding to what was specified.
+   */
+  public static GeoArea makeGeoArea(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, final double rightLon) {
+    return GeoBBoxFactory.makeGeoBBox(planetModel, topLat, bottomLat, leftLon, rightLon);
+  }
+
+  /**
+   * Create a GeoArea of the right kind given (x,y,z) bounds.
+   * @param planetModel is the planet model
+   * @param minX is the min X boundary
+   * @param maxX is the max X boundary
+   * @param minY is the min Y boundary
+   * @param maxY is the max Y boundary
+   * @param minZ is the min Z boundary
+   * @param maxZ is the max Z boundary
+   */
+  public static GeoArea makeGeoArea(final PlanetModel planetModel, final double minX, final double maxX, final double minY, final double maxY, final double minZ, final double maxZ) {
+    return XYZSolidFactory.makeXYZSolid(planetModel, minX, maxX, minY, maxY, minZ, maxZ);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
new file mode 100755
index 0000000..0ae2425
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * All bounding box shapes have this interface in common.
+ * This describes methods that bounding boxes have above and beyond
+ * GeoMembershipShape's.
+ *
+ * @lucene.experimental
+ */
+public interface GeoBBox extends GeoMembershipShape, GeoSizeable, GeoArea {
+
+  /**
+   * Expand box by specified angle.
+   *
+   * @param angle is the angle amount to expand the GeoBBox by.
+   * @return a new GeoBBox.
+   */
+  public GeoBBox expand(double angle);
+
+}