Index: contrib/spatial/src/java/org/apache/lucene/spatial/tier/Shape.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/tier/Shape.java	(revision 833122)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/tier/Shape.java	Fri Dec 18 15:32:49 CET 2009
@@ -22,32 +22,87 @@
 import java.util.List;
 
 /**
- * <p><font color="red"><b>NOTE:</b> This API is still in
- * flux and might change in incompatible ways in the next
- * release.</font>
+ * Shape contains information related to a shape created on a specific cartesian tier.  Because the tiers consist
+ * of a set of boxes, shapes are defined simply by what boxes the shape overlaps, and what tier level the boxes are at.
+ * Such a simply approximation will result in points being included that are not in the actual shape, but this fine grained
+ * filtering is left out of the cartesian shape filtering process.
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
  */
-public class Shape implements Serializable{
+public class Shape implements Serializable {
 
-  private List<Double> area = new ArrayList<Double>();
-  private String tierId;
+  private final List<Double> boxIds = new ArrayList<Double>();
+  private final int tierId;
-  
+
-  public Shape (String tierId){
+  /**
+   * Creates a new Shape that represents a shape at the given tier level
+   *
+   * @param tierId ID of the tier level that the shape is in
+   */
+  public Shape(int tierId) {
     this.tierId = tierId;
   }
 
+  /**
+   * Adds the given box id to the list of boxes this shape overlaps
+   *
+   * @param boxId ID of a box that this shape overlaps
+   */
-  public void addBox(double  boxId){
+  public void addBox(double boxId) {
-    area.add(boxId);
+    boxIds.add(boxId);
   }
-  
+
+  // ================================================= Getters / Setters =============================================
+
+  /**
+   * Returns the tier level ID that this shape is in
+   *
+   * @return Tier level id that this shape is in
+   */
+  public int getTierID() {
+    return tierId;
+  }
+
+  /**
+   * Returns the list of ids of the boxes that this shape overlaps
+   *
+   * @return List of ids of the boxes the shape overlaps.  Always non-null.
+   */
+  public List<Double> getBoxIds() {
+    return boxIds;
+  }
+
+  // ================================================= Deprecated Methods =============================================
+
+  /**
+   * @deprecated Deprecated since tierId is now an integer.  This will be removed
+   */
+  @Deprecated
+  public Shape(String tierId) {
+    this.tierId = Integer.parseInt(tierId);
+  }
+
+  /**
+   * @deprecated Deprecated since the method name is non-intuitive
+   */
+  @Deprecated
-  public List<Double> getArea(){
+  public List<Double> getArea() {
-    return area;
+    return boxIds;
   }
-  
+
+  /**
+   * @deprecated Deprecated since tierId is now an integer.  This will be removed
+   */
+  @Deprecated
-  public String getTierId(){
+  public String getTierId() {
-    return tierId;
+    return String.valueOf(tierId);
   }
-  
+
+  /**
+   * @deprecated Deprecated since this method is not used.
+   */
+  @Deprecated
-  public boolean isInside(double boxId){
+  public boolean isInside(double boxId) {
-    return area.contains(boxId);
+    return boxIds.contains(boxId);
   }
 }
Index: contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesianShapeFilter.java
===================================================================
--- contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesianShapeFilter.java	(revision 833122)
+++ contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesianShapeFilter.java	Sun Dec 20 20:34:20 CET 2009
@@ -22,22 +22,24 @@
 import java.io.ObjectOutputStream;
 
 import junit.framework.TestCase;
+
 /**
- * 
- * Test for {@link CartesianShapeFilter}
- *
+ * Tests for {@link CartesianShapeFilter}
  */
 public class TestCartesianShapeFilter extends TestCase {
 
+  /**
+   * Pass condition: An instance of CartesianShapeFilter should be able to be serialized
+   *
+   * @throws IOException Can be thrown while trying to serialize an instance of CartesianShapeFilter 
+   */
   public void testSerializable() throws IOException {
-    CartesianShapeFilter filter = new CartesianShapeFilter(new Shape("1"),
-        "test");
+    CartesianShapeFilter filter = new CartesianShapeFilter(new Shape(1), "test");
     try {
-      ByteArrayOutputStream bos = new ByteArrayOutputStream();
-      ObjectOutputStream oos = new ObjectOutputStream(bos);
-      oos.writeObject(filter);
+      ObjectOutputStream outputStream = new ObjectOutputStream(new ByteArrayOutputStream());
+      outputStream.writeObject(filter);
     } catch (NotSerializableException e) {
-      fail("Filter should be serializable but raised a NotSerializableException ["+e.getMessage()+"]");
+      fail("Filter should be serializable but raised a NotSerializableException [" + e.getMessage() + "]");
     }
   }
 
Index: contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java	(revision 833122)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java	Sun Dec 20 20:23:34 CET 2009
@@ -21,6 +21,7 @@
 import java.math.RoundingMode;
 
 import org.apache.lucene.search.Filter;
+import org.apache.lucene.spatial.geometry.LatLngRectangle;
 import org.apache.lucene.spatial.tier.projections.CartesianTierPlotter;
 import org.apache.lucene.spatial.tier.projections.IProjector;
 import org.apache.lucene.spatial.tier.projections.SinusoidalProjector;
@@ -28,132 +29,126 @@
 import org.apache.lucene.spatial.geometry.FloatLatLng;
 import org.apache.lucene.spatial.geometry.shape.LLRect;
 
-
 /**
- * <p><font color="red"><b>NOTE:</b> This API is still in
- * flux and might change in incompatible ways in the next
- * release.</font>
+ * Builds instances of {@link org.apache.lucene.spatial.tier.CartesianShapeFilter} for a given latitude, longitude and distance
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
  */
 public class CartesianPolyFilterBuilder {
 
-  // Finer granularity than 1 mile isn't accurate with
-  // standard java math.  Also, there's already a 2nd
-  // precise filter, if needed, in DistanceQueryBuilder,
-  // that will make the filtering exact.
+  // Finer granularity than 1 mile isn't accurate with standard java math.
   public static final double MILES_FLOOR = 1.0;
+  private static IProjector PROJECTOR = new SinusoidalProjector();
 
-  private IProjector projector = new SinusoidalProjector();
   private final String tierPrefix;
-  
+
+  /**
+   * Creates a new CartesianPolyFilterBuilder that will construct instances of CartesianShapeFilter using the given prefix
+   * of the cartesian tier fields
+   *
+   * @param tierPrefix Prefix of the cartesian tier fields in documents.  This will be suffixed by the cartesian tier
+   *                   level id to determine which fields the filter should access in documents 
+   */
-  public CartesianPolyFilterBuilder( String tierPrefix ) {
+  public CartesianPolyFilterBuilder(String tierPrefix) {
     this.tierPrefix = tierPrefix;
   }
-  
+
-  public Shape getBoxShape(double latitude, double longitude, double miles)
-  {  
+  /**
+   * Creates a new CartesianShapeFilter that will filter out documents outside of the given miles of the point defined by
+   * the given latitude and longitude
+   *
+   * @param latitude Latitude of the point at the centre of the search area
+   * @param longitude Longitude of the point at the centre of the search area
+   * @param miles Radius in miles around the point that documents must be in, in order not to be filtered out
+   * @return CartesianShapeFilter that will filter out documents of the radius of the point
+   */
+  public Filter getBoundingArea(double latitude, double longitude, double miles) {
+    Shape shape = getBoxShape(latitude, longitude, miles);
+    return new CartesianShapeFilter(shape, tierPrefix + shape.getTierID());
+  }
+
+  // ================================================= Helper Methods ================================================
+
+  /**
+   * Creates the CartesianShape that covers a circle with the given latitude and longitude at its centre, and the given
+   * radius in miles
+   *
+   * @param latitude Latitude of the centre of the circle
+   * @param longitude Longitude of the centre of the circle
+   * @param miles Radius of the circle
+   * @return CartesianShape that covers the circle defined by the lat/long and radius
+   */
+  private Shape getBoxShape(double latitude, double longitude, double miles) {
     if (miles < MILES_FLOOR) {
       miles = MILES_FLOOR;
     }
-    LLRect box1 = LLRect.createBox( new FloatLatLng( latitude, longitude ), miles, miles );
-    LatLng ll = box1.getLowerLeft();
-    LatLng ur = box1.getUpperRight();
 
-    double latY = ur.getLat();
-    double latX = ll.getLat();
-    double longY = ur.getLng();
-    double longX = ll.getLng();
-    double longX2 = 0.0;
+    LatLngRectangle latLngRectangle = LatLngRectangle.createBox(new LatLng(latitude, longitude), miles);
+    LatLng lowerLeft = latLngRectangle.getLowerLeft();
+    LatLng upperRight = latLngRectangle.getUpperRight();
 
-    if (ur.getLng() < 0.0 && ll.getLng() > 0.0) {
-	longX2 = ll.getLng();
- 	longX = -180.0;	
+    double latY = upperRight.getLat();
+    double latX = lowerLeft.getLat();
+
+    double lngY = upperRight.getLng();
+    double lngX = lowerLeft.getLng();
+    double lngX2 = 0.0;
+
+    if (lngY < 0.0 && lngX > 0.0) {
+      lngX2 = lngX;
+      lngX = -180;
     }
-    if (ur.getLng() > 0.0 && ll.getLng() < 0.0) {
-	longX2 = ll.getLng();
- 	longX = 0.0;	
+    if (lngY > 0.0 && lngX < 0.0) {
+      lngX2 = lngX;
+      lngX = 0.0;
     }
-    
+
-    //System.err.println("getBoxShape:"+latY+"," + longY);
-    //System.err.println("getBoxShape:"+latX+"," + longX);
-    CartesianTierPlotter ctp = new CartesianTierPlotter(2, projector,tierPrefix);
-    int bestFit = ctp.bestFit(miles);
+    int bestFit = CartesianTierPlotter.bestFit(miles);
-    
+
-    ctp = new CartesianTierPlotter(bestFit, projector,tierPrefix);
-    Shape shape = new Shape(ctp.getTierFieldName());
+    CartesianTierPlotter tierPlotter = new CartesianTierPlotter(bestFit, PROJECTOR);
+    Shape shape = new Shape(bestFit);
+    addBoxes(shape, tierPlotter, latX, lngX, latY, lngY);
-    
+
-    // generate shape
-    // iterate from startX->endX
-    //     iterate from startY -> endY
-    //      shape.add(currentLat.currentLong);
-
-    shape = getShapeLoop(shape,ctp,latX,longX,latY,longY);
-    if (longX2 != 0.0) {
-	if (longX2 != 0.0) {
-		if (longX == 0.0) {
-			longX = longX2;
-			longY = 0.0;
-        		shape = getShapeLoop(shape,ctp,latX,longX,latY,longY);
+    if (lngX2 != 0.0) {
+      if (lngX == 0.0) {
+        lngX = lngX2;
+        lngY = 0.0;
+        addBoxes(shape, tierPlotter, latX, lngX, latY, lngY);
-		} else {
+      } else {
-			longX = longX2;
-			longY = -180.0;
-        		shape = getShapeLoop(shape,ctp,latY,longY,latX,longX);
+        lngX = lngX2;
+        lngY = -180.0;
+        addBoxes(shape, tierPlotter, latY, lngY, latX, lngX);
-		}
-	}
+      }
+    }
-        //System.err.println("getBoxShape2:"+latY+"," + longY);
-        //System.err.println("getBoxShape2:"+latX+"," + longX);
-    }
- 
-    return shape; 
-  } 
+
+    return shape;
+  }
   
-  public Shape getShapeLoop(Shape shape, CartesianTierPlotter ctp, double latX, double longX, double latY, double longY)
-  {  
+  private void addBoxes(Shape shape, CartesianTierPlotter tierPlotter, double latX, double lngX, double latY, double lngY) {
+    double beginAt = tierPlotter.getTierBoxId(latX, lngX);
+    double endAt = tierPlotter.getTierBoxId(latY, lngY);
- 
+
-    //System.err.println("getShapeLoop:"+latY+"," + longY);
-    //System.err.println("getShapeLoop:"+latX+"," + longX);
-    double beginAt = ctp.getTierBoxId(latX, longX);
-    double endAt = ctp.getTierBoxId(latY, longY);
+    double tierVert = tierPlotter.getTierVerticalPosDivider();
-    
+
-    double tierVert = ctp.getTierVerticalPosDivider();
-    //System.err.println(" | "+ beginAt+" | "+ endAt);
-    
-    double startX = beginAt - (beginAt %1);
+    double startX = beginAt - (beginAt % 1);
-    double startY = beginAt - startX ; //should give a whole number
-    
-    double endX = endAt - (endAt %1);
+    double endX = endAt - (endAt % 1);
-    double endY = endAt -endX; //should give a whole number
-    
+
-    int scale = (int)Math.log10(tierVert);
+    int scale = (int) Math.log10(tierVert);
-    endY = new BigDecimal(endY).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
-    startY = new BigDecimal(startY).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
-    double xInc = 1.0d / tierVert;
-    xInc = new BigDecimal(xInc).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
+    double startY = new BigDecimal(beginAt - startX).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
+    double endY = new BigDecimal(endAt - endX).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
-    
+
-    //System.err.println("go from startX:"+startX+" to:" + endX);
-    for (; startX <= endX; startX++){
+    double xInc = new BigDecimal(1.0D / tierVert).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
-      
+
+    for (; startX <= endX; startX++) {
       double itY = startY;
-      //System.err.println("go from startY:"+startY+" to:" + endY);
-      while (itY <= endY){
+      while (itY <= endY) {
-        //create a boxId
-        // startX.startY
-        double boxId = startX + itY ;
+        double boxId = startX + itY;
         shape.addBox(boxId);
-        //System.err.println("----"+startX+" and "+itY);
-        //System.err.println("----"+boxId);
-        itY += xInc;
-        
-        // java keeps 0.0001 as 1.0E-1
-        // which ends up as 0.00011111
-        itY = new BigDecimal(itY).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
+        // java keeps 0.0001 as 1.0E-1 which ends up as 0.00011111
+        itY = new BigDecimal(itY + xInc).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
       }
     }
-    return shape;
   }
   
-  public Filter getBoundingArea(double latitude, double longitude, double miles) 
-  {
-    Shape shape = getBoxShape(latitude, longitude, miles);
-    return new CartesianShapeFilter(shape, shape.getTierId());
+
-  }
+}
-}
Index: contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java	(revision 834847)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java	Sun Dec 20 20:04:18 CET 2009
@@ -28,34 +28,43 @@
 import org.apache.lucene.util.OpenBitSet;
 
 /**
- * <p><font color="red"><b>NOTE:</b> This API is still in
- * flux and might change in incompatible ways in the next
- * release.</font>
+ * CartesianShapeFilter is a proper Lucene filter that filters out documents that are not within the boxes that define
+ * a certain CartesianShape overlaps.  For example, if a shape overlaps boxes 1, 3 and 6, then a document that has been
+ * plotted to be within box 5 will be filtered out.
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
  */
 public class CartesianShapeFilter extends Filter {
  
   private final Shape shape;
   private final String fieldName;
-  
+
-  CartesianShapeFilter(final Shape shape, final String fieldName){
+  /**
+   * Creates a new CartesianShapeFilter that will filter out documents that are not within the boxes defined in the
+   * given Shape.
+   *
+   * @param shape Shape containing boxes that documents must be within, in order not to be filtered out
+   * @param fieldName Name of the field in the documents that will be checked for what boxes the document is in
+   */
+  public CartesianShapeFilter(Shape shape, String fieldName) {
     this.shape = shape;
     this.fieldName = fieldName;
   }
-  
+
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public DocIdSet getDocIdSet(final IndexReader reader) throws IOException {
-    final OpenBitSet bits = new OpenBitSet(reader.maxDoc());
-    final TermDocs termDocs = reader.termDocs();
-    final List<Double> area = shape.getArea();
-    int sz = area.size();
+  public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+    OpenBitSet bits = new OpenBitSet(reader.maxDoc());
-    
+
-    final Term term = new Term(fieldName);
-    // iterate through each boxid
-    for (int i =0; i< sz; i++) {
-      double boxId = area.get(i).doubleValue();
+    Term term = new Term(fieldName);
+    TermDocs termDocs = reader.termDocs();
+    List<Double> boxIds = shape.getBoxIds();
+    
+    for (double boxId : boxIds) {
       termDocs.seek(term.createTerm(NumericUtils.doubleToPrefixCoded(boxId)));
-      // iterate through all documents
-      // which have this boxId
+      // iterate through all documents which have this boxId
       while (termDocs.next()) {
         bits.fastSet(termDocs.doc());
       }
Index: contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/IProjector.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/IProjector.java	(revision 810951)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/IProjector.java	Fri Dec 18 14:44:14 CET 2009
@@ -23,6 +23,18 @@
  * release.</font>
  */
 public interface IProjector {
-  public String coordsAsString(double latitude, double longitude);
+
+  /**
+   * Projects the given latitude and longitude to an x/y coordinate pair
+   *
+   * @param latitude Latitude to project
+   * @param longitude Longitude to project
+   * @return x/y coordinate pair created by projecting the latitude and longitude
+   */
   public double[] coords(double latitude, double longitude);
+
+  /**
+   * @deprecated This method is unused and will be removed
+   */
+  public String coordsAsString(double latitude, double longitude);
 }
\ No newline at end of file
Index: contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/SinusoidalProjector.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/SinusoidalProjector.java	(revision 811070)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/SinusoidalProjector.java	Fri Dec 18 14:46:31 CET 2009
@@ -19,26 +19,27 @@
 
 /**
  * Based on Sinusoidal Projections
- * Project a latitude / longitude on a 2D cartesian map
+ * Project a latitude / longitude on a 2D cartisian map
  *
- * <p><font color="red"><b>NOTE:</b> This API is still in
- * flux and might change in incompatible ways in the next
- * release.</font>
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
  */
 public class SinusoidalProjector implements IProjector {
 
-  
-  public String coordsAsString(double latitude, double longitude) {
-    return null;
-  }
-  
+  /**
+   * {@inheritDoc}
+   */
   public double[] coords(double latitude, double longitude) {
     double rlat = Math.toRadians(latitude);
     double rlong = Math.toRadians(longitude);
     double nlat = rlong * Math.cos(rlat);
-    double r[] = {nlat, rlong};
-    return r;
+    return new double[]{nlat, rlong};
+  }
-    
+
+  /**
+   * {@inheritDoc}
+   */
+  public String coordsAsString(double latitude, double longitude) {
+    return null;
   }
-  
+
 }
Index: contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java	(revision 821186)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java	Sun Dec 20 20:46:10 CET 2009
@@ -18,147 +18,174 @@
 package org.apache.lucene.spatial.tier.projections;
 
 /**
- * <p><font color="red"><b>NOTE:</b> This API is still in
- * flux and might change in incompatible ways in the next
- * release.</font>
+ * CartesianTierPlotter provides functionality for plotting a point defined by a longitude and latitude, in a box thats
+ * part of a cartesian tier.
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
  */
 public class CartesianTierPlotter {
+
+  /**
+   * @deprecated This class will not provide a default field prefix in the future as it is not its responsibility
+   */
+  @Deprecated
   public static final String DEFALT_FIELD_PREFIX = "_tier_";
-  
+
-  final int tierLevel;
-  int tierLength;
-  int tierBoxes;
-  int tierVerticalPosDivider;
-  final IProjector projector;
-  final String fieldPrefix;
-  Double idd = Double.valueOf(180);
+  private static final Double idd = 180D;
+  private static final double LOG_2 = Math.log(2);
   
-  public CartesianTierPlotter (int tierLevel, IProjector projector, String fieldPrefix) {
+  private final int tierLevel;
+  private final int tierLength;
+  private final int tierVerticalPosDivider;
+  private final IProjector projector;
-  
+
+  private String fieldPrefix;
+
+  /**
+   * Creates a new CartesianTierPlotter that will plot points at the given tier level using the given Projector
+   *
+   * @param tierLevel Tier Level the plotter should plot its points at
+   * @param projector Projector that the plotter should use to project points onto a tier
+   */
+  public CartesianTierPlotter(int tierLevel, IProjector projector) {
     this.tierLevel  = tierLevel;
     this.projector = projector;
-    this.fieldPrefix = fieldPrefix;
     
-    setTierLength();
-    setTierBoxes();
-    setTierVerticalPosDivider();
-  }
-  
-  private void setTierLength (){
-    this.tierLength = (int) Math.pow(2 , this.tierLevel);
+    this.tierLength = (int) Math.pow(2, this.tierLevel);
+    this.tierVerticalPosDivider = calculateTierVerticalPosDivider();
   }
-  
+
-  private void setTierBoxes () {
-    this.tierBoxes = (int)Math.pow(this.tierLength, 2);
+  /**
+   * Find the tier with the best fit for a bounding box. Best fit is defined as the ceiling of log2 (circumference of
+   * earth / distance) distance is defined as the smallest box fitting the corner between a radius and a bounding box.
+   * <p/>
+   * Distances less than a mile return 15, finer granularity is in accurate
+   *
+   * @param miles Distance in miles of the bounding box that the tier should be a best fit for
+   * @return Tier level with the best fit for the bounding box
+   */
+  public static int bestFit(double miles) {
+    //28,892 a rough circumference of the earth
+    // TODO - Change to DistanceUnits
+    int circ = 28892;
+
+    double r = miles / 2.0;
+
+    double corner = r - Math.sqrt(Math.pow(r, 2) / 2.0d);
+    double times = circ / corner;
+    int bestFit = (int) Math.ceil(log2(times)) + 1;
+
+    if (bestFit > 15) {
+      // 15 is the granularity of about 1 mile
+      // finer granularity isn't accurate with standard java math
+      return 15;
-  }
+    }
+    return bestFit;
+  }
   
   /**
-   * Get nearest max power of 10 greater than
-   * the tierlen
-   * e.g
-   * tierId of 13 has tierLen 8192
-   * nearest max power of 10 greater than tierLen 
-   * would be 10,000
+   * TierBoxId is latitude box id + longitude box id where latitude box id, and longitude box id are transposded in to
+   * position coordinates.
+   *
+   * @param latitude Latitude of the point whose box id is to be returned
+   * @param longitude Longitude of the point whose box id is to be returned
+   * @return Id of the box where the point with the latitude and longitude, is located
    */
+  public double getTierBoxId(double latitude, double longitude) {
+    double[] coords = projector.coords(latitude, longitude);
+    return getBoxId(coords[0]) + (getBoxId(coords[1]) / tierVerticalPosDivider);
+  }
-  
+
-  private void setTierVerticalPosDivider() {
+  // ================================================= Helper Methods ================================================
-    
+
-    // ceiling of log base 10 of tierLen
+  /**
+   * Calculates the nearest max power of 10 greater than the tierlen
+   * <p/>
+   * e.g tierId of 13 has tierLen 8192 nearest max power of 10 greater than tierLen would be 10,000
+   *
+   * @return Nearest max power of 10 greater than the tier len
+   */
+  private int calculateTierVerticalPosDivider() {
+    return (int) Math.pow(10, (int) Math.ceil(Math.log10(this.tierLength)));
+  }
-    
+
-    tierVerticalPosDivider = Double.valueOf(Math.ceil(
-          Math.log10(Integer.valueOf(this.tierLength).doubleValue()))).intValue();
+  /**
+   * Returns the box id of the given coordinate
+   *
+   * @param coord Coordinate whose box id is to be computed
+   * @return Box id of the coordinate
+   */
+  private double getBoxId(double coord) {
+    return Math.floor(coord / (idd / this.tierLength));
+  }
-    
+
-    // 
-    tierVerticalPosDivider = (int)Math.pow(10, tierVerticalPosDivider );
-    
+  /**
+   * Computes log to base 2 of the given value
+   *
+   * @param value Value to compute the log of
+   * @return Log_2 of the value
+   */
+  public static double log2(double value) {
+    return Math.log(value) / LOG_2;
   }
-  
+
+  // ================================================= Getters / Setters =============================================
+
+  /**
+   * Returns the nearest max power of 10 greater than the tier len
+   *
+   * @return Nearest max power of 10 greater than the tier len
+   */
-  public double getTierVerticalPosDivider(){
+  public double getTierVerticalPosDivider() {
     return tierVerticalPosDivider;
   }
-  
+
   /**
-   * TierBoxId is latitude box id + longitude box id
-   * where latitude box id, and longitude box id are transposed in to position
-   * coordinates.
+   * Returns the ID of the tier level plotting is occuring at
-   * 
+   *
-   * @param latitude
-   * @param longitude
+   * @return ID of the tier level plotting is occuring at
    */
-  public double getTierBoxId (double latitude, double longitude) {
-    
-    double[] coords = projector.coords(latitude, longitude);
-    
-    double id = getBoxId(coords[0]) + (getBoxId(coords[1]) / tierVerticalPosDivider);
-    return id ;
+  public int getTierLevelId() {
+    return this.tierLevel;
   }
-  
+
+  // ================================================= Deprecated Methods =============================================
-  
+
-  private double getBoxId (double coord){
+  /**
+   * @deprecated This constructor is deprecated since this class should not handle the field prefix. This will be removed.
+   */
+  @Deprecated
+  public CartesianTierPlotter (int tierLevel, IProjector projector, String fieldPrefix) {
+    this.tierLevel  = tierLevel;
+    this.projector = projector;
+    this.fieldPrefix = fieldPrefix;
-    
+
-    
-    return Math.floor(coord / (idd / this.tierLength));
+    this.tierLength = (int) Math.pow(2, this.tierLevel);
+    this.tierVerticalPosDivider = calculateTierVerticalPosDivider();
   }
-  
+
-  @SuppressWarnings("unused")
-  private double getBoxId (double coord, int tierLen){
-    return Math.floor(coord / (idd / tierLen) );
-  }
   /**
    * get the string name representing current tier
    * _localTier&lt;tiedId&gt;
+   *
+   * @deprecated This class will no longer handle the tier field name so this method will be removed
    */
+  @Deprecated
   public String getTierFieldName (){
-    
+
     return fieldPrefix + this.tierLevel;
   }
-  
+
   /**
    * get the string name representing tierId
    * _localTier&lt;tierId&gt;
    * @param tierId
+   *
+   * @deprecated This class will no longer handle the tier field name so this method will be removed
    */
+  @Deprecated
   public String getTierFieldName (int tierId){
-    
+
     return fieldPrefix + tierId;
   }
-  
-  /**
-   * Find the tier with the best fit for a bounding box
-   * Best fit is defined as the ceiling of
-   *  log2 (circumference of earth / distance) 
-   *  distance is defined as the smallest box fitting
-   *  the corner between a radius and a bounding box.
-   *  
-   *  Distances less than a mile return 15, finer granularity is
-   *  in accurate
-   */
-  public int bestFit(double miles){
-    
-    //28,892 a rough circumference of the earth
-    int circ = 28892;
-    
-    double r = miles / 2.0;
-    
-    double corner = r - Math.sqrt(Math.pow(r, 2) / 2.0d);
-    double times = circ / corner;
-    int bestFit =  (int)Math.ceil(log2(times)) + 1;
-    
-    if (bestFit > 15) {
-      // 15 is the granularity of about 1 mile
-      // finer granularity isn't accurate with standard java math
-      return 15;
-    }
+}
-    return bestFit;
-  }
-  
-  /**
-   * a log to the base 2 formula
-   * <code>Math.log(value) / Math.log(2)</code>
-   * @param value
-   */
-  public double log2(double value) {
-    
-    return Math.log(value) / Math.log(2);
-  }
-}
