GeoPointConversion.java :  » Map » mapdroid » org » mapdroid » utils » Android Open Source

Android Open Source » Map » mapdroid 
mapdroid » org » mapdroid » utils » GeoPointConversion.java
package org.mapdroid.utils;

import android.os.Bundle;

import com.google.android.maps.GeoPoint;

public class GeoPointConversion{  
  private static final double deg2rad = Math.PI / 180;
  private static final double rad2deg = 180.0 / Math.PI;
  //These values describes the model we're using for our computation.
  //We're using the WGS-84 Ellipsoid Model! 
  private static final double a =       6378137;    //Equatorial Radius
  private static final double eccSquared = 0.00669438;    //Eccentricity Squared
  //-----------------------------------------------------------------
  private static final double k0 = 0.9996;          //Scale along central meridian of zone
  public static final String UTM_ZONE = "UTM_ZONE";
  public static final String UTM_VALUE = "UTM_VALUE";

      
  //Constructor
  public GeoPointConversion(){}

  public static Bundle geoPointToUTM(GeoPoint point){
  //converts lat/long to UTM coords.  Equations from USGS Bulletin 1532 
  //East Longitudes are positive, West longitudes are negative. 
  //North latitudes are positive, South latitudes are negative
  //Lat and Long are in decimal degrees
    //Written by Chuck Gantz- chuck.gantz@globalstar.com

    double lonOrigin;          //Central Meridian of zone
    double eccPrimeSquared;
    double N, T, C, A, M;
    
    double lat = point.getLatitudeE6()/1E6;
    double lon = point.getLongitudeE6()/1E6;
    
  //Make sure the longitude is between -180.00 .. 179.9
    double lonTemp = (lon+180)-(int)((lon+180)/360)*360-180; // -180.00 .. 179.9;

    double latRad = lat*deg2rad;
    double lonRad = lonTemp*deg2rad;
    double lonOriginRad;
    int    zoneNumber;
    String utmZone;
    double[] utm = {0,0};

    zoneNumber = (int)((lonTemp + 180)/6) + 1;
    
    if( lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0 )
      zoneNumber = 32;

    // Special zones for Svalbard
    if( lat >= 72.0 && lat < 84.0 ){
      if(      lonTemp >= 0.0  && lonTemp <  9.0 ) zoneNumber = 31;
      else if( lonTemp >= 9.0  && lonTemp < 21.0 ) zoneNumber = 33;
      else if( lonTemp >= 21.0 && lonTemp < 33.0 ) zoneNumber = 35;
      else if( lonTemp >= 33.0 && lonTemp < 42.0 ) zoneNumber = 37;
    }
    lonOrigin = (zoneNumber - 1)*6 - 180 + 3;  //+3 puts origin in middle of zone
    lonOriginRad = lonOrigin * deg2rad;

    //compute the UTM Zone from the latitude and longitude
    utmZone = Integer.toString(zoneNumber) + UTMLetterDesignator(lat);

    eccPrimeSquared = (eccSquared)/(1-eccSquared);

    N = a / Math.sqrt(1 - eccSquared * Math.sin(latRad) * Math.sin(latRad));
    T = Math.tan(latRad) * Math.tan(latRad);
    C = eccPrimeSquared * Math.cos(latRad) * Math.cos(latRad);
    A = Math.cos(latRad) * (lonRad - lonOriginRad);

    M = a*((1  - eccSquared/4    - 3*eccSquared*eccSquared/64  - 5*eccSquared*eccSquared*eccSquared / 256)*latRad 
          - (3*eccSquared/8  + 3*eccSquared*eccSquared/32  + 45*eccSquared*eccSquared*eccSquared/1024)*Math.sin(2*latRad)
                    + (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*Math.sin(4*latRad) 
                    - (35*eccSquared*eccSquared*eccSquared/3072)*Math.sin(6*latRad));
    
    utm[0] = (double)(k0*N*(A+(1-T+C)*A*A*A/6
            + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
            + 500000.0);

    utm[1] = (double)(k0*(M+N*Math.tan(latRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
           + (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
    if(lat < 0)
      utm[1] += 10000000.0; //10000000 meter offset for southern hemisphere
    
    Bundle bundle = new Bundle();
    bundle.putString(GeoPointConversion.UTM_ZONE, utmZone);
    bundle.putDoubleArray(GeoPointConversion.UTM_VALUE, utm);
    return bundle;
  }

  private static char UTMLetterDesignator(double Lat){
  //This routine determines the correct UTM letter designator for the given latitude
  //returns 'Z' if latitude is outside the UTM limits of 84N to 80S
    //Written by Chuck Gantz- chuck.gantz@globalstar.com
    char LetterDesignator;

    if((84 >= Lat) && (Lat >= 72)) LetterDesignator = 'X';
    else if((72 > Lat) && (Lat >= 64)) LetterDesignator = 'W';
    else if((64 > Lat) && (Lat >= 56)) LetterDesignator = 'V';
    else if((56 > Lat) && (Lat >= 48)) LetterDesignator = 'U';
    else if((48 > Lat) && (Lat >= 40)) LetterDesignator = 'T';
    else if((40 > Lat) && (Lat >= 32)) LetterDesignator = 'S';
    else if((32 > Lat) && (Lat >= 24)) LetterDesignator = 'R';
    else if((24 > Lat) && (Lat >= 16)) LetterDesignator = 'Q';
    else if((16 > Lat) && (Lat >= 8)) LetterDesignator = 'P';
    else if(( 8 > Lat) && (Lat >= 0)) LetterDesignator = 'N';
    else if(( 0 > Lat) && (Lat >= -8)) LetterDesignator = 'M';
    else if((-8> Lat) && (Lat >= -16)) LetterDesignator = 'L';
    else if((-16 > Lat) && (Lat >= -24)) LetterDesignator = 'K';
    else if((-24 > Lat) && (Lat >= -32)) LetterDesignator = 'J';
    else if((-32 > Lat) && (Lat >= -40)) LetterDesignator = 'H';
    else if((-40 > Lat) && (Lat >= -48)) LetterDesignator = 'G';
    else if((-48 > Lat) && (Lat >= -56)) LetterDesignator = 'F';
    else if((-56 > Lat) && (Lat >= -64)) LetterDesignator = 'E';
    else if((-64 > Lat) && (Lat >= -72)) LetterDesignator = 'D';
    else if((-72 > Lat) && (Lat >= -80)) LetterDesignator = 'C';
    else LetterDesignator = 'Z'; //This is here as an error flag to show that the Latitude is outside the UTM limits

    return LetterDesignator;
  }


  public static GeoPoint utmToGeoPoint(double utmEasting, double utmNorthing, String utmZone){
  //converts UTM coords to lat/long.  Equations from USGS Bulletin 1532 
  //East Longitudes are positive, West longitudes are negative. 
  //North latitudes are positive, South latitudes are negative
  //Lat and Long are in decimal degrees. 
    //Written by Chuck Gantz- chuck.gantz@globalstar.com

    double eccPrimeSquared;
    double e1 = (1-Math.sqrt(1-eccSquared))/(1+Math.sqrt(1-eccSquared));
    double N1, T1, C1, R1, D, M;
    double lonOrigin;
    double mu, /*phil,*/ phi1Rad;
    double x, y;
    int zoneNumber;
    char zoneLetter;
    //int NorthernHemisphere; //1 for northern hemispher, 0 for southern

    x = utmEasting - 500000.0; //remove 500,000 meter offset for longitude
    y = utmNorthing;

    CharSequence utmZoneCopy = utmZone;
    zoneLetter = utmZoneCopy.charAt(utmZoneCopy.length()-1);
    CharSequence zoneNumberString = utmZoneCopy.subSequence(0, utmZoneCopy.length()-1);
    zoneNumber = Integer.parseInt((String) zoneNumberString);
    if((zoneLetter - 'N') >= 0){}
      //NorthernHemisphere = 1;//point is in northern hemisphere
    else
    {
      //NorthernHemisphere = 0;//point is in southern hemisphere
      y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
    }

    lonOrigin = (zoneNumber - 1)*6 - 180 + 3;  //+3 puts origin in middle of zone

    eccPrimeSquared = (eccSquared)/(1-eccSquared);

    M = y / k0;
    mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256));

    phi1Rad = mu  + (3*e1/2-27*e1*e1*e1/32)*Math.sin(2*mu) 
          + (21*e1*e1/16-55*e1*e1*e1*e1/32)*Math.sin(4*mu)
          +(151*e1*e1*e1/96)*Math.sin(6*mu);
    //phi1 = phi1Rad*rad2deg;

    N1 = a/Math.sqrt(1-eccSquared*Math.sin(phi1Rad)*Math.sin(phi1Rad));
    T1 = Math.tan(phi1Rad)*Math.tan(phi1Rad);
    C1 = eccPrimeSquared*Math.cos(phi1Rad)*Math.cos(phi1Rad);
    R1 = a*(1-eccSquared)/Math.pow(1-eccSquared*Math.sin(phi1Rad)*Math.sin(phi1Rad), 1.5);
    D = x/(N1*k0);

    double lat = phi1Rad - (N1*Math.tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
            +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720);
    lat = lat * rad2deg;

    double lon = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)
            *D*D*D*D*D/120)/Math.cos(phi1Rad);
    lon = lonOrigin + lon * rad2deg;

    return new GeoPoint((int)(lat*1E6), (int)(lon*1E6));
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.