To whom it may concern,

I had some trouble converting DD to UTM ( WGS84 ). I looked in every dark corner on the net, but I was unable to find the code to do it programmatically without the use of ( sometimes ) expensive third party controls. So .. I decided to hack something together myself , and all in managed code :D. I decide to post it, since I know there are many people looking for it and they don't have to go throught the same struggle as me to get is done.

remember .. this is just code to convert Lat/Long DD ( eg. 44.123456 ) to UTM Northing/Easting ( eg. 7342333, 218734, 31T). I'm still working on the code to do it the other way around and code to include other Datums. You can use this code directly in your application. You'll need to do a little bit of work if you want to update MathEngine.cs with this code.

Cheers,

private void ConvertLatLongToUTM(object Sender, EventArgs e)

{

//Read the inputs

string sLong = textboxLongitude.Text;

string sLat = textboxLatitude.Text;

double dLong = ParseIn(sLong);

double dLat = ParseIn(sLat);

textboxLongitude.Text = dLong.ToString("0.000000°");

textboxLatitude.Text = dLat.ToString("0.000000°");

double dX;

double dY;

string Zone;

//Convert

LatLongtoUTM(dLat, dLong,

out dY, out dX,

out Zone);

//Populate UTM units ( Northing, Easting and Zone )

txtboxEasting.Text = dX.ToString("###,###,### meters");

txtboxNorthing.Text = dY.ToString("###,###,### meters");

txtZone.Text = Zone;

//Populate North/South

char cZoneLetter = UTMZone[UTMZone.Length - 1];

bool bNorth = (cZoneLetter >= 'N');

//Populate da Zone

string sZoneNo = UTMZone.Substring(0, UTMZone.Length - 1);

}

private double ParseIn(string sIn)

{

sIn = sIn.Trim();

StringBuilder sb = new StringBuilder(sIn);

for (int n = 0; n < sIn.Length; n++)

{

if (!Char.IsDigit(sIn[n]) &&

sIn[n] != '-' &&

sIn[n] != '.')

{

sb[n] = 'X';

}

}

sb.Replace("X", "");

if (sb.Length == 0)

{

return 0.0;

}

return Double.Parse(sb.ToString());

}

void LatLongtoUTM( double Lat, double Long,

out double UTMNorthing, out double UTMEasting,

out string Zone )

{

double a = 6378137; //WGS84

double eccSquared = 0.00669438; //WGS84

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

Zone = ZoneNumber.ToString() + UTMLetterDesignator(Lat);

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

N = a/Math.Sqrt(1-eccSquared*Math.Sin(LatRad)*Math.Sin(Lat Rad));

T = Math.Tan(LatRad)*Math.Tan(LatRad);

C = eccPrimeSquared*Math.Cos(LatRad)*Math.Co s(LatRad);

A = Math.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)*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));

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*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)

UTMNorthing += 10000000.0; //10000000 meter offset for southern hemisphere

}

private char UTMLetterDesignator(double Lat)

{

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'; //Latitude is outside the UTM limits

return LetterDesignator;

}

class Ellipsoid

{

//Attributes

public string ellipsoidName;

public double EquatorialRadius;

public double eccentricitySquared;

public Ellipsoid(string name, double radius, double ecc)

{

ellipsoidName = name;

EquatorialRadius = radius;

eccentricitySquared = ecc;

}

};