2D Graphics GUI Java

/*
 * This file is part of the AusStage Utilities Package
 *
 * The AusStage Utilities Package is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * The AusStage Utilities Package is distributed in the hope that it will 
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the AusStage Utilities Package.  
 * If not, see .
*/
//package au.edu.ausstage.utils;
// import additional libraries
import java.text.DecimalFormat;
/**
 * A class to represent a latitude and longitude
 */
public class Coordinate implements Comparable{
  // declare private class level variables
  private float latitude;
  private float longitude;
  private DecimalFormat format;
  
  /**
   * Constructor for this class
   *
   * @param latitude a latitude coordinate in decimal notation
   * @param longitude a longitude coordinate in decimal notation
   */
  public Coordinate(float latitude, float longitude) {
  
    if(CoordinateManager.isValidLatitude(latitude) == true && CoordinateManager.isValidLongitude(longitude) == true) {
      this.latitude = latitude;
      this.longitude = longitude;
    } else {
      throw new IllegalArgumentException("The parameters did not pass validation as defined by the CoordinateManager class");
    }
    
    this.format = new DecimalFormat("##.######");
  }
  
  /*
   * get and set methods
   */
  public float getLatitude() {
    return latitude;
  }
  
  public float getLongitude() {
    return longitude;
  }
  
  public void setLatitude(float latitude) {
    if(CoordinateManager.isValidLatitude(latitude) == true) {
      this.latitude = latitude;
    } else {
      throw new IllegalArgumentException("The parameter did not pass validation as defined by the CoordinateManager class");
    }
  }
  
  public void setLongitude(float longitude) {
    if(CoordinateManager.isValidLongitude(longitude) == true) {  
      this.longitude = longitude;
    } else {
      throw new IllegalArgumentException("The parameter did not pass validation as defined by the CoordinateManager class");
    }
  }
  
  public String getLatitudeAsString() {
  
    return format.format(latitude);
  }
  
  public String getLongitudeAsString() {
    return format.format(longitude);
  }
  
  public String toString() {
    return format.format(latitude) + ", " + format.format(longitude);
  }
  
  /*
   * methods required for ordering in collections
   * http://java.sun.com/docs/books/tutorial/collections/interfaces/order.html
   */
  /**
   * A method to determine if one event is the same as another
   *
   * @param o the object to compare this one to
   *
   * @return  true if they are equal, false if they are not
   */
  public boolean equals(Object o) {
    // check to make sure the object is an event
    if ((o instanceof Coordinate) == false) {
      // o is not an event object
       return false;
    }
    
    // compare these two events
    Coordinate c = (Coordinate)o;
    
    // build items for comparison
    String me  = this.getLatitudeAsString() + this.getLongitudeAsString();
    String you = c.getLatitudeAsString() + c.getLongitudeAsString();
    
    return me.equals(you);
    
  } // end equals method
  
  /**
   * Overide the default hashcode method
   * 
   * @return a hashcode for this object
   */
  public int hashCode() {
  
    String me = this.getLatitudeAsString() + this.getLongitudeAsString();
    return 31*me.hashCode();
  }
    
    /**
     * The compareTo method compares the receiving object with the specified object and returns a 
     * negative integer, 0, or a positive integer depending on whether the receiving object is 
     * less than, equal to, or greater than the specified object.
     *
     * @param c the event to compare this one to
     *
     * @return  an integer indicating comparison result
     */    
  public int compareTo(Coordinate c) {
  
    String me  = this.getLatitudeAsString() + this.getLongitudeAsString();
    String you = c.getLatitudeAsString() + c.getLongitudeAsString();
    
    Double meDbl  = Double.valueOf(me);
    Double youDbl = Double.valueOf(you);
    
    if(meDbl == youDbl) {
      return 0;
    } else {
      Double tmp = Math.floor(meDbl - youDbl);
      return tmp.intValue();
    }
    
  } // end compareTo method
}
class CoordinateManager {
  // declare public constants
  
  /**
   * The minimum allowed latitude
   */
  public static float MIN_LATITUDE = Float.valueOf("-90.0000");
  
  /**
   * The maximum allowed latitude
   */
  public static float MAX_LATITUDE = Float.valueOf("90.0000");
  
  /**
   * The minimum allowed longitude
   */
  public static float MIN_LONGITUDE = Float.valueOf("-180.0000");
  
  /**
   * The maximum allowed longitude 
   */
  public static float MAX_LONGITUDE = Float.valueOf("180.0000");
  
  /**
   * The diameter of the Earth used in calculations
   */
  public static float EARTH_DIAMETER = Float.valueOf("12756.274");
  /**
   * A method to validate a latitude value
   *
   * @param latitude the latitude to check is valid
   *
   * @return         true if, and only if, the latitude is within the MIN and MAX latitude
   */
  public static boolean isValidLatitude(float latitude) {
    if(latitude >= MIN_LATITUDE && latitude <= MAX_LATITUDE) {
      return true;
    } else {
      return false;
    }
  }
  
  /**
   * A method to validate a longitude value
   *
   * @param longitude the longitude to check is valid
   *
   * @return          true if, and only if, the longitude is between the MIN and MAX longitude
   */
  public static boolean isValidLongitude(float longitude) {
    if(longitude >= MIN_LONGITUDE && longitude <= MAX_LONGITUDE) {
      return true;
    } else {
      return false;
    }
  }
  
  /**
   * A private method to calculate the latitude constant
   *
   * @return a double representing the latitude constant
   */
  public static double latitudeConstant() {
    return EARTH_DIAMETER * (Math.PI / Float.valueOf("360"));
    //return EARTH_DIAMETER * (Float.valueOf("3.14") / Float.valueOf("360"));
  }
  
  /**
   * A private method to caluclate the longitude constant
   *
   * @param latitude  a latitude coordinate in decimal notation
   *
   * @return a double representing the longitude constant
   */
  public static double longitudeConstant(float latitude) {
  
    //return Math.abs( Math.cos(Math.abs(latitude)));
    return EARTH_DIAMETER * Math.PI * Math.abs(Math.cos(Math.abs(latitude))) / Float.valueOf("360");
  
  }
  
  /**
   * A method to add distance in a northerly direction to a coordinate
   *
   * @param latitude  a latitude coordinate in decimal notation
   * @param longitude a longitude coordinate in decimal notation
   * @param distance  the distance to add in metres
   *
   * @return          the new coordinate
   */
  public static Coordinate addDistanceNorth(float latitude, float longitude, int distance) {
  
    // check on the parameters
    if(isValidLatitude(latitude) == false || isValidLongitude(longitude) == false || distance <= 0) {
      throw new IllegalArgumentException("All parameters are required and must be valid");
    }
    
    // convert the distance from metres to kilometers
    float kilometers = distance / new Float(1000);  
    
    // calculate the new latitude
    double newLat = latitude + (kilometers / latitudeConstant());
    
    return new Coordinate(new Float(newLat).floatValue(), longitude);
  
  }
  
  /**
   * A method to add distance in a southerly direction to a coordinate
   *
   * @param latitude  a latitude coordinate in decimal notation
   * @param longitude a longitude coordinate in decimal notation
   * @param distance  the distance to add in metres
   *
   * @return          the new coordinate
   */
  public static Coordinate addDistanceSouth(float latitude, float longitude, int distance) {
  
    // check on the parameters
    if(isValidLatitude(latitude) == false || isValidLongitude(longitude) == false || distance <= 0) {
      throw new IllegalArgumentException("All parameters are required and must be valid");
    }
    
    // convert the distance from metres to kilometers
    float kilometers = distance / new Float(1000);
    
    // calculate the new latitude
    double newLat = latitude - (kilometers / latitudeConstant());
    
    return new Coordinate(new Float(newLat).floatValue(), longitude);
  
  }
  
  /**
   * A method to add distance in an easterly direction to a coordinate
   *
   * @param latitude  a latitude coordinate in decimal notation
   * @param longitude a longitude coordinate in decimal notation
   * @param distance  the distance to add in metres
   *
   * @return          the new coordinate
   */
  public static Coordinate addDistanceEast(float latitude, float longitude, int distance) {
  
    // check on the parameters
    if(isValidLatitude(latitude) == false || isValidLongitude(longitude) == false || distance <= 0) {
      throw new IllegalArgumentException("All parameters are required and must be valid");
    }
    
    // convert the distance from metres to kilometers
    float kilometers = distance / 1000;  
    
    // calculate the new longitude
    double newLng = longitude + (distance / longitudeConstant(latitude));
    
    return new Coordinate(latitude, new Float(newLng).floatValue());  
  }
  
  /**
   * A method to add distance in an westerly direction to a coordinate
   *
   * @param latitude  a latitude coordinate in decimal notation
   * @param longitude a longitude coordinate in decimal notation
   * @param distance  the distance to add in metres
   *
   * @return          the new coordinate
   */
  public static Coordinate addDistanceWest(float latitude, float longitude, int distance) {
  
    // check on the parameters
    if(isValidLatitude(latitude) == false || isValidLongitude(longitude) == false || distance <= 0) {
      throw new IllegalArgumentException("All parameters are required and must be valid");
    }
    
    // convert the distance from metres to kilometers
    float kilometers = distance / 1000;  
    
    // calculate the new longitude
    double newLng = longitude - (distance / longitudeConstant(latitude));
    
    return new Coordinate(latitude, new Float(newLng).floatValue());  
  }
  
  /**
   * A method to build four coordinates representing a bounding box given a start coordinate and a distance
   *
   * @param latitude  a latitude coordinate in decimal notation
   * @param longitude a longitude coordinate in decimal notation
   * @param distance  the distance to add in metres
   *
   * @return          a hashMap representing the bounding box (NE,SE,SW,NW)
   */
  public static java.util.HashMap getBoundingBox(float latitude, float longitude, int distance) {
  
    // check on the parameters
    if(isValidLatitude(latitude) == false || isValidLongitude(longitude) == false || distance <= 0) {
      throw new IllegalArgumentException("All parameters are required and must be valid");
    }
    
    // convert the distance from metres to kilometers
    float kilometers = distance / 1000;  
    
    // declare helper variables
    java.util.HashMap boundingBox = new java.util.HashMap();
    
    // calculate the coordinates
    Coordinate north = addDistanceNorth(latitude, longitude, distance);
    Coordinate south = addDistanceSouth(latitude, longitude, distance);
    Coordinate east  = addDistanceEast(latitude, longitude, distance);
    Coordinate west  = addDistanceWest(latitude, longitude, distance);
    
    // build the bounding box object
    boundingBox.put("NE", new Coordinate(north.getLatitude(), east.getLongitude()));
    boundingBox.put("SE", new Coordinate(south.getLatitude(), east.getLongitude()));
    boundingBox.put("SW", new Coordinate(south.getLatitude(), west.getLongitude()));
    boundingBox.put("NW", new Coordinate(north.getLatitude(), west.getLongitude()));
    
    // return the bounding box object
    return boundingBox;  
  }
}