void decimalLatLongtoUTM(const double ref_equ_radius, const double ref_ecc_squared, swarmGpsData * gpsdata) { double Lat = gpsdata->latdd; double Long = gpsdata->londd; double a = ref_equ_radius; double eccSquared = ref_ecc_squared; double k0 = 0.9996; double LongOrigin; double eccPrimeSquared; double N, T, C, A, M; //Make sure the longitude is between -180.00 .. 179.9 double LongTemp = (Long+180) - (int)((Long+180)/360)*360-180; // -180.00 .. 179.9; double LatRad = Lat*DEG2RAD; double LongRad = LongTemp*DEG2RAD; double LongOriginRad; int ZoneNumber; ZoneNumber = (int)((LongTemp + 180)/6) + 1; if( Lat >= 56.0 && Lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0 ) ZoneNumber = 32; // Special zones for Svalbard if( Lat >= 72.0 && Lat < 84.0 ) { if( LongTemp >= 0.0 && LongTemp < 9.0 ) ZoneNumber = 31; else if( LongTemp >= 9.0 && LongTemp < 21.0 ) ZoneNumber = 33; else if( LongTemp >= 21.0 && LongTemp < 33.0 ) ZoneNumber = 35; else if( LongTemp >= 33.0 && LongTemp < 42.0 ) ZoneNumber = 37; } LongOrigin = (ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone LongOriginRad = LongOrigin * DEG2RAD; //compute the UTM Zone from the latitude and longitude sprintf(gpsdata->UTMZone, "%d%c", ZoneNumber, UTMLetterDesignator(Lat)); eccPrimeSquared = (eccSquared)/(1-eccSquared); N = a/sqrt(1-eccSquared*sin(LatRad)*sin(LatRad)); T = tan(LatRad)*tan(LatRad); C = eccPrimeSquared*cos(LatRad)*cos(LatRad); A = cos(LatRad)*(LongRad-LongOriginRad); 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)*sin(2*LatRad) + (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*LatRad) - (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*LatRad)); gpsdata->UTMEasting = (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); gpsdata->UTMNorthing = (double)(k0*(M+N*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) gpsdata->UTMNorthing += 10000000.0; //10000000 meter offset for southern hemisphere }
void LLtoUTM(int ReferenceEllipsoid, const double Lat, const double Long, double &UTMNorthing, double &UTMEasting, char* UTMZone) { //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- [email protected] double a = ellipsoid[ReferenceEllipsoid].EquatorialRadius; double eccSquared = ellipsoid[ReferenceEllipsoid].eccentricitySquared; double k0 = 0.9996; double LongOrigin; double eccPrimeSquared; double N, T, C, A, M; //Make sure the longitude is between -180.00 .. 179.9 double LongTemp = (Long+180)-int((Long+180)/360)*360-180; // -180.00 .. 179.9; double LatRad = Lat*deg2rad; double LongRad = LongTemp*deg2rad; double LongOriginRad; int ZoneNumber; ZoneNumber = int((LongTemp + 180)/6) + 1; if( Lat >= 56.0 && Lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0 ) ZoneNumber = 32; // Special zones for Svalbard if( Lat >= 72.0 && Lat < 84.0 ) { if( LongTemp >= 0.0 && LongTemp < 9.0 ) ZoneNumber = 31; else if( LongTemp >= 9.0 && LongTemp < 21.0 ) ZoneNumber = 33; else if( LongTemp >= 21.0 && LongTemp < 33.0 ) ZoneNumber = 35; else if( LongTemp >= 33.0 && LongTemp < 42.0 ) ZoneNumber = 37; } LongOrigin = (ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone LongOriginRad = LongOrigin * deg2rad; //compute the UTM Zone from the latitude and longitude sprintf(UTMZone, "%d%c", ZoneNumber, UTMLetterDesignator(Lat)); eccPrimeSquared = (eccSquared)/(1-eccSquared); N = a/sqrt(1-eccSquared*sin(LatRad)*sin(LatRad)); T = tan(LatRad)*tan(LatRad); C = eccPrimeSquared*cos(LatRad)*cos(LatRad); A = cos(LatRad)*(LongRad-LongOriginRad); 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)*sin(2*LatRad) + (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*LatRad) - (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*LatRad)); UTMEasting = (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); UTMNorthing = (double)(k0*(M+N*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) UTMNorthing += 10000000.0; //10000000 meter offset for southern hemisphere }