content: /*
   * Copyright 2010 Alexandre Gellibert
   *
   * Licensed 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 com.beoui.geocell;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import com.beoui.geocell.model.Point;
  
  
  /**
   * Ported java version of python geocell: http://code.google.com/p/geomodel/source/browse/trunk/geo/geocell.py
   * <p>
   * Defines the notion of 'geocells' and exposes methods to operate on them.
   * <p>
   * A geocell is a hexadecimal string that defines a two dimensional rectangular
   * region inside the [-90,90] x [-180,180] latitude/longitude space. A geocell's
   * 'resolution' is its length. For most practical purposes, at high resolutions,
   * geocells can be treated as single points.
   * <p>
   * Much like geohashes (see http://en.wikipedia.org/wiki/Geohash), geocells are
   * hierarchical, in that any prefix of a geocell is considered its ancestor, with
   * geocell[:-1] being geocell's immediate parent cell.
   * <p>
   * To calculate the rectangle of a given geocell string, first divide the
   * [-90,90] x [-180,180] latitude/longitude space evenly into a 4x4 grid like so:
   * <p>
   * +---+---+---+---+ (90, 180)
   * | a | b | e | f |
   * +---+---+---+---+
   * | 8 | 9 | c | d |
   * +---+---+---+---+
   * | 2 | 3 | 6 | 7 |
   * +---+---+---+---+
   * | 0 | 1 | 4 | 5 |
   * (-90,-180) +---+---+---+---+
   * <p>
   * NOTE: The point (0, 0) is at the intersection of grid cells 3, 6, 9 and c. And,
   * for example, cell 7 should be the sub-rectangle from
   * (-45, 90) to (0, 180).
   * <p>
   * Calculate the sub-rectangle for the first character of the geocell string and
   * re-divide this sub-rectangle into another 4x4 grid. For example, if the geocell
   * string is '78a', we will re-divide the sub-rectangle like so:
   * <p>
   * .                   .
   * .                   .
   * . . +----+----+----+----+ (0, 180)
   * | 7a | 7b | 7e | 7f |
   * +----+----+----+----+
   * | 78 | 79 | 7c | 7d |
   * +----+----+----+----+
   * | 72 | 73 | 76 | 77 |
   * +----+----+----+----+
   * | 70 | 71 | 74 | 75 |
   * . . (-45,90) +----+----+----+----+
   * .                   .
   * .                   .
   * <p>
   * Continue to re-divide into sub-rectangles and 4x4 grids until the entire
   * geocell string has been exhausted. The final sub-rectangle is the rectangular
   * region for the geocell.
   *
   * @author api.roman.public@gmail.com (Roman Nurik)
   * @author (java portage) Alexandre Gellibert
   */
  
  public class GeocellManager {
  
      // The maximum *practical* geocell resolution.
      public static final int MAX_GEOCELL_RESOLUTION = 13;
  
      /**
       * Returns the list of geocells (all resolutions) that are containing the point
       *
       * @param point
       * @return Returns the list of geocells (all resolutions) that are containing the point
       */
      public static List<String> generateGeoCell(Point point) {
          List<String> geocells = new ArrayList<>();
          String geocellMax = GeocellUtils.compute(point, GeocellManager.MAX_GEOCELL_RESOLUTION);
          for(int i = 1; i < GeocellManager.MAX_GEOCELL_RESOLUTION; i++) {
              geocells.add(GeocellUtils.compute(point, i));
          }
          geocells.add(geocellMax);
          return geocells;
      }
  
  }
  