sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mattm...@apache.org
Subject svn commit: r986558 [1/2] - in /incubator/sis/trunk: ./ sis-core/src/main/java/org/apache/sis/core/ sis-core/src/main/java/org/apache/sis/distance/ sis-core/src/main/java/org/apache/sis/projections/ sis-core/src/main/java/org/apache/sis/storage/ sis-co...
Date Wed, 18 Aug 2010 03:21:47 GMT
Author: mattmann
Date: Wed Aug 18 03:21:43 2010
New Revision: 986558

URL: http://svn.apache.org/viewvc?rev=986558&view=rev
Log:
- fix for SIS-3 Refactor SIS

Added:
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLon.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonPointRadius.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonRect.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/distance/
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/distance/DistanceUtils.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/GeoRSSData.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/NodeType.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTree.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeData.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeNode.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeReader.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeWriter.java   (with props)
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/Quadrant.java   (with props)
    incubator/sis/trunk/sis-webapp/
    incubator/sis/trunk/sis-webapp/pom.xml
    incubator/sis/trunk/sis-webapp/src/
    incubator/sis/trunk/sis-webapp/src/main/
    incubator/sis/trunk/sis-webapp/src/main/java/
    incubator/sis/trunk/sis-webapp/src/main/java/org/
    incubator/sis/trunk/sis-webapp/src/main/java/org/apache/
    incubator/sis/trunk/sis-webapp/src/main/java/org/apache/sis/
    incubator/sis/trunk/sis-webapp/src/main/java/org/apache/sis/services/
    incubator/sis/trunk/sis-webapp/src/main/java/org/apache/sis/services/LocationServlet.java   (with props)
    incubator/sis/trunk/sis-webapp/src/main/resources/
    incubator/sis/trunk/sis-webapp/src/main/resources/sis-location-config.xml
    incubator/sis/trunk/sis-webapp/src/main/webapp/
    incubator/sis/trunk/sis-webapp/src/main/webapp/META-INF/
    incubator/sis/trunk/sis-webapp/src/main/webapp/META-INF/context.xml
    incubator/sis/trunk/sis-webapp/src/main/webapp/WEB-INF/
    incubator/sis/trunk/sis-webapp/src/main/webapp/WEB-INF/web.xml
Removed:
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/CartesianPoint.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/DistanceUnits.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/Ellipse.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/FixedLatLng.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/FloatLatLng.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/Geometry2D.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/IntersectCase.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LLRect.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLng.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LineSegment.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/Point2D.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/PointsD.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/Rectangle.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/Shape.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/TierBoundaries.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/Vector2D.java
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/projections/
Modified:
    incubator/sis/trunk/CHANGES.txt
    incubator/sis/trunk/pom.xml
    incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/util/GeoHashUtils.java

Modified: incubator/sis/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/CHANGES.txt?rev=986558&r1=986557&r2=986558&view=diff
==============================================================================
--- incubator/sis/trunk/CHANGES.txt (original)
+++ incubator/sis/trunk/CHANGES.txt Wed Aug 18 03:21:43 2010
@@ -2,6 +2,8 @@ Apache SIS Change Log
 ======================
 Release 0.1-incubating (Current Development)
 
+* SIS-3 Refactor SIS (Nga Chung, mattmann)
+
 * SIS-7 Top level pom for SIS (mattmann)
 
 * SIS-5 Website logo (mattmann)

Modified: incubator/sis/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/pom.xml?rev=986558&r1=986557&r2=986558&view=diff
==============================================================================
--- incubator/sis/trunk/pom.xml (original)
+++ incubator/sis/trunk/pom.xml Wed Aug 18 03:21:43 2010
@@ -47,6 +47,7 @@
   <modules>
     <module>sis-parent</module>
     <module>sis-core</module>
+    <module>sis-webapp</module>
   </modules>
 
   <build>

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLon.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLon.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLon.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLon.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,104 @@
+/**
+ * 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 2D point on earth surface by latitude and longitude.
+ * 
+ * 
+ */
+public class LatLon {
+
+  private double lat;
+  private double lon;
+
+  /**
+   * LatLon to represent geo point.
+   * 
+   * @param lat
+   *          the latitude
+   * @param lon
+   *          the longitude
+   */
+  public LatLon(double lat, double lon) {
+    this.lat = lat;
+    this.lon = lon;
+  }
+
+  /**
+   * Shifts the latitude by +90.0 so that all latitude lies in the positive
+   * coordinate. Used mainly for Java 2D geometry.
+   * 
+   * @return latitude shifted by +90.0
+   */
+  public double getShiftedLat() {
+    return this.lat + 90.0;
+  }
+
+  /**
+   * Shifts the longitude by +180.0 so that all longitude lies in the positive
+   * coordinate. Used mainly for Java 2D geometry.
+   * 
+   * @return longitude shifted by +180.0
+   */
+  public double getShiftedLon() {
+    return this.lon + 180.0;
+  }
+
+  /**
+   * Returns the latitude.
+   * 
+   * @return latitude
+   */
+  public double getLat() {
+    return this.lat;
+  }
+
+  /**
+   * Returns the longitude.
+   * 
+   * @return longitude
+   */
+  public double getLon() {
+    return this.lon;
+  }
+
+  /**
+   * Normalizes the longitude values to be between -180.0 and 180.0
+   * 
+   * @return longitude value that is between -180.0 and 180.0 inclusive
+   */
+  public double getNormLon() {
+    double normLon = this.lon;
+    if (normLon > 180.0) {
+      while (normLon > 180.0) {
+        normLon -= 360.0;
+      }
+    } else if (normLon < -180.0) {
+      while (normLon < -180.0) {
+        normLon += 360.0;
+      }
+    }
+    return normLon;
+  }
+
+  @Override
+  public String toString() {
+    return this.lat + "," + this.lon;
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonPointRadius.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonPointRadius.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonPointRadius.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonPointRadius.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,171 @@
+/**
+ * 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;
+
+//JDK imports
+import java.awt.geom.Area;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+
+//SIS imports
+import org.apache.sis.distance.DistanceUtils;
+
+/**
+ * Represents a 2D point associated with a radius to enable great circle
+ * estimation on earth surface.
+ * 
+ */
+public class LatLonPointRadius {
+
+  private LatLon center;
+  private double radius;
+
+  /**
+   * Creates a representation of point-radius search region.
+   * 
+   * @param center
+   *          the center of the search region
+   * @param radius
+   *          the radius of the search region
+   */
+  public LatLonPointRadius(LatLon center, double radius) {
+    this.center = center;
+    this.radius = radius;
+  }
+
+  /**
+   * Gets the circular region approximation on the earth surface using haversine
+   * formula.
+   * 
+   * @param numberOfPoints
+   *          the number of points used to estimate the circular region
+   * @return an array of LatLon representing the points that estimate the
+   *         circular region
+   */
+  public LatLon[] getCircularRegionApproximation(int numberOfPoints) {
+    if (this.radius >= DistanceUtils.HALF_EARTH_CIRCUMFERENCE) {
+      LatLon[] points = new LatLon[5];
+      points[0] = new LatLon(-90.0, -180.0);
+      points[1] = new LatLon(90.0, -180.0);
+      points[2] = new LatLon(90.0, 180.0);
+      points[3] = new LatLon(-90.0, 180.0);
+      points[4] = points[0];
+      return points;
+    }
+    // plus one to add closing point
+    LatLon[] points = new LatLon[numberOfPoints + 1];
+    for (int i = 0; i < 360; i += (360 / numberOfPoints)) {
+      points[i] = DistanceUtils.getPointOnGreatCircle(this.center.getLat(),
+          this.center.getLon(), radius, i);
+    }
+
+    points[numberOfPoints] = points[0];
+
+    return points;
+  }
+
+  /**
+   * Calculates the rectangular region enclosing the circular search region.
+   * 
+   * @param numberOfPoints
+   *          the number of points used to estimate the circular search region
+   * @return Java Rectangle2D object that bounds the circlar search region
+   */
+  public Rectangle2D getRectangularRegionApproximation(int numberOfPoints) {
+    if (this.radius >= DistanceUtils.HALF_EARTH_CIRCUMFERENCE) {
+      return new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0);
+    }
+    int numberOfCrossOvers = 0;
+
+    Path2D path = new Path2D.Double();
+    LatLon initPT = DistanceUtils.getPointOnGreatCircle(this.center.getLat(),
+        this.center.getLon(), this.radius, 0);
+    path.moveTo(initPT.getShiftedLon(), initPT.getShiftedLat());
+
+    LatLon currPT = initPT;
+    for (int i = 1; i < 360; i++) {
+
+      LatLon pt = DistanceUtils.getPointOnGreatCircle(this.center.getLat(),
+          this.center.getLon(), this.radius, i);
+      path.lineTo(pt.getShiftedLon(), pt.getShiftedLat());
+
+      if (dateLineCrossOver(currPT.getNormLon(), pt.getNormLon())) {
+        numberOfCrossOvers++;
+      }
+      currPT = pt;
+    }
+    if (dateLineCrossOver(initPT.getNormLon(), currPT.getNormLon())) {
+      numberOfCrossOvers++;
+    }
+
+    /**
+     * If the path crosses the dateline once, it's a special case, so take care
+     * of it differently. It will need to include areas around the pole.
+     */
+    if (numberOfCrossOvers == 1) {
+      Rectangle2D r = path.getBounds2D();
+      Rectangle2D lowerHalf = new Rectangle2D.Double(0.0, 0.0, 360.0, r
+          .getMaxY());
+      if (lowerHalf.contains(this.center.getShiftedLon(), this.center
+          .getShiftedLat())) {
+        return lowerHalf;
+      } else {
+        return new Rectangle2D.Double(0.0, r.getMinY(), 360.0, 180.0 - r
+            .getMinY());
+      }
+    }
+
+    if (path.contains(this.center.getShiftedLon(), this.center.getShiftedLat())) {
+      Rectangle2D r = path.getBounds2D();
+      if ((r.getMaxX() - r.getMinX()) > 359.0) {
+        return new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0);
+      } else if (r.getMinX() < 0 || r.getMaxX() > 360.0) {
+        /**
+         * For circles that crosses the dateline instead of splitting in half
+         * and having to go down the tree twice, for first version span
+         * longitude 360.0 and use the exact height of the box
+         */
+        return new Rectangle2D.Double(0.0, r.getY(), 360.0, r.getHeight());
+      } else {
+        return path.getBounds2D();
+      }
+    } else {
+      Area pathArea = new Area(path);
+      Area wholeMap = new Area(new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0));
+      wholeMap.subtract(pathArea);
+      return wholeMap.getBounds2D();
+    }
+  }
+
+  /**
+   * Returns true if the line segment connecting the two specified longitudes
+   * crosses the international dateline.
+   * 
+   * @param longitude1
+   *          first longitude
+   * @param longitude2
+   *          second longitude
+   * @return true if the line segment crosses the internation dateline, false
+   *         otherwise
+   */
+  private boolean dateLineCrossOver(double longitude1, double longitude2) {
+    if (Math.abs(longitude1 - longitude2) > 180.0)
+      return true;
+    return false;
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonRect.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonRect.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonRect.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/core/LatLonRect.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,99 @@
+/**
+ * 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;
+
+//JDK imports
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Represents a 2D rectangle on earth surface specified by lower left and upper
+ * right coordinates.
+ * 
+ */
+public class LatLonRect {
+  private LatLon lowerLeft;
+  private LatLon upperRight;
+
+  /**
+   * Creates representation of 2D rectangle.
+   * 
+   * @param lowerLeft
+   *          lower left coordinatee of rectangle
+   * @param upperRight
+   *          upper right coordinate of rectangle
+   */
+  public LatLonRect(LatLon lowerLeft, LatLon upperRight) {
+    this.lowerLeft = lowerLeft;
+    this.upperRight = upperRight;
+  }
+
+  /**
+   * Returns true if the rectangle crosses the international dateline.
+   * 
+   * @return true if the rectangle crosses the international dateline, false
+   *         otherwise
+   */
+  private boolean crossesDateLine() {
+    if (lowerLeft.getLon() > upperRight.getLon()) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Calculates the rectangles that makes up this rectangle. Need to do some
+   * calculation because rectangular region can cross the dateline and will need
+   * to be represented as two separate rectangles
+   * 
+   * @return an array of Java Rectangle2D representing this rectangular region
+   *         on the earth surface
+   */
+  public Rectangle2D[] getJavaRectangles() {
+    Rectangle2D[] rect;
+    if (crossesDateLine()) {
+      rect = new Rectangle2D[2];
+
+      LatLonRect west = new LatLonRect(new LatLon(this.lowerLeft.getLat(),
+          -180.0), new LatLon(this.upperRight.getLat(), this.upperRight
+          .getLon()));
+      LatLonRect east = new LatLonRect(new LatLon(this.lowerLeft.getLat(),
+          this.lowerLeft.getLon()), new LatLon(this.upperRight.getLat(), 180.0));
+      rect[0] = getJavaRectangle(west);
+      rect[1] = getJavaRectangle(east);
+    } else {
+      rect = new Rectangle2D[1];
+      rect[0] = getJavaRectangle(this);
+    }
+    return rect;
+  }
+
+  /**
+   * Creates a Java Rectangle2D of the specified LatLonRect.
+   * 
+   * @param rect
+   *          specified LatLonRect
+   * @return Java Rectangle2D
+   */
+  private Rectangle2D getJavaRectangle(LatLonRect rect) {
+    return new Rectangle2D.Double(rect.lowerLeft.getShiftedLon(),
+        rect.lowerLeft.getShiftedLat(), rect.upperRight.getShiftedLon()
+            - rect.lowerLeft.getShiftedLon(), rect.upperRight.getShiftedLat()
+            - rect.lowerLeft.getShiftedLat());
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/distance/DistanceUtils.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/distance/DistanceUtils.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/distance/DistanceUtils.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/distance/DistanceUtils.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,93 @@
+/**
+ * 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.distance;
+
+// SIS imports
+import org.apache.sis.core.LatLon;
+
+/**
+ * Class to calculate distances on earth surface. Actual calculation code very
+ * similar to Apache SIS but refractor to allow use of custom classes.
+ * 
+ */
+public class DistanceUtils {
+
+  public static final int EARTH_RADIUS = 6371; // in km
+  public static final double HALF_EARTH_CIRCUMFERENCE = 20037.58; // in km
+
+  /**
+   * Returns a coordinate on the great circle at the specified bearing.
+   * 
+   * @param latitude
+   *          the latitude of center of circle
+   * @param longtitude
+   *          the longitude of center of circle
+   * @param d
+   *          the distance from the center
+   * @param bearing
+   *          the great circle bearing
+   * @return a coordinate at the specified bearing
+   */
+  public static LatLon getPointOnGreatCircle(double latitude, double longitude,
+      double d, double bearing) {
+    double angularDistance = d / EARTH_RADIUS;
+
+    double lon1 = Math.toRadians(longitude);
+    double lat1 = Math.toRadians(latitude);
+
+    double cosLat = Math.cos(lat1);
+    double sinLat = Math.sin(lat1);
+
+    double sinD = Math.sin(angularDistance);
+    double cosD = Math.cos(angularDistance);
+    double brng = Math.toRadians(bearing);
+
+    double lat2 = Math.asin((sinLat * cosD) + (cosLat * sinD * Math.cos(brng)));
+    double lon2 = lon1
+        + Math.atan2(Math.sin(brng) * sinD * cosLat, cosD - sinLat
+            * Math.sin(lat2));
+
+    return new LatLon(Math.toDegrees(lat2), Math.toDegrees(lon2));
+  }
+
+  /**
+   * Calculates haversine (great circle) distance between two lat/lon
+   * coordinates.
+   * 
+   * @param latitude1
+   *          latitude of first coordinate
+   * @param longitude1
+   *          longitude of first coordinate
+   * @param latitude2
+   *          latitude of second coordinate
+   * @param longitude2
+   *          longitude of second coordinate
+   * @return great circle distance between specified lat/lon coordinates
+   */
+  public static double getHaversineDistance(double latitude1,
+      double longitude1, double latitude2, double longitude2) {
+    double longRadian1 = Math.toRadians(longitude1);
+    double latRadian1 = Math.toRadians(latitude1);
+    double longRadian2 = Math.toRadians(longitude2);
+    double latRadian2 = Math.toRadians(latitude2);
+    double angularDistance = Math.acos(Math.sin(latRadian1)
+        * Math.sin(latRadian2) + Math.cos(latRadian1) * Math.cos(latRadian2)
+        * Math.cos(longRadian1 - longRadian2));
+    return EARTH_RADIUS * angularDistance;
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/GeoRSSData.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/GeoRSSData.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/GeoRSSData.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/GeoRSSData.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,187 @@
+/**
+ * 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.storage;
+
+//JDK imports
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.HashMap;
+
+//SIS imports
+import org.apache.sis.core.LatLon;
+
+//ROME imports
+import com.sun.syndication.feed.module.georss.GeoRSSModule;
+import com.sun.syndication.feed.rss.Item;
+
+/**
+ * Implements QuadTreeData to store GeoRSS items into quad tree. Provides
+ * methods to save and load GeoRSS items to and from file.
+ * 
+ */
+public class GeoRSSData implements QuadTreeData {
+
+	private String filename;
+	private LatLon latLon;
+
+	/**
+	 * Creates a GeoRSSData object that stores the name of the file that the
+	 * entry's information is written to and the geo location of the entry.
+	 * 
+	 * @param filename
+	 *            filename where rss entry's info is stored
+	 * @param latLon
+	 *            geo location of the entry
+	 */
+	public GeoRSSData(String filename, LatLon latLon) {
+		this.filename = filename;
+		this.latLon = latLon;
+	}
+
+	/**
+	 * Returns the Java 2D x-coordinate for the longitude.
+	 * 
+	 * @return the Java 2D x-coordinate
+	 */
+	public double getX() {
+		return latLon.getShiftedLon();
+	}
+
+	/**
+	 * Returns the Java 2D y-coordinate for the latitude.
+	 * 
+	 * @return the Java 2D y-coordinate
+	 */
+	public double getY() {
+		return latLon.getShiftedLat();
+	}
+
+	/**
+	 * Returns the latitude.
+	 * 
+	 * @return the latitude
+	 */
+	public double getLat() {
+		return this.latLon.getLat();
+	}
+
+	/**
+	 * Returns the longitude.
+	 * 
+	 * @return the longitude
+	 */
+	public double getLon() {
+		return this.latLon.getLon();
+	}
+
+	/**
+	 * Returns the name of the file where the entry's info is saved.
+	 * 
+	 * @return the name of the file where the entry's info is saved
+	 */
+	public String getFileName() {
+		return this.filename;
+	}
+
+	/**
+	 * Saves the GeoRSS entry to file.
+	 * 
+	 * @param item
+	 *            the Item object from Java ROME API containing the GeoRSS entry
+	 * @param geoRSSModule
+	 *            the Java ROME API GeoRSSModule to parse geo location
+	 * @param directory
+	 *            the path of the directory in which to save the file
+	 */
+	public void saveToFile(Item item, GeoRSSModule geoRSSModule,
+			String directory) {
+		try {
+			BufferedWriter writer = new BufferedWriter(new FileWriter(directory
+					+ filename));
+			if (item.getTitle() != null) {
+				writer.write("title;" + item.getTitle().replace('\n', ' '));
+				writer.newLine();
+			}
+			if (item.getLink() != null) {
+				writer.write("link;" + item.getLink().replace('\n', ' '));
+				writer.newLine();
+			}
+			if (item.getSource() != null) {
+				writer.write("source;"
+						+ item.getSource().getValue().replace('\n', ' '));
+				writer.newLine();
+			}
+			if (item.getAuthor() != null) {
+				writer.write("author;" + item.getAuthor().replace('\n', ' '));
+				writer.newLine();
+			}
+			if (item.getDescription() != null) {
+				writer.write("description;"
+						+ item.getDescription().getValue().replace('\n', ' '));
+				writer.newLine();
+			}
+			writer.write("pubDate;" + item.getPubDate().toString());
+			writer.newLine();
+			writer.write("lat;" + geoRSSModule.getPosition().getLatitude());
+			writer.newLine();
+			writer.write("lon;" + geoRSSModule.getPosition().getLongitude());
+			writer.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Reads the file that contains the GeoRSS entry's information and returns a
+	 * HashMap of key, value pairs where the key is the name of the element e.g.
+	 * title, author.
+	 * 
+	 * @param fullFileName
+	 *            the full path to the file
+	 * @return HashMap where the key is the name of the element and the value is
+	 *         the data inside the element's tag
+	 */
+	public static HashMap<String, String> loadFromFile(String fullFileName) {
+		HashMap<String, String> map = new HashMap<String, String>();
+		try {
+			BufferedReader reader = new BufferedReader(new FileReader(
+					fullFileName));
+			String line = "";
+			while ((line = reader.readLine()) != null) {
+				int delimIndex = line.indexOf(';');
+				if (delimIndex != -1)
+					map.put(line.substring(0, delimIndex), line.substring(
+							delimIndex + 1, line.length()));
+			}
+			reader.close();
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return map;
+
+	}
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/NodeType.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/NodeType.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/NodeType.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/NodeType.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,27 @@
+/**
+ * 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.storage;
+
+/**
+ * Enum to represent node type of quad tree. Black means node contains data.
+ * White means node is empty. Gray means node is parent.
+ * 
+ */
+public enum NodeType {
+  BLACK, WHITE, GRAY
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTree.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTree.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTree.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTree.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,541 @@
+/**
+ * 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.storage;
+
+//JDK imports
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+//SIS imports
+import org.apache.sis.core.LatLon;
+import org.apache.sis.core.LatLonPointRadius;
+import org.apache.sis.core.LatLonRect;
+import org.apache.sis.distance.DistanceUtils;
+
+/**
+ * Implementation of Quad Tree Index. Insertion algorithm implemented based on
+ * design of quad tree index in H. Samet, The Design and Analysis of Spatial
+ * Data Structures. Massachusetts: Addison Wesley Publishing Company, 1989.
+ * 
+ */
+public class QuadTree {
+
+  // assume map is shifted to be in positive coordinate
+  private static final double EARTH_MIN_X = 0;
+  private static final double EARTH_MIN_Y = 0;
+  private static final double EARTH_MAX_X = 360;
+  private static final double EARTH_MAX_Y = 180;
+  private static final double EARTH_MID_X = (EARTH_MAX_X - EARTH_MIN_X) / 2;
+  private static final double EARTH_MID_Y = (EARTH_MAX_Y - EARTH_MIN_Y) / 2;
+  private static final double[] xf = new double[] { -0.25, 0.25, -0.25, 0.25 };
+  private static final double[] yf = new double[] { 0.25, 0.25, -0.25, -0.25 };
+
+  private QuadTreeNode root;
+  private int size;
+  private int nodeSize;
+
+  private int maxDepth;
+  private int capacity;
+
+  /**
+   * Creates a quad tree.
+   * 
+   * @param capacity
+   *          the capacity of each node in the quad tree
+   * @param maxDepth
+   *          the maximum depth of the tree
+   */
+  public QuadTree(int capacity, int maxDepth) {
+    this.size = 0;
+    this.nodeSize = 0;
+    this.capacity = capacity;
+    this.maxDepth = maxDepth;
+    this.root = new QuadTreeNode(NodeType.GRAY, this.nodeSize);
+  }
+
+  /**
+   * Creates a quad tree with 0 capacity and depth. Useful when user wants to
+   * set the capacity and depth after quad tree construction.
+   */
+  public QuadTree() {
+    this.size = 0;
+    this.nodeSize = 0;
+    this.capacity = 0;
+    this.maxDepth = 0;
+    this.root = new QuadTreeNode(NodeType.GRAY, this.nodeSize);
+  }
+
+  /**
+   * Inserts the specified data into the quad tree.
+   * 
+   * @param data
+   *          specified data to be inserted
+   * @return true if the data was inserted into the quad tree; false if data
+   *         cannot be inserted because the capacity of the node has been
+   *         exceeded and the depth of the tree will be exceeded if we insert
+   *         this data
+   */
+  public boolean insert(QuadTreeData data) {
+    if (insert(data, this.root)) {
+      this.size++;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Calculates the quadrant that the data lies in.
+   * 
+   * @param data
+   *          specifed data
+   * @param x
+   *          the x-midpoint of the current node
+   * @param y
+   *          the y-midpoint of the current node
+   * @return the quadrant that the data lies in
+   */
+  private Quadrant compare(final QuadTreeData data, final double x,
+      final double y) {
+    if (data.getX() < x)
+      if (data.getY() < y)
+        return Quadrant.SW;
+      else
+        return Quadrant.NW;
+    else if (data.getY() < y)
+      return Quadrant.SE;
+    else
+      return Quadrant.NE;
+  }
+
+  /**
+   * Inserts the data into the quad tree with the specified root.
+   * 
+   * @param data
+   *          data to be inserted
+   * @param root
+   *          root of quadtree
+   * @return true if data was inserted, false otherwise
+   */
+  private boolean insert(final QuadTreeData data, final QuadTreeNode root) {
+    int currentDepth = 0;
+
+    QuadTreeNode r = root;
+    double x = EARTH_MID_X;
+    double y = EARTH_MID_Y;
+    double lx = EARTH_MAX_X;
+    double ly = EARTH_MAX_Y;
+
+    QuadTreeNode u;
+    QuadTreeNode t;
+    Quadrant q, uq;
+    t = r;
+    q = compare(data, x, y);
+    currentDepth++;
+    while (t.getChild(q) != null
+        && t.getChild(q).getNodeType() == NodeType.GRAY) {
+      t = t.getChild(q);
+      x = x + xf[q.index()] * lx;
+      lx = lx / 2.0;
+      y = y + yf[q.index()] * ly;
+      ly = ly / 2.0;
+      q = compare(data, x, y);
+      currentDepth++;
+
+      if (currentDepth > this.maxDepth)
+        return false;
+    }
+    if (t.getChild(q) == null) {
+      QuadTreeNode newlyCreated = new QuadTreeNode(++this.nodeSize,
+          this.capacity);
+      newlyCreated.addData(data);
+      t.setChild(newlyCreated, q);
+    } else {
+      u = t.getChild(q);
+      if (u.getCount() < this.capacity) {
+        u.addData(data);
+        return true;
+      } else {
+        QuadTreeData[] originalData = u.getData();
+
+        if (!maxDepthExceeded(originalData, data, x, y, lx, ly, q, currentDepth)) {
+          t.setChild(new QuadTreeNode(NodeType.GRAY, u.getId()), q);
+          t = t.getChild(q);
+          x = x + xf[q.index()] * lx;
+          lx = lx / 2.0;
+
+          y = y + yf[q.index()] * ly;
+          ly = ly / 2.0;
+          q = compare(data, x, y);
+          currentDepth++;
+          if (currentDepth > this.maxDepth)
+            return false;
+          while (isSimilarQuad(originalData, data, x, y, q)) {
+            t.setChild(new QuadTreeNode(NodeType.GRAY, ++this.nodeSize), q);
+            t = t.getChild(q);
+            x = x + xf[q.index()] * lx;
+            lx = lx / 2.0;
+
+            y = y + yf[q.index()] * ly;
+            ly = ly / 2.0;
+            q = compare(data, x, y);
+            currentDepth++;
+            if (currentDepth > this.maxDepth)
+              return false;
+          }
+
+          if (t.getChild(q) == null) {
+            QuadTreeNode newlyCreated = new QuadTreeNode(++this.nodeSize,
+                this.capacity);
+            newlyCreated.addData(data);
+            t.setChild(newlyCreated, q);
+          } else {
+            t.getChild(q).addData(data);
+          }
+
+          for (int i = 0; i < originalData.length; i++) {
+            uq = compare(originalData[i], x, y);
+            if (t.getChild(uq) == null) {
+              QuadTreeNode newlyCreated = new QuadTreeNode(++this.nodeSize,
+                  this.capacity);
+              newlyCreated.addData(originalData[i]);
+              t.setChild(newlyCreated, uq);
+            } else {
+              t.getChild(uq).addData(originalData[i]);
+            }
+          }
+        } else {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Determines if insertion of the data will cause the depth of the quad tree
+   * to be exceeded.
+   * 
+   * @param originalData
+   *          array containing the data that is already stored in the node
+   * @param toBeAddedData
+   *          data to be added to the node
+   * @param originalX
+   *          the x-midpoint of the node
+   * @param originalY
+   *          the y-midpoint of the node
+   * @param originalLX
+   *          the width of the node
+   * @param originalLY
+   *          the height of the node
+   * @param originalQ
+   *          the quadrant that all data currently lies in
+   * @param depth
+   *          the current depth
+   * @return true if the depth will be exceeded, false otherwise
+   */
+  private boolean maxDepthExceeded(final QuadTreeData[] originalData,
+      final QuadTreeData toBeAddedData, final double originalX,
+      final double originalY, final double originalLX, final double originalLY,
+      final Quadrant originalQ, final int depth) {
+    int currentDepth = depth;
+    double x = originalX;
+    double lx = originalLX;
+    double y = originalY;
+    double ly = originalLY;
+    Quadrant q = originalQ;
+
+    x = x + xf[q.index()] * lx;
+    lx = lx / 2.0;
+
+    y = y + yf[q.index()] * ly;
+    ly = ly / 2.0;
+    q = compare(toBeAddedData, x, y);
+    currentDepth++;
+    if (currentDepth > this.maxDepth)
+      return true;
+    while (isSimilarQuad(originalData, toBeAddedData, x, y, q)) {
+      x = x + xf[q.index()] * lx;
+      lx = lx / 2.0;
+
+      y = y + yf[q.index()] * ly;
+      ly = ly / 2.0;
+      q = compare(toBeAddedData, x, y);
+      currentDepth++;
+      if (currentDepth > this.maxDepth)
+        return true;
+    }
+    return false;
+  }
+
+  /**
+   * Returns true if all data (new and old) have to be stored in the same
+   * quadrant of the node.
+   * 
+   * @param originalData
+   *          array of data already stored in the node
+   * @param newNode
+   *          the node in which data is stored
+   * @param x
+   *          the x midpoint of the node
+   * @param y
+   *          the y midpoint of the node
+   * @param q
+   *          the quadrant that the new data lies in
+   * @return true if all data lies in the quadrant, false otherwise
+   */
+  private boolean isSimilarQuad(QuadTreeData[] originalData,
+      QuadTreeData newNode, double x, double y, Quadrant q) {
+    Quadrant quad = compare(originalData[0], x, y);
+    if (q != quad)
+      return false;
+    for (int i = 1; i < originalData.length; i++) {
+      if (compare(originalData[i], x, y) != quad)
+        return false;
+    }
+    return true;
+  }
+
+  /**
+   * Performs point radius search.
+   * 
+   * @param point
+   *          the center of the circular region
+   * @param radiusKM
+   *          the radius in kilometers
+   * @return a list of QuadTreeData that are within the given radius from the
+   *         point
+   */
+  public List<QuadTreeData> queryByPointRadius(final LatLon point,
+      final double radiusKM) {
+    LatLonPointRadius pr = new LatLonPointRadius(point, radiusKM);
+    return queryByPointRadius(point, radiusKM, this.root,
+        new Rectangle2D.Double(EARTH_MIN_X, EARTH_MIN_Y, EARTH_MAX_X,
+            EARTH_MAX_Y), pr.getRectangularRegionApproximation(360));
+  }
+
+  private List<QuadTreeData> queryByPointRadius(final LatLon point,
+      final double radiusKM, final QuadTreeNode node,
+      final Rectangle2D nodeRegion, final Rectangle2D searchRegion) {
+    List<QuadTreeData> matches = new ArrayList<QuadTreeData>();
+    if (node == null) {
+      return matches;
+    } else if (node.getNodeType() != NodeType.GRAY) {
+      if (node.getNodeType() == NodeType.WHITE)
+        return matches;
+      else {
+        QuadTreeData[] data = node.getData();
+        for (int i = 0; i < node.getCount(); i++) {
+          if (DistanceUtils.getHaversineDistance(data[i].getLat(), data[i]
+              .getLon(), point.getLat(), point.getLon()) <= radiusKM) {
+            matches.add(data[i]);
+          }
+        }
+        return matches;
+      }
+
+    } else {
+      Rectangle2D swRectangle = new Rectangle2D.Double(nodeRegion.getX(),
+          nodeRegion.getY(), nodeRegion.getWidth() / 2,
+          nodeRegion.getHeight() / 2);
+      Rectangle2D seRectangle = new Rectangle2D.Double(nodeRegion.getX()
+          + nodeRegion.getWidth() / 2, nodeRegion.getY(),
+          nodeRegion.getWidth() / 2, nodeRegion.getHeight() / 2);
+      Rectangle2D nwRectangle = new Rectangle2D.Double(nodeRegion.getX(),
+          nodeRegion.getY() + nodeRegion.getHeight() / 2,
+          nodeRegion.getWidth() / 2, nodeRegion.getHeight() / 2);
+      Rectangle2D neRectangle = new Rectangle2D.Double(nodeRegion.getX()
+          + nodeRegion.getWidth() / 2, nodeRegion.getY()
+          + nodeRegion.getHeight() / 2, nodeRegion.getWidth() / 2, nodeRegion
+          .getHeight() / 2);
+
+      if (swRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> swMatches = queryByPointRadius(point, radiusKM, node
+            .getChild(Quadrant.SW), swRectangle, searchRegion);
+        for (QuadTreeData q : swMatches) {
+          matches.add(q);
+        }
+      }
+      if (seRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> seMatches = queryByPointRadius(point, radiusKM, node
+            .getChild(Quadrant.SE), seRectangle, searchRegion);
+        for (QuadTreeData q : seMatches) {
+          matches.add(q);
+        }
+      }
+      if (nwRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> nwMatches = queryByPointRadius(point, radiusKM, node
+            .getChild(Quadrant.NW), nwRectangle, searchRegion);
+        for (QuadTreeData q : nwMatches) {
+          matches.add(q);
+        }
+      }
+      if (neRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> neMatches = queryByPointRadius(point, radiusKM, node
+            .getChild(Quadrant.NE), neRectangle, searchRegion);
+        for (QuadTreeData q : neMatches) {
+          matches.add(q);
+        }
+      }
+    }
+    return matches;
+  }
+
+  /**
+   * Performs bounding box search.
+   * 
+   * @param searchRegion
+   *          LatLonRect representing the rectangular search region
+   * @return a list of QuadTreeData that are within the given radius from the
+   *         point
+   */
+  public List<QuadTreeData> queryByBoundingBox(final LatLonRect searchRegion) {
+    Rectangle2D rectArray[] = searchRegion.getJavaRectangles();
+    if (rectArray.length == 1) {
+      // traverse tree once because region does not cross dateline
+      return queryByBoundingBox(rectArray[0]);
+
+    } else if (rectArray.length == 2) {
+      // traverse tree twice since region crosses dateline
+      List<QuadTreeData> firstMatches = queryByBoundingBox(rectArray[0]);
+      List<QuadTreeData> secondMatches = queryByBoundingBox(rectArray[1]);
+
+      // merge two lists and return
+      for (QuadTreeData q : secondMatches) {
+        if (!firstMatches.contains(q)) {
+          firstMatches.add(q);
+        }
+      }
+      return firstMatches;
+    } else {
+      return null;
+    }
+  }
+
+  private List<QuadTreeData> queryByBoundingBox(final Rectangle2D searchRegion) {
+    return queryByBoundingBox(this.root, new Rectangle2D.Double(EARTH_MIN_X,
+        EARTH_MIN_Y, EARTH_MAX_X, EARTH_MAX_Y), searchRegion);
+  }
+
+  private List<QuadTreeData> queryByBoundingBox(final QuadTreeNode node,
+      final Rectangle2D nodeRegion, final Rectangle2D searchRegion) {
+
+    List<QuadTreeData> matches = new ArrayList<QuadTreeData>();
+    if (node == null) {
+      return matches;
+    } else if (node.getNodeType() != NodeType.GRAY) {
+      if (node.getNodeType() == NodeType.WHITE)
+        return matches;
+      else {
+        QuadTreeData[] data = node.getData();
+        for (int i = 0; i < node.getCount(); i++) {
+          if (searchRegion.contains(data[i].getX(), data[i].getY())) {
+            matches.add(data[i]);
+          }
+        }
+        return matches;
+      }
+
+    } else {
+      Rectangle2D swRectangle = new Rectangle2D.Double(nodeRegion.getX(),
+          nodeRegion.getY(), nodeRegion.getWidth() / 2,
+          nodeRegion.getHeight() / 2);
+      Rectangle2D seRectangle = new Rectangle2D.Double(nodeRegion.getX()
+          + nodeRegion.getWidth() / 2, nodeRegion.getY(),
+          nodeRegion.getWidth() / 2, nodeRegion.getHeight() / 2);
+      Rectangle2D nwRectangle = new Rectangle2D.Double(nodeRegion.getX(),
+          nodeRegion.getY() + nodeRegion.getHeight() / 2,
+          nodeRegion.getWidth() / 2, nodeRegion.getHeight() / 2);
+      Rectangle2D neRectangle = new Rectangle2D.Double(nodeRegion.getX()
+          + nodeRegion.getWidth() / 2, nodeRegion.getY()
+          + nodeRegion.getHeight() / 2, nodeRegion.getWidth() / 2, nodeRegion
+          .getHeight() / 2);
+
+      if (swRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> swMatches = queryByBoundingBox(node
+            .getChild(Quadrant.SW), swRectangle, searchRegion);
+        for (QuadTreeData q : swMatches) {
+          matches.add(q);
+        }
+      }
+      if (seRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> seMatches = queryByBoundingBox(node
+            .getChild(Quadrant.SE), seRectangle, searchRegion);
+        for (QuadTreeData q : seMatches) {
+          matches.add(q);
+        }
+      }
+      if (nwRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> nwMatches = queryByBoundingBox(node
+            .getChild(Quadrant.NW), nwRectangle, searchRegion);
+        for (QuadTreeData q : nwMatches) {
+          matches.add(q);
+        }
+      }
+      if (neRectangle.intersects(searchRegion)) {
+        List<QuadTreeData> neMatches = queryByBoundingBox(node
+            .getChild(Quadrant.NE), neRectangle, searchRegion);
+        for (QuadTreeData q : neMatches) {
+          matches.add(q);
+        }
+      }
+    }
+    return matches;
+  }
+
+  public int size() {
+    return this.size;
+  }
+
+  public QuadTreeNode getRoot() {
+    return this.root;
+  }
+
+  public void setSize(int size) {
+    this.size = size;
+  }
+
+  public int getSize() {
+    return this.size;
+  }
+
+  public void setNodeSize(int nodeSize) {
+    this.nodeSize = nodeSize;
+  }
+
+  public int getNodeSize() {
+    return this.nodeSize;
+  }
+
+  public int getCapacity() {
+    return this.capacity;
+  }
+
+  public int getDepth() {
+    return this.maxDepth;
+  }
+
+  public void setCapacity(int capacity) {
+    this.capacity = capacity;
+  }
+
+  public void setDepth(int depth) {
+    this.maxDepth = depth;
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeData.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeData.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeData.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeData.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,61 @@
+/**
+ * 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.storage;
+
+/**
+ * Interface representing data stored in quad tree. All data to be stored in
+ * quad tree must implement this interface, so that quad tree can access
+ * location and store name of file in which data is saved.
+ * 
+ */
+public interface QuadTreeData {
+  /**
+   * Returns the Java 2D x-coordinate for the longitude.
+   * 
+   * @return the Java 2D x-coordinate
+   */
+  public double getX();
+
+  /**
+   * Returns the Java 2D y-coordinate for the latitude.
+   * 
+   * @return the Java 2D y-coordinate
+   */
+  public double getY();
+
+  /**
+   * Returns the latitude.
+   * 
+   * @return the latitude
+   */
+  public double getLat();
+
+  /**
+   * Returns the longitude.
+   * 
+   * @return the longitude
+   */
+  public double getLon();
+
+  /**
+   * Returns the name of the file where the entry's info is saved.
+   * 
+   * @return the name of the file where the entry's info is saved
+   */
+  public String getFileName();
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeNode.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeNode.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeNode.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeNode.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,178 @@
+/**
+ * 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.storage;
+
+/**
+ * Implementation of quad tree node.
+ * 
+ */
+public class QuadTreeNode {
+
+  private QuadTreeData[] data;
+  private QuadTreeNode nw;
+  private QuadTreeNode ne;
+  private QuadTreeNode se;
+  private QuadTreeNode sw;
+  private NodeType type;
+  private int id;
+  private int capacity;
+  private int dataCount;
+
+  /**
+   * Constructs a quad tree node that can store data
+   * 
+   * @param id
+   *          node's id
+   * @param capacity
+   *          node's capcacity
+   */
+  public QuadTreeNode(int id, int capacity) {
+    this.capacity = capacity;
+    this.dataCount = 0;
+    this.data = new QuadTreeData[this.capacity];
+    this.type = NodeType.BLACK;
+    this.nw = null;
+    this.ne = null;
+    this.sw = null;
+    this.se = null;
+    this.id = id;
+  }
+
+  /**
+   * Constructs a quad tree node that acts as a parent.
+   * 
+   * @param type
+   *          node's type
+   * @param id
+   *          node's id
+   */
+  public QuadTreeNode(NodeType type, int id) {
+    this.type = type;
+    this.nw = null;
+    this.ne = null;
+    this.sw = null;
+    this.se = null;
+    this.data = null;
+    this.id = id;
+  }
+
+  /**
+   * Add data to the node.
+   * 
+   * @param data
+   *          data to be added
+   */
+  public void addData(QuadTreeData data) {
+    if (this.dataCount < this.capacity) {
+      this.data[dataCount] = data;
+      this.dataCount++;
+    }
+  }
+
+  /**
+   * Gets the number of data stored in the node
+   * 
+   * @return number of data stored in the node
+   */
+  public int getCount() {
+    return this.dataCount;
+  }
+
+  /**
+   * Gets the node type.
+   * 
+   * @return node type
+   */
+  public NodeType getNodeType() {
+    return this.type;
+  }
+
+  /**
+   * Sets the node's quadrant to point to the specified child.
+   * 
+   * @param child
+   *          child of this node
+   * @param q
+   *          quadrant where the child resides
+   */
+  public void setChild(QuadTreeNode child, Quadrant q) {
+    switch (q) {
+    case NW:
+      this.nw = child;
+      break;
+    case NE:
+      this.ne = child;
+      break;
+    case SW:
+      this.sw = child;
+      break;
+    case SE:
+      this.se = child;
+      break;
+    }
+  }
+
+  /**
+   * Returns the child of this node that resides in the specified quadrant.
+   * 
+   * @param q
+   *          specified quadrant
+   * @return child in the specified quadrant
+   */
+  public QuadTreeNode getChild(Quadrant q) {
+    switch (q) {
+    case NW:
+      return this.nw;
+    case NE:
+      return this.ne;
+    case SW:
+      return this.sw;
+    case SE:
+      return this.se;
+    default:
+      return null;
+    }
+  }
+
+  /**
+   * Returns the data stored in this node.
+   * 
+   * @return data stored in this node
+   */
+  public QuadTreeData[] getData() {
+    return this.data;
+  }
+
+  /**
+   * Returns node's id.
+   * 
+   * @return node's id
+   */
+  public int getId() {
+    return this.id;
+  }
+
+  /**
+   * Returns node's capacity.
+   * 
+   * @return node's capacity
+   */
+  public int getCapacity() {
+    return this.capacity;
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeReader.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeReader.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeReader.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeReader.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,146 @@
+/**
+ * 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.storage;
+
+//JDK imports
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+//SIS imports
+import org.apache.sis.core.LatLon;
+
+/**
+ * Class to reload the quad tree index from file.
+ * 
+ */
+public class QuadTreeReader {
+
+  /**
+   * Loads the quad tree index from file.
+   * 
+   * @param directory
+   *          the directory where the index files are located
+   * @param treeConfigFile
+   *          the name of the tree configuration file
+   * @param nodeFile
+   *          the name of the root node file
+   * @return fully loaded QuadTree
+   */
+  public static QuadTree readFromFile(final String directory,
+      final String treeConfigFile, final String nodeFile) {
+    QuadTree tree = new QuadTree();
+    readConfigFromFile(tree, directory, treeConfigFile);
+    readFromFile(tree, tree.getRoot(), directory, nodeFile);
+    return tree;
+  }
+
+  private static void readConfigFromFile(QuadTree tree, String directory,
+      String treeConfigFile) {
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(directory
+          + treeConfigFile));
+      String line = "";
+      while ((line = reader.readLine()) != null) {
+        String[] tokens = line.split(";");
+        int capacity = Integer.parseInt(tokens[1]);
+        int depth = Integer.parseInt(tokens[3]);
+        tree.setCapacity(capacity);
+        tree.setDepth(depth);
+      }
+    } catch (FileNotFoundException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    } catch (NumberFormatException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+  }
+
+  private static void readFromFile(final QuadTree tree,
+      final QuadTreeNode parent, final String directory, final String filename) {
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(directory
+          + filename));
+      String line = "";
+      while ((line = reader.readLine()) != null) {
+        String[] tokens = line.split(":");
+        Quadrant quadrant = Quadrant.getQuadrant(Integer.parseInt(tokens[0]));
+        String nodetype = tokens[1];
+        int id = Integer.parseInt(tokens[2]);
+
+        if (nodetype.equals("GRAY")) {
+          parent.setChild(new QuadTreeNode(NodeType.GRAY, id), quadrant);
+          tree.setNodeSize(tree.getNodeSize() + 1);
+        } else {
+          int capacity = Integer.parseInt(tokens[3]);
+          parent.setChild(new QuadTreeNode(id, capacity), quadrant);
+          for (int i = 4; i < tokens.length; i++) {
+            String[] dataTokens = tokens[i].split(";");
+            double lat = Double.parseDouble(dataTokens[0]);
+            double lon = Double.parseDouble(dataTokens[1]);
+            parent.getChild(quadrant).addData(
+                new GeoRSSData(dataTokens[2], new LatLon(lat, lon)));
+            tree.setSize(tree.getSize() + 1);
+          }
+          tree.setNodeSize(tree.getNodeSize() + 1);
+        }
+
+      }
+      reader.close();
+
+      if (parent.getChild(Quadrant.NW) != null
+          && parent.getChild(Quadrant.NW).getNodeType() == NodeType.GRAY) {
+        readFromFile(tree, parent.getChild(Quadrant.NW), directory, "node_"
+            + parent.getChild(Quadrant.NW).getId() + ".txt");
+      }
+
+      if (parent.getChild(Quadrant.NE) != null
+          && parent.getChild(Quadrant.NE).getNodeType() == NodeType.GRAY) {
+        readFromFile(tree, parent.getChild(Quadrant.NE), directory, "node_"
+            + parent.getChild(Quadrant.NE).getId() + ".txt");
+      }
+
+      if (parent.getChild(Quadrant.SW) != null
+          && parent.getChild(Quadrant.SW).getNodeType() == NodeType.GRAY) {
+        readFromFile(tree, parent.getChild(Quadrant.SW), directory, "node_"
+            + parent.getChild(Quadrant.SW).getId() + ".txt");
+      }
+
+      if (parent.getChild(Quadrant.SE) != null
+          && parent.getChild(Quadrant.SE).getNodeType() == NodeType.GRAY) {
+        readFromFile(tree, parent.getChild(Quadrant.SE), directory, "node_"
+            + parent.getChild(Quadrant.SE).getId() + ".txt");
+      }
+
+    } catch (FileNotFoundException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (NumberFormatException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeWriter.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeWriter.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeWriter.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/QuadTreeWriter.java Wed Aug 18 03:21:43 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.storage;
+
+//JDK imports
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Class to save the quad tree index from file.
+ * 
+ */
+public class QuadTreeWriter {
+
+  /**
+   * Writes the entire quad tree index to file with each node in saved in a
+   * separate file.
+   * 
+   * @param tree
+   * @param directory
+   */
+  public static void writeTreeToFile(QuadTree tree, String directory) {
+    writeTreeConfigsToFile(tree, directory);
+    writeNodeToFile(tree.getRoot(), directory);
+  }
+
+  private static void writeTreeConfigsToFile(QuadTree tree, String directory) {
+    try {
+      BufferedWriter writer = new BufferedWriter(new FileWriter(directory
+          + "tree_config.txt"));
+      writer.write("capacity;" + tree.getCapacity() + ";depth;"
+          + tree.getDepth());
+      writer.newLine();
+      writer.close();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+  }
+
+  private static void writeNodeToFile(QuadTreeNode node, String directory) {
+    try {
+      BufferedWriter writer = new BufferedWriter(new FileWriter(directory
+          + "node_" + node.getId() + ".txt"));
+
+      if (node.getNodeType() == NodeType.GRAY) {
+        if (node.getChild(Quadrant.NW) != null) {
+          writer.write(getQuadTreeDataString(Quadrant.NW, node
+              .getChild(Quadrant.NW)));
+          writer.newLine();
+        }
+
+        if (node.getChild(Quadrant.NE) != null) {
+          writer.write(getQuadTreeDataString(Quadrant.NE, node
+              .getChild(Quadrant.NE)));
+          writer.newLine();
+        }
+
+        if (node.getChild(Quadrant.SW) != null) {
+          writer.write(getQuadTreeDataString(Quadrant.SW, node
+              .getChild(Quadrant.SW)));
+          writer.newLine();
+        }
+
+        if (node.getChild(Quadrant.SE) != null) {
+          writer.write(getQuadTreeDataString(Quadrant.SE, node
+              .getChild(Quadrant.SE)));
+          writer.newLine();
+        }
+      }
+      writer.close();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    if (node.getNodeType() == NodeType.GRAY) {
+      if (node.getChild(Quadrant.NW) != null
+          && node.getChild(Quadrant.NW).getNodeType() == NodeType.GRAY) {
+        writeNodeToFile(node.getChild(Quadrant.NW), directory);
+      }
+
+      if (node.getChild(Quadrant.NE) != null
+          && node.getChild(Quadrant.NE).getNodeType() == NodeType.GRAY) {
+        writeNodeToFile(node.getChild(Quadrant.NE), directory);
+      }
+
+      if (node.getChild(Quadrant.SW) != null
+          && node.getChild(Quadrant.SW).getNodeType() == NodeType.GRAY) {
+        writeNodeToFile(node.getChild(Quadrant.SW), directory);
+      }
+
+      if (node.getChild(Quadrant.SE) != null
+          && node.getChild(Quadrant.SE).getNodeType() == NodeType.GRAY) {
+        writeNodeToFile(node.getChild(Quadrant.SE), directory);
+      }
+    }
+  }
+
+  private static String getQuadTreeDataString(Quadrant quadrant,
+      final QuadTreeNode node) {
+    StringBuffer str = new StringBuffer();
+    str.append(quadrant.index());
+    str.append(':');
+    str.append(node.getNodeType().toString());
+    str.append(':');
+    str.append(node.getId());
+    str.append(':');
+    str.append(node.getCapacity());
+    str.append(':');
+    QuadTreeData[] data = node.getData();
+    for (int i = 0; i < node.getCount(); i++) {
+      str.append(data[i].getLat());
+      str.append(';');
+      str.append(data[i].getLon());
+      str.append(';');
+      str.append(data[i].getFileName());
+      str.append(':');
+    }
+    return str.substring(0, str.length() - 1);
+  }
+}

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

Added: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/Quadrant.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/Quadrant.java?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/Quadrant.java (added)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/storage/Quadrant.java Wed Aug 18 03:21:43 2010
@@ -0,0 +1,63 @@
+/**
+ * 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.storage;
+
+/**
+ * Enum to represent the 4 quadrants of a quad tree node.
+ * 
+ */
+public enum Quadrant {
+
+  NW(0), NE(1), SW(2), SE(3);
+  private final int index;
+
+  private Quadrant(int index) {
+    this.index = index;
+  }
+
+  /**
+   * Returns the index of the quadrant.
+   * 
+   * @return index of the quadrant
+   */
+  public int index() {
+    return index;
+  }
+
+  /**
+   * Retrieves the quadrant matching specified index.
+   * 
+   * @param index
+   *          specified index
+   * @return quadrant matching specified index
+   */
+  public static Quadrant getQuadrant(int index) {
+    switch (index) {
+    case 0:
+      return NW;
+    case 1:
+      return NE;
+    case 2:
+      return SW;
+    case 3:
+      return SE;
+    default:
+      return null;
+    }
+  }
+}

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

Modified: incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/util/GeoHashUtils.java
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/util/GeoHashUtils.java?rev=986558&r1=986557&r2=986558&view=diff
==============================================================================
--- incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/util/GeoHashUtils.java (original)
+++ incubator/sis/trunk/sis-core/src/main/java/org/apache/sis/util/GeoHashUtils.java Wed Aug 18 03:21:43 2010
@@ -17,6 +17,7 @@
 
 package org.apache.sis.util;
 
+//JDK imports
 import java.util.HashMap;
 import java.util.Map;
 

Added: incubator/sis/trunk/sis-webapp/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sis/trunk/sis-webapp/pom.xml?rev=986558&view=auto
==============================================================================
--- incubator/sis/trunk/sis-webapp/pom.xml (added)
+++ incubator/sis/trunk/sis-webapp/pom.xml Wed Aug 18 03:21:43 2010
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.sis</groupId>
+    <artifactId>sis-parent</artifactId>
+    <version>0.1-SNAPSHOT</version>
+    <relativePath>../sis-parent/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>sis-webapp</artifactId>
+  <packaging>war</packaging>
+  <name>Apache SIS web services layer</name>
+  <url>http://incubator.apache.org/sis/</url>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+    </dependency>
+    <dependency>
+      <groupId>org.geonames</groupId>
+      <artifactId>georss-rome</artifactId>
+      <version>0.9.8</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sis</groupId>
+      <artifactId>sis-core</artifactId>
+      <version>0.1-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>



Mime
View raw message