Package com.motomapia.util

Source Code of com.motomapia.util.GeoUtils

/*
*/

package com.motomapia.util;

import com.beoui.geocell.model.Point;
import com.google.appengine.api.datastore.GeoPt;

/**
* Some simple static methods useful for dealing with geolocation
* @author Jeff Schnitzer
*/
public class GeoUtils
{
  /**
   * Convert to the geocell version
   */
  public static Point toPoint(GeoPt geoPt)
  {
    return new Point(geoPt.getLatitude(), geoPt.getLongitude());
  }
 
  /**
   * Convert to the google version
   */
  public static GeoPt toGeoPt(Point point)
  {
    return new GeoPt((float)point.getLat(), (float)point.getLon());
  }
 
  /**
   * Get the normal (unsigned) area of a polygon.
   *
   * @param polygon is a simple closed polygon defined by a set of points. A line is drawn from
   *  the last point to the first one; the array should not contain the first/last point twice.
   */
  public static double area(GeoPt[] polygon)
  {
    return Math.abs(areaSigned(polygon));
  }
 
  /**
   * Get the signed area of a polygon, indicating if the points are left or right clockwise.
   *
   * @param polygon is a simple closed polygon defined by a set of points. A line is drawn from
   *  the last point to the first one; the array should not contain the first/last point twice.
   */
  public static double areaSigned(GeoPt[] polygon)
  {
    if (polygon.length < 2)
      return 0;
   
    double sum = 0.0;
    for (int i=0; i<polygon.length; i++)
    {
      int next = i + 1;
      if (next == polygon.length) next = 0;
     
      sum += ((double)polygon[i].getLongitude() * (double)polygon[next].getLatitude());
      sum -= ((double)polygon[i].getLatitude() * (double)polygon[next].getLongitude());
    }
   
    return sum / 2;
  }

  /**
   * Gets the approximate center by averaging the points.  Really simple.
   * 
   * @param polygon is a simple closed polygon defined by a set of points. A line is drawn from
   *  the last point to the first one; the array should not contain the first/last point twice.
   */
  public static GeoPt centroidByAverage(GeoPt[] polygon)
  {
    float cLat = 0;
    float cLon = 0;
   
    for (int i=0; i<polygon.length; i++)
    {
      cLat += polygon[i].getLatitude();
      cLon += polygon[i].getLongitude();
    }
   
    cLat /= polygon.length;
    cLon /= polygon.length;
   
    return new GeoPt(cLat, cLon);
  }
 
  /**
   * Get the center of gravity of the polygon.
   * http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
   *
   * @param polygon is a simple closed polygon defined by a set of points. A line is drawn from
   *  the last point to the first one; the array should not contain the first/last point twice.
   */
  public static GeoPt centroid(GeoPt[] polygon)
  {
    if (polygon.length == 0)
      return null;
    else if (polygon.length == 1)
      return polygon[0];
     
    double cLat = 0.0f;
    double cLon = 0.0f;
   
    for (int i=0; i<polygon.length; i++)
    {
      double p1Lat = polygon[i].getLatitude();
      double p1Lon = polygon[i].getLongitude();
     
      int j = (i+1) == polygon.length ? 0 : i+1;
     
      double p2Lat = polygon[j].getLatitude();
      double p2Lon = polygon[j].getLongitude();

      double factor = p1Lon * p2Lat - p2Lon * p1Lat;
      cLat += (p1Lat + p2Lat) * factor;     
      cLon += (p1Lon + p2Lon) * factor;
    }

    double area = areaSigned(polygon);
    area *= 6.0;

    double factor = 1 / area;
    cLon *= factor;
    cLat *= factor;

    //log.debug("Centroid is " + cLat + ", " + cLon);
    return new GeoPt((float)cLat, (float)cLon);
  }
 
  /**
   * Determine if a polygon contains a point.
   *
   * @param polygon is a simple closed polygon defined by a set of points. A line is drawn from
   *  the last point to the first one; the array should not contain the first/last point twice.
   * @param pt is a point which is tested for enclosure in the polygon
   */
  public static boolean contains(GeoPt[] polygon, GeoPt pt)
  {
    int crossings = 0;
    for (int i=0; i<polygon.length; i++)
    {
      GeoPt p1 = polygon[i];
      GeoPt p2 = polygon[(i+1) == polygon.length ? 0 : i+1];
     
      double slope = (p2.getLongitude() - p1.getLongitude()) / (p2.getLatitude() - p1.getLatitude());
      boolean cond1 = (p1.getLatitude() <= pt.getLatitude()) && (pt.getLatitude() < p2.getLatitude());
      boolean cond2 = (p2.getLatitude() <= pt.getLatitude()) && (pt.getLatitude() < p1.getLatitude());
      boolean cond3 = pt.getLongitude() < slope * (pt.getLatitude() - p1.getLatitude()) + p1.getLongitude();
      if ((cond1 || cond2) && cond3)
        crossings++;
    }
   
    return (crossings % 2 != 0);
  }
}
TOP

Related Classes of com.motomapia.util.GeoUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.