Code Search for Developers
 
 
  

GridReferenceConverter.java from GridBlocks at Krugle


Show GridReferenceConverter.java syntax highlighted

//-----------------------------------------------------------------------------
// GridReferenceConverter.java
//
// (c) 2003 Jonathan Stott
//
// 0.2 - 02 Mar 2004
//  - Added ability to convert UTM to/from latitude/longitude
//  - Added ability to convert OSGB grid references to/from latitude/longitude
// 0.1 - 11 Nov 2003
//  - First version
//-----------------------------------------------------------------------------

package fi.hip.gb.bluetooth.coordconv;

/**
 * Convert latitude/longitude to UTM references and vice/versa.
 * 
 * Based on algorithm published by the Ordnance Survey at
 * http://www.gps.gov.uk/guidecontents.asp
 * 
 * @author Jonathan Stott
 * @version 0.2
 */
public class GridReferenceConverter {

  private static final double UTM_F0 = 0.9996;
  
  /**
   * Convert an UTM reference to a latitude and longitude
   * 
   * @param ellipsoid A reference ellipsoid to use
   * @param utm the UTM reference to convert
   * @return the converted latitude and longitude
   * @since 0.2
   */
  public static LatitudeLongitude UTMReferenceToLatitudeLongitude(
                                  ReferenceEllipsoid ellipsoid,
                                  UTMReference utm) {

    double a = ellipsoid.getSemiMajorAxis();
    double eSquared = ellipsoid.getEccentricitySquared();
    double ePrimeSquared = eSquared / (1.0 - eSquared);
    double e1 = (1 - sqrt(1 - eSquared)) / (1 + sqrt(1 - eSquared));
    double x = utm.getEasting() - 500000.0;;
    double y = utm.getNorthing();
    int zoneNumber = utm.getLongitudeZone();
    char zoneLetter = utm.getLatitudeZone();
    double longitudeOrigin = (zoneNumber - 1.0) * 6.0 - 180.0 + 3.0;
    
    // Correct y for southern hemisphere
    if ((zoneLetter - 'N') < 0) {
      y -= 10000000.0;
    }

    double m = y / UTM_F0;
    double mu =
      m
        / (a
          * (1.0
            - eSquared / 4.0
            - 3.0 * eSquared * eSquared / 64.0
            - 5.0
              * pow(eSquared, 3.0)
              / 256.0));

    double phi1Rad =
      mu
        + (3.0 * e1 / 2.0 - 27.0 * pow(e1, 3.0) / 32.0) * sin(2.0 * mu)
        + (21.0 * e1 * e1 / 16.0 - 55.0 * pow(e1, 4.0) / 32.0)
          * sin(4.0 * mu)
        + (151.0 * pow(e1, 3.0) / 96.0) * sin(6.0 * mu);

    double n =
      a
        / sqrt(1.0 - eSquared * sin(phi1Rad) * sin(phi1Rad));
    double t = tan(phi1Rad) * tan(phi1Rad);
    double c = ePrimeSquared * cos(phi1Rad) * cos(phi1Rad);
    double r =
      a
        * (1.0 - eSquared)
        / pow(
          1.0 - eSquared * sin(phi1Rad) * sin(phi1Rad),
          1.5);
    double d = x / (n * UTM_F0);

    double latitude = (
    
      phi1Rad
        - (n * tan(phi1Rad) / r)
          * (d * d / 2.0
            - (5.0
              + (3.0 * t)
              + (10.0 * c)
              - (4.0 * c * c)
              - (9.0 * ePrimeSquared))
              * pow(d, 4.0)
              / 24.0
            + (61.0
              + (90.0 * t)
              + (298.0 * c)
              + (45.0 * t * t)
              - (252.0 * ePrimeSquared)
              - (3.0 * c * c))
              * pow(d, 6.0)
              / 720.0)) * (180.0 / Math.PI);

    double longitude = longitudeOrigin + (
      (d
        - (1.0 + 2.0 * t + c) * pow(d, 3.0) / 6.0
        + (5.0
          - (2.0 * c)
          + (28.0 * t)
          - (3.0 * c * c)
          + (8.0 * ePrimeSquared)
          + (24.0 * t * t))
          * pow(d, 5.0)
          / 120.0)
        / cos(phi1Rad)) * (180.0 / Math.PI);
    
    return new LatitudeLongitude(new Float(latitude), new Float(longitude));
  }
  
  /**
   * Convert a latitude and longitude to an UTM reference 
   * 
   * @param ellipsoid A reference ellipsoid to use
   * @param latitudeLongitude The latitude and longitude to convert
   * @return the converted UTM reference
   * @since 0.2
   */
  public static UTMReference latitudeLongitudeToUTMReference(
                             ReferenceEllipsoid ellipsoid,
                             LatitudeLongitude latitudeLongitude) {

      int longitudeZone = 
          (int) ((latitudeLongitude.getLongitude().floatValue() + 180.0) / 6.0) + 1;
      char UTMZone = getUTMLatitudeZoneLetter(latitudeLongitude.getLatitude());
      
      return latitudeLongitudeToUTMReference(ellipsoid, latitudeLongitude, longitudeZone, UTMZone);
  }
  
  /**
   * Convert a latitude and longitude to an UTM reference 
   * 
   * @param ellipsoid A reference ellipsoid to use
   * @param latitudeLongitude The latitude and longitude to convert
   * @param longitudeZone longitude zone
   * @param UTMZone latitude zone
   * @return the converted UTM reference
   * @since 0.2
   */
  public static UTMReference latitudeLongitudeToUTMReference(
                             ReferenceEllipsoid ellipsoid,
                             LatitudeLongitude latitudeLongitude,
                             int longitudeZone,
                             char UTMZone) {

    double a = ellipsoid.getSemiMajorAxis();
    double eSquared = ellipsoid.getEccentricitySquared();
    float longitude = latitudeLongitude.getLongitude().floatValue();
    float latitude = latitudeLongitude.getLatitude().floatValue();

    double latitudeRad = latitude * (Math.PI / 180.0);
    double longitudeRad = longitude * (Math.PI / 180.0);
    
    //int longitudeZone = (int) ((longitude + 180.0) / 6.0) + 1;

    // Special zone for Norway
    if (latitude >= 56.0
      && latitude < 64.0
      && longitude >= 3.0
      && longitude < 12.0) {
      longitudeZone = 32;
    }

    // Special zones for Svalbard
    if (latitude >= 72.0 && latitude < 84.0) {
      if (longitude >= 0.0 && longitude < 9.0) {
        longitudeZone = 31;
      } else if (longitude >= 9.0 && longitude < 21.0) {
        longitudeZone = 33;
      } else if (longitude >= 21.0 && longitude < 33.0) {
        longitudeZone = 35;
      } else if (longitude >= 33.0 && longitude < 42.0) {
        longitudeZone = 37;
      }
    }
    
    double longitudeOrigin = (longitudeZone - 1) * 6 - 180 + 3;
    double longitudeOriginRad = longitudeOrigin * (Math.PI / 180.0);

    //char UTMZone = getUTMLatitudeZoneLetter(latitude);

    double ePrimeSquared = (eSquared) / (1 - eSquared);

    double n = a / sqrt(1 - eSquared * sin(latitudeRad) * sin(latitudeRad));
    double t = tan(latitudeRad) * tan(latitudeRad);
    double c = ePrimeSquared * cos(latitudeRad) * cos(latitudeRad);
    double A = cos(latitudeRad) * (longitudeRad - longitudeOriginRad);

    double M =
      a
        * ((1
          - eSquared / 4
          - 3 * eSquared * eSquared / 64
          - 5 * eSquared * eSquared * eSquared / 256)
          * latitudeRad
          - (3 * eSquared / 8
            + 3 * eSquared * eSquared / 32
            + 45 * eSquared * eSquared * eSquared / 1024)
            * sin(2 * latitudeRad)
          + (15 * eSquared * eSquared / 256
            + 45 * eSquared * eSquared * eSquared / 1024)
            * sin(4 * latitudeRad)
          - (35 * eSquared * eSquared * eSquared / 3072)
            * sin(6 * latitudeRad));

    double UTMEasting =
      (double) (UTM_F0
        * n
        * (A
          + (1 - t + c) * pow(A, 3.0) / 6
          + (5 - 18 * t + t * t + 72 * c - 58 * ePrimeSquared)
            * pow(A, 5.0)
            / 120)
        + 500000.0);

    double UTMNorthing =
      (double) (UTM_F0
        * (M
          + n
            * tan(latitudeRad)
            * (A * A / 2
              + (5 - t + (9 * c) + (4 * c * c)) * pow(A, 4.0) / 24
              + (61 - (58 * t) + (t * t) + (600 * c) - (330 * ePrimeSquared))
                * pow(A, 6.0)
                / 720)));
    
    // Adjust for the southern hemisphere
    if (latitude < 0) {
      UTMNorthing += 10000000.0;
    }

    return new UTMReference(UTMEasting, UTMNorthing, UTMZone, longitudeZone);
  }
  
  
  /**
   *  Work out the UTM latitude zone from the latitude
   * 
   * @param latitude
   * @return
   * @since 0.2
   */
  public static char getUTMLatitudeZoneLetter(Float lat) {
      float latitude = lat.floatValue();
    if ((84 >= latitude) && (latitude >= 72)) return 'X';
    else if (( 72 > latitude) && (latitude >=  64)) return 'W';
    else if (( 64 > latitude) && (latitude >=  56)) return 'V';
    else if (( 56 > latitude) && (latitude >=  48)) return 'U';
    else if (( 48 > latitude) && (latitude >=  40)) return 'T';
    else if (( 40 > latitude) && (latitude >=  32)) return 'S';
    else if (( 32 > latitude) && (latitude >=  24)) return 'R';
    else if (( 24 > latitude) && (latitude >=  16)) return 'Q';
    else if (( 16 > latitude) && (latitude >=   8)) return 'P';
    else if ((  8 > latitude) && (latitude >=   0)) return 'N';
    else if ((  0 > latitude) && (latitude >=  -8)) return 'M';
    else if (( -8 > latitude) && (latitude >= -16)) return 'L';
    else if ((-16 > latitude) && (latitude >= -24)) return 'K';
    else if ((-24 > latitude) && (latitude >= -32)) return 'J';
    else if ((-32 > latitude) && (latitude >= -40)) return 'H';
    else if ((-40 > latitude) && (latitude >= -48)) return 'G';
    else if ((-48 > latitude) && (latitude >= -56)) return 'F';
    else if ((-56 > latitude) && (latitude >= -64)) return 'E';
    else if ((-64 > latitude) && (latitude >= -72)) return 'D';
    else if ((-72 > latitude) && (latitude >= -80)) return 'C';
    else return 'Z';
  }
  
  /**
   * Calculate sin(x) 
   * 
   * @param x
   * @return
   * @since 0.1
   */
  private static double sin(double x) {
    return Math.sin(x);
  }
  
  
  /**
   * Calculate sin^2(x) 
   * 
   * @param x
   * @return
   * @since 0.1
   */
  private static double sinSquared(double x) {
    return sin(x) * sin(x);
  }
  
  
  /**
   * Calculate cos(x) 
   * 
   * @param x
   * @return
   * @since 0.1
   */
  private static double cos(double x) {
    return Math.cos(x);
  }
  
  
  /**
   * Calculate tan(x) 
   * 
   * @param x
   * @return
   * @since 0.1
   */
  private static double tan(double x) {
    return Math.tan(x);
  }
  
  
  /**
   * Calculate tan^2(x) 
   * 
   * @param x
   * @return
   * @since 0.1
   */
  private static double tanSquared(double x) {
    return tan(x) * tan(x);
  }
  
  
  /**
   * Calculate sec(x) 
   * 
   * @param x
   * @return
   * @since 0.1
   */
  private static double sec(double x) {
    return 1.0 / cos(x);
  }
  
  
  /**
   * Calculate x^e 
   * 
   * @param x
   * @param e
   * @return
   * @since 0.1
   */
  private static double pow(double x, double e) {
    return Math.pow(x, e);
  }
  
  
  /**
   * Calculate sqrt(x) 
   * 
   * @param x
   * @return
   * @since 0.2
   */
  private static double sqrt(double x) {
    return Math.sqrt(x);
  }
}




See more files for this project here

GridBlocks

GridBlocks builds a grid application framework via easy-to-use building blocks in distributed environment. The framework offers components for Grid security, distributed storage, computing, and Portlet web interfaces.

Project homepage: http://sourceforge.net/projects/gridblocks
Programming language(s): Java,JSP,XML
License: other

  GridReferenceConverter.java
  ReferenceEllipsoid.java
  ReferenceEllipsoids.java
  UTMReference.java