sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mattm...@apache.org
Subject svn commit: r929771 - in /incubator/sis/trunk: ./ src/main/java/org/apache/sis/core/ src/main/java/org/apache/sis/util/
Date Thu, 01 Apr 2010 01:40:25 GMT
Author: mattmann
Date: Thu Apr  1 01:40:24 2010
New Revision: 929771

URL: http://svn.apache.org/viewvc?rev=929771&view=rev
Log:
- wrap up SIS-1

Added:
    incubator/sis/trunk/src/main/java/org/apache/sis/core/
    incubator/sis/trunk/src/main/java/org/apache/sis/core/CartesianPoint.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/DistanceUnits.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/Ellipse.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/FixedLatLng.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/FloatLatLng.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/Geometry2D.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/IntersectCase.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/LLRect.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/LatLng.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/LineSegment.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/Point2D.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/PointsD.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/Rectangle.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/Shape.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/TierBoundaries.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/core/Vector2D.java   (with props)
    incubator/sis/trunk/src/main/java/org/apache/sis/util/
    incubator/sis/trunk/src/main/java/org/apache/sis/util/GeoHashUtils.java
Modified:
    incubator/sis/trunk/CHANGES.txt

Modified: incubator/sis/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/CHANGES.txt?rev=929771&r1=929770&r2=929771&view=diff
==============================================================================
--- incubator/sis/trunk/CHANGES.txt (original)
+++ incubator/sis/trunk/CHANGES.txt Thu Apr  1 01:40:24 2010
@@ -2,3 +2,4 @@ Apache SIS Change Log
 ======================
 Release 0.1-incubating (Current Development)
 
+1. SIS-1 Import LocalLucene (mattmann)

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/CartesianPoint.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/CartesianPoint.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/CartesianPoint.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/CartesianPoint.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,80 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Represents lat/lngs as fixed point numbers translated so that all world
+ * coordinates are in the first quadrant. The same fixed point scale as is used
+ * for FixedLatLng is employed.
+ * 
+ */
+public class CartesianPoint {
+  private int x;
+  private int y;
+
+  public CartesianPoint(int x, int y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  public int getX() {
+    return x;
+  }
+
+  public int getY() {
+    return y;
+  }
+
+  @Override
+  public String toString() {
+    return "Point(" + x + "," + y + ")";
+  }
+
+  /**
+   * Return a new point translated in the x and y dimensions
+   */
+  public CartesianPoint translate(int deltaX, int deltaY) {
+    return new CartesianPoint(this.x + deltaX, this.y + deltaY);
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + x;
+    result = prime * result + y;
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CartesianPoint other = (CartesianPoint) obj;
+    if (x != other.x)
+      return false;
+    if (y != other.y)
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/CartesianPoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/DistanceUnits.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/DistanceUnits.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/DistanceUnits.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/DistanceUnits.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,120 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Enum representing difference distance units, currently only kilometers and
+ * miles
+ */
+public enum DistanceUnits {
+
+  MILES("miles", 3959, 24902), KILOMETERS("km", 6371, 40076);
+
+  private static final double MILES_KILOMETRES_RATIO = 1.609344;
+
+  private final String unit;
+
+  private final double earthCircumference;
+
+  private final double earthRadius;
+
+  /**
+   * Creates a new DistanceUnit that represents the given unit
+   * 
+   * @param unit
+   *          Distance unit in String form
+   * @param earthRadius
+   *          Radius of the Earth in the specific distance unit
+   * @param earthCircumfence
+   *          Circumference of the Earth in the specific distance unit
+   */
+  DistanceUnits(String unit, double earthRadius, double earthCircumfence) {
+    this.unit = unit;
+    this.earthCircumference = earthCircumfence;
+    this.earthRadius = earthRadius;
+  }
+
+  /**
+   * Returns the DistanceUnit which represents the given unit
+   * 
+   * @param unit
+   *          Unit whose DistanceUnit should be found
+   * @return DistanceUnit representing the unit
+   * @throws IllegalArgumentException
+   *           if no DistanceUnit which represents the given unit is found
+   */
+  public static DistanceUnits findDistanceUnit(String unit) {
+    if (MILES.getUnit().equals(unit)) {
+      return MILES;
+    }
+
+    if (KILOMETERS.getUnit().equals(unit)) {
+      return KILOMETERS;
+    }
+
+    throw new IllegalArgumentException("Unknown distance unit " + unit);
+  }
+
+  /**
+   * Converts the given distance in given DistanceUnit, to a distance in the
+   * unit represented by {@code this}
+   * 
+   * @param distance
+   *          Distance to convert
+   * @param from
+   *          Unit to convert the distance from
+   * @return Given distance converted to the distance in the given unit
+   */
+  public double convert(double distance, DistanceUnits from) {
+    if (from == this) {
+      return distance;
+    }
+    return (this == MILES) ? distance / MILES_KILOMETRES_RATIO : distance
+        * MILES_KILOMETRES_RATIO;
+  }
+
+  /**
+   * Returns the string representation of the distance unit
+   * 
+   * @return String representation of the distance unit
+   */
+  public String getUnit() {
+    return unit;
+  }
+
+  /**
+   * Returns the <a href="http://en.wikipedia.org/wiki/Earth_radius">average
+   * earth radius</a>
+   * 
+   * @return the average earth radius
+   */
+  public double earthRadius() {
+    return earthRadius;
+  }
+
+  /**
+   * Returns the <a
+   * href="http://www.lyberty.com/encyc/articles/earth.html">circumference of
+   * the Earth</a>
+   * 
+   * @return the circumference of the Earth
+   */
+  public double earthCircumference() {
+    return earthCircumference;
+  }
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/DistanceUnits.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/Ellipse.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/Ellipse.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/Ellipse.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/Ellipse.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,229 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Ellipse shape. From C++ gl.
+ * 
+ */
+public class Ellipse implements Geometry2D {
+  private Point2D center;
+
+  /**
+   * Half length of major axis
+   */
+  private double a;
+
+  /**
+   * Half length of minor axis
+   */
+  private double b;
+
+  private double k1, k2, k3;
+
+  /**
+   * sin of rotation angle
+   */
+  private double s;
+
+  /**
+   * cos of rotation angle
+   */
+  private double c;
+
+  public Ellipse() {
+    center = new Point2D(0, 0);
+  }
+
+  private double SQR(double d) {
+    return d * d;
+  }
+
+  /**
+   * Constructor given bounding rectangle and a rotation.
+   */
+  public Ellipse(Point2D p1, Point2D p2, double angle) {
+    center = new Point2D();
+
+    // Set the center
+    center.x((p1.x() + p2.x()) * 0.5f);
+    center.y((p1.y() + p2.y()) * 0.5f);
+
+    // Find sin and cos of the angle
+    double angleRad = Math.toRadians(angle);
+    c = Math.cos(angleRad);
+    s = Math.sin(angleRad);
+
+    // Find the half lengths of the semi-major and semi-minor axes
+    double dx = Math.abs(p2.x() - p1.x()) * 0.5;
+    double dy = Math.abs(p2.y() - p1.y()) * 0.5;
+    if (dx >= dy) {
+      a = dx;
+      b = dy;
+    } else {
+      a = dy;
+      b = dx;
+    }
+
+    // Find k1, k2, k3 - define when a point x,y is on the ellipse
+    k1 = SQR(c / a) + SQR(s / b);
+    k2 = 2 * s * c * ((1 / SQR(a)) - (1 / SQR(b)));
+    k3 = SQR(s / a) + SQR(c / b);
+  }
+
+  /**
+   * Determines if a line segment intersects the ellipse and if so finds the
+   * point(s) of intersection.
+   * 
+   * @param seg
+   *          Line segment to test for intersection
+   * @param pt0
+   *          OUT - intersection point (if it exists)
+   * @param pt1
+   *          OUT - second intersection point (if it exists)
+   * 
+   * @return Returns the number of intersection points (0, 1, or 2).
+   */
+  public int intersect(LineSegment seg, Point2D pt0, Point2D pt1) {
+    if (pt0 == null)
+      pt0 = new Point2D();
+    if (pt1 == null)
+      pt1 = new Point2D();
+
+    // Solution is found by parameterizing the line segment and
+    // substituting those values into the ellipse equation.
+    // Results in a quadratic equation.
+    double x1 = center.x();
+    double y1 = center.y();
+    double u1 = seg.A.x();
+    double v1 = seg.A.y();
+    double u2 = seg.B.x();
+    double v2 = seg.B.y();
+    double dx = u2 - u1;
+    double dy = v2 - v1;
+    double q0 = k1 * SQR(u1 - x1) + k2 * (u1 - x1) * (v1 - y1) + k3
+        * SQR(v1 - y1) - 1;
+    double q1 = (2 * k1 * dx * (u1 - x1)) + (k2 * dx * (v1 - y1))
+        + (k2 * dy * (u1 - x1)) + (2 * k3 * dy * (v1 - y1));
+    double q2 = (k1 * SQR(dx)) + (k2 * dx * dy) + (k3 * SQR(dy));
+
+    // Compare q1^2 to 4*q0*q2 to see how quadratic solves
+    double d = SQR(q1) - (4 * q0 * q2);
+    if (d < 0) {
+      // Roots are complex valued. Line containing the segment does
+      // not intersect the ellipse
+      return 0;
+    }
+
+    if (d == 0) {
+      // One real-valued root - line is tangent to the ellipse
+      double t = -q1 / (2 * q2);
+      if (0 <= t && t <= 1) {
+        // Intersection occurs along line segment
+        pt0.x(u1 + t * dx);
+        pt0.y(v1 + t * dy);
+        return 1;
+      } else
+        return 0;
+    } else {
+      // Two distinct real-valued roots. Solve for the roots and see if
+      // they fall along the line segment
+      int n = 0;
+      double q = Math.sqrt(d);
+      double t = (-q1 - q) / (2 * q2);
+      if (0 <= t && t <= 1) {
+        // Intersection occurs along line segment
+        pt0.x(u1 + t * dx);
+        pt0.y(v1 + t * dy);
+        n++;
+      }
+
+      // 2nd root
+      t = (-q1 + q) / (2 * q2);
+      if (0 <= t && t <= 1) {
+        if (n == 0) {
+          pt0.x(u1 + t * dx);
+          pt0.y(v1 + t * dy);
+          n++;
+        } else {
+          pt1.x(u1 + t * dx);
+          pt1.y(v1 + t * dy);
+          n++;
+        }
+      }
+      return n;
+    }
+  }
+
+  public IntersectCase intersect(Rectangle r) {
+    // Test if all 4 corners of the rectangle are inside the ellipse
+    Point2D ul = new Point2D(r.MinPt().x(), r.MaxPt().y());
+    Point2D ur = new Point2D(r.MaxPt().x(), r.MaxPt().y());
+    Point2D ll = new Point2D(r.MinPt().x(), r.MinPt().y());
+    Point2D lr = new Point2D(r.MaxPt().x(), r.MinPt().y());
+    if (contains(ul) && contains(ur) && contains(ll) && contains(lr))
+      return IntersectCase.CONTAINS;
+
+    // Test if any of the rectangle edges intersect
+    Point2D pt0 = new Point2D(), pt1 = new Point2D();
+    LineSegment bottom = new LineSegment(ll, lr);
+    if (intersect(bottom, pt0, pt1) > 0)
+      return IntersectCase.INTERSECTS;
+
+    LineSegment top = new LineSegment(ul, ur);
+    if (intersect(top, pt0, pt1) > 0)
+      return IntersectCase.INTERSECTS;
+
+    LineSegment left = new LineSegment(ll, ul);
+    if (intersect(left, pt0, pt1) > 0)
+      return IntersectCase.INTERSECTS;
+
+    LineSegment right = new LineSegment(lr, ur);
+    if (intersect(right, pt0, pt1) > 0)
+      return IntersectCase.INTERSECTS;
+
+    // Ellipse does not intersect any edge : since the case for the ellipse
+    // containing the rectangle was considered above then if the center
+    // is inside the ellipse is fully inside and if center is outside
+    // the ellipse is fully outside
+    return (r.contains(center)) ? IntersectCase.WITHIN : IntersectCase.OUTSIDE;
+  }
+
+  public double area() {
+    throw new UnsupportedOperationException();
+  }
+
+  public Point2D centroid() {
+    throw new UnsupportedOperationException();
+  }
+
+  public boolean contains(Point2D pt) {
+    // Plug in equation for ellipse, If evaluates to <= 0 then the
+    // point is in or on the ellipse.
+    double dx = pt.x() - center.x();
+    double dy = pt.y() - center.y();
+    double eq = (((k1 * SQR(dx)) + (k2 * dx * dy) + (k3 * SQR(dy)) - 1));
+
+    return eq <= 0;
+  }
+
+  public void translate(Vector2D v) {
+    throw new UnsupportedOperationException();
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/Ellipse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/FixedLatLng.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/FixedLatLng.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/FixedLatLng.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/FixedLatLng.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,160 @@
+/**
+ * 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.sis.core;
+
+/**
+ * 
+ * A fixed latitude longitude pair.
+ *
+ */
+public class FixedLatLng extends LatLng {
+  public static final double SCALE_FACTOR=1000000;
+  public static final int SCALE_FACTOR_INT=1000000;
+  
+  private int lat, lng;
+  private boolean normalized;
+  
+  public FixedLatLng(int lat, int lng) {
+    setLat(lat);
+    setLng(lng);
+  }
+  
+  public FixedLatLng(LatLng ll) {
+    this.lat=ll.getFixedLat();
+    this.lng=ll.getFixedLng();
+  }
+  
+  protected void setLat(int lat) {
+    if (lat>90*SCALE_FACTOR || lat<-90*SCALE_FACTOR) {
+      throw new IllegalArgumentException("Illegal lattitude");
+    }
+    this.lat=lat;
+  }
+
+  protected void setLng(int lng) {
+    this.lng=lng;
+  }
+  
+  public static double fixedToDouble(int fixed) {
+    return (fixed)/SCALE_FACTOR;
+  }
+  
+  public static int doubleToFixed(double d) {
+    return (int)(d*SCALE_FACTOR);
+  }
+  
+  @Override
+  public LatLng copy() {
+    return new FixedLatLng(this);
+  }
+
+  @Override
+  public int getFixedLat() {
+    return lat;
+  }
+
+  @Override
+  public int getFixedLng() {
+    return lng;
+  }
+
+  @Override
+  public double getLat() {
+    return fixedToDouble(lat);
+  }
+
+  @Override
+  public double getLng() {
+    return fixedToDouble(lng);
+  }
+
+  @Override
+  public boolean isFixedPoint() {
+    return true;
+  }
+
+  @Override
+  public FixedLatLng toFixed() {
+    return this;
+  }
+
+  @Override
+  public FloatLatLng toFloat() {
+    return new FloatLatLng(this);
+  }
+
+  @Override
+  public boolean isNormalized() {
+    return 
+      normalized || (
+          (lng>=-180*SCALE_FACTOR_INT) &&
+          (lng<=180*SCALE_FACTOR_INT)
+          );
+  }
+
+  @Override
+  public LatLng normalize() {
+    if (isNormalized()) return this;
+    
+    int delta=0;
+    if (lng<0) delta=360*SCALE_FACTOR_INT;
+    if (lng>=0) delta=-360*SCALE_FACTOR_INT;
+    
+    int newLng=lng;
+    while (newLng<=-180*SCALE_FACTOR_INT || newLng>=180*SCALE_FACTOR_INT) {
+      newLng+=delta;
+    }
+    
+    FixedLatLng ret=new FixedLatLng(lat, newLng);
+    ret.normalized=true;
+    return ret;
+  }
+  
+  @Override
+  public LatLng calculateMidpoint(LatLng other) {
+    return new FixedLatLng(
+        (lat+other.getFixedLat())/2,
+        (lng+other.getFixedLng())/2);
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = prime + lat;
+    result = prime * result + lng;
+    result = prime * result + (normalized ? 1231 : 1237);
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (getClass() != obj.getClass())
+      return false;
+    FixedLatLng other = (FixedLatLng) obj;
+    if (lat != other.lat)
+      return false;
+    if (lng != other.lng)
+      return false;
+    if (normalized != other.normalized)
+      return false;
+    return true;
+  }
+  
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/FixedLatLng.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/FloatLatLng.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/FloatLatLng.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/FloatLatLng.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/FloatLatLng.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,143 @@
+/**
+ * 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.sis.core;
+
+/**
+ * 
+ * A lat/lon pair using {@link Double} representation.
+ *
+ */
+public class FloatLatLng extends LatLng {
+  private double lat;
+  private double lng;
+  private boolean normalized;
+  
+  public FloatLatLng(double lat, double lng) {
+    if (lat>90.0 || lat<-90.0) throw new IllegalArgumentException("Illegal latitude value " + lat);
+    this.lat=lat;
+    this.lng=lng;
+  }
+  
+  public FloatLatLng(LatLng ll) {
+    this.lat=ll.getLat();
+    this.lng=ll.getLng();
+  }
+  
+  @Override
+  public LatLng copy() {
+    return new FloatLatLng(this);
+  }
+
+  @Override
+  public int getFixedLat() {
+    return FixedLatLng.doubleToFixed(this.lat);
+  }
+
+  @Override
+  public int getFixedLng() {
+    return FixedLatLng.doubleToFixed(this.lng);
+  }
+
+  @Override
+  public double getLat() {
+    return this.lat;
+  }
+
+  @Override
+  public double getLng() {
+    return this.lng;
+  }
+
+  @Override
+  public boolean isFixedPoint() {
+    return false;
+  }
+
+  @Override
+  public FixedLatLng toFixed() {
+    return new FixedLatLng(this);
+  }
+
+  @Override
+  public FloatLatLng toFloat() {
+    return this;
+  }
+  
+  @Override
+  public boolean isNormalized() {
+    return 
+      normalized || (
+          (lng>=-180) &&
+          (lng<=180)
+          );
+  }
+
+  @Override
+  public LatLng normalize() {
+    if (isNormalized()) return this;
+    
+    double delta=0;
+    if (lng<0) delta=360;
+    if (lng>=0) delta=-360;
+    
+    double newLng=lng;
+    while (newLng<=-180 || newLng>=180) {
+      newLng+=delta;
+    }
+    
+    FloatLatLng ret=new FloatLatLng(lat, newLng);
+    ret.normalized=true;
+    return ret;
+  }
+
+  @Override
+  public LatLng calculateMidpoint(LatLng other) {
+    return new FloatLatLng(
+        (lat+other.getLat())/2.0,
+        (lng+other.getLng())/2.0);
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    long temp;
+    temp = Double.doubleToLongBits(lat);
+    int result = prime  + (int) (temp ^ (temp >>> 32));
+    temp = Double.doubleToLongBits(lng);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    result = prime * result + (normalized ? 1231 : 1237);
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (getClass() != obj.getClass())
+      return false;
+    FloatLatLng other = (FloatLatLng) obj;
+    if (Double.doubleToLongBits(lat) != Double.doubleToLongBits(other.lat))
+      return false;
+    if (Double.doubleToLongBits(lng) != Double.doubleToLongBits(other.lng))
+      return false;
+    if (normalized != other.normalized)
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/FloatLatLng.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/Geometry2D.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/Geometry2D.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/Geometry2D.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/Geometry2D.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,49 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Common set of operations available on 2d shapes.
+ * 
+ */
+public interface Geometry2D {
+  /**
+   * Translate according to the vector
+   * 
+   * @param v
+   */
+  public void translate(Vector2D v);
+
+  /**
+   * Does the shape contain the given point
+   * 
+   * @param p
+   */
+  public boolean contains(Point2D p);
+
+  /**
+   * Return the area
+   */
+  public double area();
+
+  /**
+   * Return the centroid
+   */
+  public Point2D centroid();
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/Geometry2D.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/IntersectCase.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/IntersectCase.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/IntersectCase.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/IntersectCase.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,29 @@
+/**
+ * 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.sis.core;
+
+/**
+ *  Useful constants describing the different intersection cases
+ *  of SIS objects.
+ */
+public enum IntersectCase {
+  WITHIN,
+  CONTAINS,
+  OUTSIDE,
+  INTERSECTS;
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/IntersectCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/LLRect.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/LLRect.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/LLRect.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/LLRect.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,185 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Lat-long rect. Instances are mutable.
+ * 
+ */
+public class LLRect {
+  private LatLng ll, ur;
+
+  public LLRect(LatLng ll, LatLng ur) {
+    this.ll = ll;
+    this.ur = ur;
+  }
+
+  public LLRect(LLRect other) {
+    this.ll = other.ll;
+    this.ur = other.ur;
+  }
+
+  /**
+   * Return the area in units of lat-lng squared. This is a contrived unit that
+   * only has value when comparing to something else.
+   */
+  public double area() {
+    return Math.abs((ll.getLat() - ur.getLat()) * (ll.getLng() - ur.getLng()));
+  }
+
+  public LatLng getLowerLeft() {
+    return ll;
+  }
+
+  public LatLng getUpperRight() {
+    return ur;
+  }
+
+  @Override
+  public String toString() {
+    return "{" + ll + ", " + ur + "}";
+  }
+
+  public LatLng getMidpoint() {
+    return ll.calculateMidpoint(ur);
+  }
+
+  /**
+   * Approximates a box centered at the given point with the given width and
+   * height in miles.
+   * 
+   * @param center
+   * @param widthMi
+   * @param heightMi
+   */
+  public static LLRect createBox(LatLng center, double widthMi, double heightMi) {
+    double d = widthMi;
+    LatLng ur = boxCorners(center, d, 45.0); // assume right angles
+    LatLng ll = boxCorners(center, d, 225.0);
+
+    // System.err.println("boxCorners: ur " + ur.getLat() + ',' + ur.getLng());
+    // System.err.println("boxCorners: cnt " + center.getLat() + ',' +
+    // center.getLng());
+    // System.err.println("boxCorners: ll " + ll.getLat() + ',' + ll.getLng());
+    return new LLRect(ll, ur);
+  }
+
+  /**
+   * Returns a rectangle shape for the bounding box
+   */
+  public Rectangle toRectangle() {
+    return new Rectangle(ll.getLng(), ll.getLat(), ur.getLng(), ur.getLat());
+  }
+
+  private static LatLng boxCorners(LatLng center, double d, double brngdeg) {
+    double a = center.getLat();
+    double b = center.getLng();
+    double R = 3963.0; // radius of earth in miles
+    double brng = (Math.PI * brngdeg / 180);
+    double lat1 = (Math.PI * a / 180);
+    double lon1 = (Math.PI * b / 180);
+
+    // Haversine formula
+    double lat2 = Math.asin(Math.sin(lat1) * Math.cos(d / R) + Math.cos(lat1)
+        * Math.sin(d / R) * Math.cos(brng));
+    double lon2 = lon1
+        + Math.atan2(Math.sin(brng) * Math.sin(d / R) * Math.cos(lat1), Math
+            .cos(d / R)
+            - Math.sin(lat1) * Math.sin(lat2));
+
+    lat2 = (lat2 * 180) / Math.PI;
+    lon2 = (lon2 * 180) / Math.PI;
+
+    // normalize long first
+    LatLng ll = normLng(lat2, lon2);
+
+    // normalize lat - could flip poles
+    ll = normLat(ll.getLat(), ll.getLng());
+
+    return ll;
+  }
+
+  /**
+   * Returns a normalized Lat rectangle shape for the bounding box If you go
+   * over the poles, you need to flip the lng value too
+   */
+  private static LatLng normLat(double lat, double lng) {
+    if (lat > 90.0) {
+      lat = 90.0 - (lat - 90.0);
+      if (lng < 0) {
+        lng = lng + 180;
+      } else {
+        lng = lng - 180;
+      }
+    } else if (lat < -90.0) {
+      lat = -90.0 - (lat + 90.0);
+      if (lng < 0) {
+        lng = lng + 180;
+      } else {
+        lng = lng - 180;
+      }
+    }
+    LatLng ll = new FloatLatLng(lat, lng);
+    return ll;
+  }
+
+  /**
+   * Returns a normalized Lng rectangle shape for the bounding box
+   */
+  private static LatLng normLng(double lat, double lng) {
+    if (lng > 180.0) {
+      lng = -1.0 * (180.0 - (lng - 180.0));
+    } else if (lng < -180.0) {
+      lng = (lng + 180.0) + 180.0;
+    }
+    LatLng ll = new FloatLatLng(lat, lng);
+    return ll;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((ll == null) ? 0 : ll.hashCode());
+    result = prime * result + ((ur == null) ? 0 : ur.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LLRect other = (LLRect) obj;
+    if (ll == null) {
+      if (other.ll != null)
+        return false;
+    } else if (!ll.equals(other.ll))
+      return false;
+    if (ur == null) {
+      if (other.ur != null)
+        return false;
+    } else if (!ur.equals(other.ur))
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/LLRect.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/LatLng.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/LatLng.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/LatLng.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/LatLng.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,156 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Abstract base lat-lng class which can manipulate fixed point or floating
+ * point based coordinates. Instances are immutable.
+ * 
+ * @see FloatLatLng
+ **/
+public abstract class LatLng {
+
+  public abstract boolean isNormalized();
+
+  public abstract boolean isFixedPoint();
+
+  public abstract LatLng normalize();
+
+  public abstract int getFixedLat();
+
+  public abstract int getFixedLng();
+
+  public abstract double getLat();
+
+  public abstract double getLng();
+
+  public abstract LatLng copy();
+
+  public abstract FixedLatLng toFixed();
+
+  public abstract FloatLatLng toFloat();
+
+  /**
+   * Convert the lat/lng into the cartesian coordinate plane such that all world
+   * coordinates are represented in the first quadrant. The x dimension
+   * corresponds to latitude and y corresponds to longitude. The translation
+   * starts with the normalized latlng and adds 180 to the latitude and 90 to
+   * the longitude (subject to fixed point scaling).
+   */
+  public CartesianPoint toCartesian() {
+    LatLng ll = normalize();
+
+    int lat = ll.getFixedLat();
+    int lng = ll.getFixedLng();
+
+    return new CartesianPoint(lng + 180 * FixedLatLng.SCALE_FACTOR_INT, lat
+        + 90 * FixedLatLng.SCALE_FACTOR_INT);
+  }
+
+  /**
+   * The inverse of toCartesian(). Always returns a FixedLatLng.
+   * 
+   * @param pt
+   */
+  public static LatLng fromCartesian(CartesianPoint pt) {
+    int lat = pt.getY() - 90 * FixedLatLng.SCALE_FACTOR_INT;
+    int lng = pt.getX() - 180 * FixedLatLng.SCALE_FACTOR_INT;
+
+    return new FixedLatLng(lat, lng);
+  }
+
+  /**
+   * Calculates the distance between two lat/lng's in miles. Imported from mq
+   * java client.
+   * 
+   * @param ll2
+   *          Second lat,lng position to calculate distance to.
+   * 
+   * @return Returns the distance in miles.
+   */
+  public double arcDistance(LatLng ll2) {
+    return arcDistance(ll2, DistanceUnits.MILES);
+  }
+
+  /**
+   * Calculates the distance between two lat/lng's in miles or meters. Imported
+   * from mq java client. Variable references changed to match.
+   * 
+   * @param ll2
+   *          Second lat,lng position to calculate distance to.
+   * @param lUnits
+   *          Units to calculate distance, defaults to miles
+   * 
+   * @return Returns the distance in meters or miles.
+   */
+  public double arcDistance(LatLng ll2, DistanceUnits lUnits) {
+    LatLng ll1 = normalize();
+    ll2 = ll2.normalize();
+
+    double lat1 = ll1.getLat(), lng1 = ll1.getLng();
+    double lat2 = ll2.getLat(), lng2 = ll2.getLng();
+
+    // Check for same position
+    if (lat1 == lat2 && lng1 == lng2)
+      return 0.0;
+
+    // Get the m_dLongitude difference. Don't need to worry about
+    // crossing 180 since cos(x) = cos(-x)
+    double dLon = lng2 - lng1;
+
+    double a = radians(90.0 - lat1);
+    double c = radians(90.0 - lat2);
+    double cosB = (Math.cos(a) * Math.cos(c))
+        + (Math.sin(a) * Math.sin(c) * Math.cos(radians(dLon)));
+
+    double radius = (lUnits == DistanceUnits.MILES) ? 3963.205/* MILERADIUSOFEARTH */
+    : 6378.160187/* KMRADIUSOFEARTH */;
+
+    // Find angle subtended (with some bounds checking) in radians and
+    // multiply by earth radius to find the arc distance
+    if (cosB < -1.0)
+      return 3.14159265358979323846/* PI */* radius;
+    else if (cosB >= 1.0)
+      return 0;
+    else
+      return Math.acos(cosB) * radius;
+  }
+
+  private double radians(double a) {
+    return a * 0.01745329251994;
+  }
+
+  @Override
+  public String toString() {
+    return "[" + getLat() + "," + getLng() + "]";
+  }
+
+  /**
+   * Calculate the midpoint between this point an another. Respects fixed vs
+   * floating point
+   * 
+   * @param other
+   */
+  public abstract LatLng calculateMidpoint(LatLng other);
+
+  @Override
+  public abstract int hashCode();
+
+  @Override
+  public abstract boolean equals(Object obj);
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/LatLng.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/LineSegment.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/LineSegment.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/LineSegment.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/LineSegment.java Thu Apr  1 01:40:24 2010
@@ -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.sis.core;
+
+/**
+ * 2d line segment.
+ * 
+ */
+public class LineSegment {
+  public final Point2D A = new Point2D();
+  public final Point2D B = new Point2D();
+
+  public LineSegment() {
+    A.set(0, 0);
+    B.set(0, 0);
+  }
+
+  public LineSegment(Point2D p1, Point2D p2) {
+    A.set(p1);
+    B.set(p2);
+  }
+
+  /**
+   * Finds the distance of a specified point from the line segment and the
+   * closest point on the segment to the specified point.
+   * 
+   * @param P
+   *          Test point.
+   * @param closestPt
+   *          (Return) Closest point on the segment to c.
+   * 
+   * @return Returns the distance from P to the closest point on the segment.
+   */
+  public double distance(Point2D P, Point2D /* out */closestPt) {
+    if (closestPt == null)
+      closestPt = new Point2D();
+
+    // Construct vector v (AB) and w (AP)
+    Vector2D v = new Vector2D(A, B);
+    Vector2D w = new Vector2D(A, P);
+
+    // Numerator of the component of w onto v. If <= 0 then A
+    // is the closest point. By separating into the numerator
+    // and denominator of the component we avoid a division unless
+    // it is necessary.
+    double n = w.dot(v);
+    if (n <= 0.0f) {
+      closestPt.set(A);
+      return w.norm();
+    }
+
+    // Get the denominator of the component. If the component >= 1
+    // (d <= n) then point B is the closest point
+    double d = v.dot(v);
+    if (d <= n) {
+      closestPt.set(B);
+      return new Vector2D(B, P).norm();
+    }
+
+    // Closest point is along the segment. The point is the projection of
+    // w onto v.
+    closestPt.set(v.mult(n / d));
+    closestPt.add(A);
+    return new Vector2D(closestPt, P).norm();
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((A == null) ? 0 : A.hashCode());
+    result = prime * result + ((B == null) ? 0 : B.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LineSegment other = (LineSegment) obj;
+    if (A == null) {
+      if (other.A != null)
+        return false;
+    } else if (!A.equals(other.A))
+      return false;
+    if (B == null) {
+      if (other.B != null)
+        return false;
+    } else if (!B.equals(other.B))
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/LineSegment.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/Point2D.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/Point2D.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/Point2D.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/Point2D.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,133 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Point class. This type is mutable.
+ * 
+ **/
+public class Point2D {
+  private double x;
+  private double y;
+
+  public Point2D(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  public Point2D() {
+    this.x = 0;
+    this.y = 0;
+  }
+
+  public Point2D(Point2D other) {
+    this.x = other.x;
+    this.y = other.y;
+  }
+
+  @Override
+  public String toString() {
+    return "(" + x + "," + y + ")";
+  }
+
+  public double getX() {
+    return x;
+  }
+
+  public double getY() {
+    return y;
+  }
+
+  public double x() {
+    return x;
+  }
+
+  public double y() {
+    return y;
+  }
+
+  public void x(double x) {
+    this.x = x;
+  }
+
+  public void y(double y) {
+    this.y = y;
+  }
+
+  public void setX(double x) {
+    this.x = x;
+  }
+
+  public void setY(double y) {
+    this.y = y;
+  }
+
+  public void set(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  public void add(Vector2D v) {
+    this.x += v.getX();
+    this.y += v.getY();
+  }
+
+  public void set(Point2D p1) {
+    this.x = p1.getX();
+    this.y = p1.getY();
+  }
+
+  public void add(Point2D a) {
+    this.x += a.getX();
+    this.y += a.getY();
+  }
+
+  public void set(Vector2D v) {
+    this.x = v.getX();
+    this.y = v.getY();
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    long temp;
+    temp = Double.doubleToLongBits(x);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    temp = Double.doubleToLongBits(y);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Point2D other = (Point2D) obj;
+    if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
+      return false;
+    if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/Point2D.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/PointsD.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/PointsD.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/PointsD.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/PointsD.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,66 @@
+/**
+ * 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.sis.core;
+
+/**
+ * 
+**/
+public class PointsD {
+
+  double x, y;
+
+  public PointsD(Double x, Double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  public double getX() {
+    return x;
+  }
+
+  public double getY() {
+    return y;
+  }
+
+  
+  @Override
+  public String toString() {
+  
+    return x+","+y;
+  }
+  
+  
+  public String toKMLCoord() {
+  
+    return y+","+x;
+  }
+  
+  @Override
+  public boolean equals(Object obj) {
+    PointsD other = (PointsD)obj;
+    return (other.getX() == this.x && other.getY() == this.y);
+  }
+  
+  public int hashCode(){
+    
+    int result = new Double(x).hashCode();
+    result ^= 31* new Double(y).hashCode();
+    
+    return result;
+  }
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/PointsD.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/Rectangle.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/Rectangle.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/Rectangle.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/Rectangle.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,117 @@
+/**
+ * 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.sis.core;
+
+/**
+ * Rectangle shape.
+ * 
+ **/
+public class Rectangle implements Geometry2D {
+  private Point2D ptMin, ptMax;
+
+  public Rectangle() {
+    ptMin = new Point2D(-1, 1);
+    ptMax = new Point2D(1, 1);
+  }
+
+  public Rectangle(Point2D ptMin, Point2D ptMax) {
+    this.ptMin = new Point2D(ptMin);
+    this.ptMax = new Point2D(ptMax);
+  }
+
+  public Rectangle(double x1, double y1, double x2, double y2) {
+    set(x1, y1, x2, y2);
+  }
+
+  @Override
+  public String toString() {
+    return "[" + ptMin + "," + ptMax + "]";
+  }
+
+  private void set(double x1, double y1, double x2, double y2) {
+    this.ptMin = new Point2D(Math.min(x1, x2), Math.min(y1, y2));
+    this.ptMax = new Point2D(Math.max(x1, x2), Math.max(y1, y2));
+  }
+
+  public double area() {
+    return (ptMax.getX() - ptMin.getX()) * (ptMax.getY() - ptMin.getY());
+  }
+
+  public Point2D centroid() {
+    return new Point2D((ptMin.getX() + ptMax.getX()) / 2, (ptMin.getY() + ptMax
+        .getY()) / 2);
+  }
+
+  public boolean contains(Point2D p) {
+    return p.getX() >= ptMin.getX() && p.getX() <= ptMax.getX()
+        && p.getY() >= ptMin.getY() && p.getY() <= ptMax.getY();
+  }
+
+  public void translate(Vector2D v) {
+    ptMin.add(v);
+    ptMax.add(v);
+  }
+
+  Point2D MinPt() {
+    return ptMin;
+  }
+
+  Point2D MaxPt() {
+    return ptMax;
+  }
+
+  public Point2D getMaxPoint() {
+    return ptMax;
+  }
+
+  public Point2D getMinPoint() {
+    return ptMin;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((ptMax == null) ? 0 : ptMax.hashCode());
+    result = prime * result + ((ptMin == null) ? 0 : ptMin.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Rectangle other = (Rectangle) obj;
+    if (ptMax == null) {
+      if (other.ptMax != null)
+        return false;
+    } else if (!ptMax.equals(other.ptMax))
+      return false;
+    if (ptMin == null) {
+      if (other.ptMin != null)
+        return false;
+    } else if (!ptMin.equals(other.ptMin))
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/Rectangle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/Shape.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/Shape.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/Shape.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/Shape.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,51 @@
+/**
+ * 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.sis.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author pjaol
+ * 
+ */
+public class Shape {
+
+  protected List<Double> area = new ArrayList<Double>();
+  private String tierId;
+
+  public Shape(String tierId) {
+    this.tierId = tierId;
+  }
+
+  public void addBox(double boxId) {
+    area.add(boxId);
+  }
+
+  public List<Double> getArea() {
+    return area;
+  }
+
+  public String getTierId() {
+    return tierId;
+  }
+
+  public boolean isInside(double boxId) {
+    return area.contains(boxId);
+  }
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/Shape.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/TierBoundaries.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/TierBoundaries.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/TierBoundaries.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/TierBoundaries.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,137 @@
+/**
+ * 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.sis.core;
+
+import org.apache.sis.projections.CartesianTierPlotter;
+import org.apache.sis.projections.Projection;
+import org.apache.sis.projections.SinusoidalProjector;
+
+public class TierBoundaries {
+
+  CartesianTierPlotter ctp;
+  public int defaultLevel = 16;
+  Projection projection = new SinusoidalProjector();
+  PointsD topLeft, topRight, bottomLeft, bottomRight;
+
+  public PointsD getTopLeft() {
+    return topLeft;
+  }
+
+  public void setTopLeft(PointsD topLeft) {
+    this.topLeft = topLeft;
+  }
+
+  public PointsD getTopRight() {
+    return topRight;
+  }
+
+  public void setTopRight(PointsD topRight) {
+    this.topRight = topRight;
+  }
+
+  public PointsD getBottomLeft() {
+    return bottomLeft;
+  }
+
+  public void setBottomLeft(PointsD bottomLeft) {
+    this.bottomLeft = bottomLeft;
+  }
+
+  public PointsD getBottomRight() {
+    return bottomRight;
+  }
+
+  public void setBottomRight(PointsD bottomRight) {
+    this.bottomRight = bottomRight;
+  }
+
+  public static void main(String[] args) {
+    TierBoundaries tb = new TierBoundaries();
+    tb.getBoundaries(37.43629392840975, -122.13848663330079);
+  }
+
+  public TierBoundaries() {
+    ctp = new CartesianTierPlotter(defaultLevel, projection);
+
+  }
+
+  public TierBoundaries(Projection Projection) {
+    this.projection = Projection;
+    ctp = new CartesianTierPlotter(defaultLevel, Projection);
+  }
+
+  public TierBoundaries(CartesianTierPlotter ctp) {
+    this.ctp = ctp;
+  }
+
+  public void getBoundaries(double lat, double lng) {
+
+    double baseBoxId = ctp.getTierBoxId(lat, lng);
+    double currentBoxLeft = baseBoxId, currentBoxRight = baseBoxId;
+    double incVal = 0.000000001;
+    double rightLng = lng, leftLng = lng;
+    do {
+      if (currentBoxLeft == baseBoxId) {
+        rightLng -= incVal;
+        currentBoxLeft = ctp.getTierBoxId(lat, rightLng);
+      }
+
+      if (currentBoxRight == baseBoxId) {
+        leftLng += incVal;
+        currentBoxRight = ctp.getTierBoxId(lat, leftLng);
+      }
+
+    } while (currentBoxLeft == baseBoxId || currentBoxRight == baseBoxId);
+
+    double downLat = lat, upLat = lat;
+    currentBoxLeft = baseBoxId;
+    currentBoxRight = baseBoxId;
+    do {
+      if (currentBoxLeft == baseBoxId) {
+        downLat -= incVal;
+        currentBoxLeft = ctp.getTierBoxId(downLat, lng);
+      }
+
+      if (currentBoxRight == baseBoxId) {
+        upLat += incVal;
+        currentBoxRight = ctp.getTierBoxId(upLat, lng);
+      }
+
+    } while (currentBoxLeft == baseBoxId || currentBoxRight == baseBoxId);
+
+    topLeft = new PointsD(upLat, leftLng);
+    topRight = new PointsD(upLat, rightLng);
+    bottomLeft = new PointsD(downLat, leftLng);
+    bottomRight = new PointsD(downLat, rightLng);
+  }
+
+  public String toKMLCoords() {
+
+    return topLeft.toKMLCoord() + ",0\n" + topRight.toKMLCoord() + ",0\n"
+        + bottomRight.toKMLCoord() + ",0\n" + bottomLeft.toKMLCoord() + ",0\n"
+        + topLeft.toKMLCoord() + ",0\n";
+  }
+
+  @Override
+  public String toString() {
+
+    return topLeft.toString() + "\n" + topRight.toString() + "\n"
+        + bottomRight.toString() + "\n" + bottomLeft.toString() + "\n"
+        + topLeft.toString() + "n";
+  }
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/TierBoundaries.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/core/Vector2D.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/core/Vector2D.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/core/Vector2D.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/core/Vector2D.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,139 @@
+/**
+ * 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.sis.core;
+
+/**
+ * 2D vector.
+ * 
+ */
+public class Vector2D {
+  private double x;
+  private double y;
+
+  /**
+   * Create a vector from the origin of the coordinate system to the given point
+   * 
+   * @param x
+   * @param y
+   */
+  public Vector2D(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  /**
+   * Create a vector from the origin of the coordinate system to the given point
+   */
+  public Vector2D(Point2D p) {
+    this(p.getX(), p.getY());
+  }
+
+  /**
+   * Create a vector from one point to another
+   * 
+   * @param from
+   * @param to
+   */
+  public Vector2D(Point2D from, Point2D to) {
+    this(to.getX() - from.getX(), to.getY() - from.getY());
+  }
+
+  public Vector2D() {
+    this.x = 0;
+    this.y = 0;
+  }
+
+  public Vector2D(Vector2D other) {
+    this.x = other.x;
+    this.y = other.y;
+  }
+
+  public double getX() {
+    return x;
+  }
+
+  public double getY() {
+    return y;
+  }
+
+  public void setX(double x) {
+    this.x = x;
+  }
+
+  public void setY(double y) {
+    this.y = y;
+  }
+
+  public void set(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  public boolean equals(Vector2D other) {
+    return other != null && x == other.x && y == other.y;
+  }
+
+  public double dot(Vector2D in) {
+    return ((x) * in.x) + (y * in.y);
+  }
+
+  /**
+   * Vector length (magnitude) squared
+   */
+  public double normSqr() {
+    // Cast to F to prevent overflows
+    return (x * x) + (y * y);
+  }
+
+  public double norm() {
+    return Math.sqrt(normSqr());
+  }
+
+  public Vector2D mult(double d) {
+    return new Vector2D(x * d, y * d);
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    long temp;
+    temp = Double.doubleToLongBits(x);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    temp = Double.doubleToLongBits(y);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Vector2D other = (Vector2D) obj;
+    if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
+      return false;
+    if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
+      return false;
+    return true;
+  }
+
+}

Propchange: incubator/sis/trunk/src/main/java/org/apache/sis/core/Vector2D.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sis/trunk/src/main/java/org/apache/sis/util/GeoHashUtils.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/src/main/java/org/apache/sis/util/GeoHashUtils.java?rev=929771&view=auto
==============================================================================
--- incubator/sis/trunk/src/main/java/org/apache/sis/util/GeoHashUtils.java (added)
+++ incubator/sis/trunk/src/main/java/org/apache/sis/util/GeoHashUtils.java Thu Apr  1 01:40:24 2010
@@ -0,0 +1,142 @@
+/**
+ * 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.sis.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utilities for encoding and decoding geohashes. Based on
+ * http://en.wikipedia.org/wiki/Geohash.
+ */
+public class GeoHashUtils {
+
+  private static final char[] BASE_32 = { '0', '1', '2', '3', '4', '5', '6',
+      '7', '8', '9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n',
+      'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
+
+  private final static Map<Character, Integer> DECODE_MAP = new HashMap<Character, Integer>();
+
+  private static final int PRECISION = 12;
+  private static final int[] BITS = { 16, 8, 4, 2, 1 };
+
+  static {
+    for (int i = 0; i < BASE_32.length; i++) {
+      DECODE_MAP.put(Character.valueOf(BASE_32[i]), Integer.valueOf(i));
+    }
+  }
+
+  private GeoHashUtils() {
+  }
+
+  /**
+   * Encodes the given latitude and longitude into a geohash
+   * 
+   * @param latitude
+   *          Latitude to encode
+   * @param longitude
+   *          Longitude to encode
+   * @return Geohash encoding of the longitude and latitude
+   */
+  public static String encode(double latitude, double longitude) {
+    double[] latInterval = { -90.0, 90.0 };
+    double[] lngInterval = { -180.0, 180.0 };
+
+    final StringBuilder geohash = new StringBuilder();
+    boolean isEven = true;
+
+    int bit = 0;
+    int ch = 0;
+
+    while (geohash.length() < PRECISION) {
+      double mid = 0.0;
+      if (isEven) {
+        mid = (lngInterval[0] + lngInterval[1]) / 2D;
+        if (longitude > mid) {
+          ch |= BITS[bit];
+          lngInterval[0] = mid;
+        } else {
+          lngInterval[1] = mid;
+        }
+      } else {
+        mid = (latInterval[0] + latInterval[1]) / 2D;
+        if (latitude > mid) {
+          ch |= BITS[bit];
+          latInterval[0] = mid;
+        } else {
+          latInterval[1] = mid;
+        }
+      }
+
+      isEven = !isEven;
+
+      if (bit < 4) {
+        bit++;
+      } else {
+        geohash.append(BASE_32[ch]);
+        bit = 0;
+        ch = 0;
+      }
+    }
+
+    return geohash.toString();
+  }
+
+  /**
+   * Decodes the given geohash into a latitude and longitude
+   * 
+   * @param geohash
+   *          Geohash to deocde
+   * @return Array with the latitude at index 0, and longitude at index 1
+   */
+  public static double[] decode(String geohash) {
+    final double[] latInterval = { -90.0, 90.0 };
+    final double[] lngInterval = { -180.0, 180.0 };
+
+    boolean isEven = true;
+
+    double latitude;
+    double longitude;
+    for (int i = 0; i < geohash.length(); i++) {
+      final int cd = DECODE_MAP.get(Character.valueOf(geohash.charAt(i)))
+          .intValue();
+
+      for (int mask : BITS) {
+        if (isEven) {
+          if ((cd & mask) != 0) {
+            lngInterval[0] = (lngInterval[0] + lngInterval[1]) / 2D;
+          } else {
+            lngInterval[1] = (lngInterval[0] + lngInterval[1]) / 2D;
+          }
+        } else {
+          if ((cd & mask) != 0) {
+            latInterval[0] = (latInterval[0] + latInterval[1]) / 2D;
+          } else {
+            latInterval[1] = (latInterval[0] + latInterval[1]) / 2D;
+          }
+        }
+        isEven = !isEven;
+      }
+
+    }
+    latitude = (latInterval[0] + latInterval[1]) / 2D;
+    longitude = (lngInterval[0] + lngInterval[1]) / 2D;
+
+    return new double[] { latitude, longitude };
+  }
+}
\ No newline at end of file



Mime
View raw message