• Status: Solved
• Priority: Medium
• Security: Public
• Views: 2031

Conversion to UTM

Hi there, i am trying to find some code in order to take a geographical coordinate point expressed either in decimal degrees, DMS or Georef and convert it to UTM.
0
ioustinos_sarris
1 Solution

Commented:
Hi!

This is the C# code:

private void ConvertLatLongToUTM(object Sender, EventArgs e)

{
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 begin_of_the_skype_highlighting              00669438      end_of_the_skype_highlighting; //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;

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

//compute the UTM Zone from the latitude and longitude
Zone = ZoneNumber.ToString() + UTMLetterDesignator(Lat);

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

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)

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

+ (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
if(Lat < 0)
UTMNorthing += 10000000 begin_of_the_skype_highlighting              10000000      end_of_the_skype_highlighting.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 eccentricitySquared;

public Ellipsoid(string name, double radius, double ecc)
{
ellipsoidName = name;
eccentricitySquared = ecc;
}
};
0

Commented:
In general, when I need to convert between Coordinate Systems, I use proj4:
http://trac.osgeo.org/proj/
The .NET api is here:

All you need to know is the arguments of both projections (most commonly used projections are described in the documentation) and proj4 will do the work for you.
0

Commented:
Ah, sorry, You need the VB source... Here it is:

Imports Microsoft.VisualBasic

Private Sub ConvertLatLongToUTM(ByVal Sender As Object, ByVal e As EventArgs)
Dim sLong As String = textboxLongitude.Text
Dim sLat As String = textboxLatitude.Text
Dim dLong As Double = ParseIn(sLong)
Dim dLat As Double = ParseIn(sLat)
textboxLongitude.Text = dLong.ToString("0.000000°")
textboxLatitude.Text = dLat.ToString("0.000000°")
Dim dX As Double
Dim dY As Double
Dim Zone As String
LatLongtoUTM(dLat, dLong,dY, dX,Zone)
txtboxEasting.Text = dX.ToString("###,###,### meters")
txtboxNorthing.Text = dY.ToString("###,###,### meters")
txtZone.Text = Zone
Dim cZoneLetter As Char = UTMZone(UTMZone.Length - 1)
Dim bNorth As Boolean = (cZoneLetter >= "N"c)
Dim sZoneNo As String = UTMZone.Substring(0, UTMZone.Length - 1)
End Sub

Private Function ParseIn(ByVal sIn As String) As Double
sIn = sIn.Trim()
Dim sb As New StringBuilder(sIn)
For n As Integer = 0 To sIn.Length - 1
If (Not Char.IsDigit(sIn.Chars(n))) AndAlso sIn.Chars(n) <> "-"c AndAlso sIn.Chars(n) <> "."c Then
sb(n) = "X"c
End If
Next n
sb.Replace("X", "")
If sb.Length = 0 Then
Return 0.0
End If
Return Double.Parse(sb.ToString())
End Function

Private Sub LatLongtoUTM(ByVal Lat As Double, ByVal [Long] As Double, <System.Runtime.InteropServices.Out()> ByRef UTMNorthing As Double, <System.Runtime.InteropServices.Out()> ByRef UTMEasting As Double, <System.Runtime.InteropServices.Out()> ByRef Zone As String)
Dim a As Double = 6378137 'WGS84
Dim eccSquared As Double = 0.00669438
Dim k0 As Double = 0.9996
Dim LongOrigin As Double
Dim eccPrimeSquared As Double
'INSTANT VB NOTE: The variable A was renamed since Visual Basic will not allow local variables with the same name as parameters or other local variables:
Dim N, T, C, A_Renamed, M As Double
Dim LongTemp As Double = ([Long]+180)-(CInt(Fix(([Long]+180)/360)))*360-180 ' -180.00.. 179.9;
Dim ZoneNumber As Integer
ZoneNumber = (CInt(Fix((LongTemp + 180)/6))) + 1
If Lat >= 56.0 AndAlso Lat < 64.0 AndAlso LongTemp >= 3.0 AndAlso LongTemp < 12.0 Then
ZoneNumber = 32
End If
If Lat >= 72.0 AndAlso Lat < 84.0 Then
If LongTemp >= 0.0 AndAlso LongTemp < 9.0 Then
ZoneNumber = 31
ElseIf LongTemp >= 9.0 AndAlso LongTemp < 21.0 Then
ZoneNumber = 33
ElseIf LongTemp >= 21.0 AndAlso LongTemp < 33.0 Then
ZoneNumber = 35
ElseIf LongTemp >= 33.0 AndAlso LongTemp < 42.0 Then
ZoneNumber = 37
End If
End If
LongOrigin = (ZoneNumber - 1)*6 - 180 + 3 '+3 puts origin in middle of zone
Zone = ZoneNumber.ToString() & UTMLetterDesignator(Lat)
eccPrimeSquared = (eccSquared)/(1-eccSquared)
UTMEasting = CDbl(k0*N*(A_Renamed+(1-T+C)*A_Renamed*A_Renamed*A_Renamed/6+(5-18*T+T*T+72*C-58*eccPrimeSquared)*A_Renamed*A_Renamed*A_Renamed*A_Renamed*A_Renamed/120)+500000.0)
If Lat < 0 Then '10000000 meter offset for southern hemisphere
UTMNorthing += 10000000.0
End If
End Sub

Private Function UTMLetterDesignator(ByVal Lat As Double) As Char
Dim LetterDesignator As Char
If (84 >= Lat) AndAlso (Lat >= 72) Then
LetterDesignator = "X"c
ElseIf (72 > Lat) AndAlso (Lat >= 64) Then
LetterDesignator = "W"c
ElseIf (64 > Lat) AndAlso (Lat >= 56) Then
LetterDesignator = "V"c
ElseIf (56 > Lat) AndAlso (Lat >= 48) Then
LetterDesignator = "U"c
ElseIf (48 > Lat) AndAlso (Lat >= 40) Then
LetterDesignator = "T"c
ElseIf (40 > Lat) AndAlso (Lat >= 32) Then
LetterDesignator = "S"c
ElseIf (32 > Lat) AndAlso (Lat >= 24) Then
LetterDesignator = "R"c
ElseIf (24 > Lat) AndAlso (Lat >= 16) Then
LetterDesignator = "Q"c
ElseIf (16 > Lat) AndAlso (Lat >= 8) Then
LetterDesignator = "P"c
ElseIf (8 > Lat) AndAlso (Lat >= 0) Then
LetterDesignator = "N"c
ElseIf (0 > Lat) AndAlso (Lat >= -8) Then
LetterDesignator = "M"c
ElseIf (-8 > Lat) AndAlso (Lat >= -16) Then
LetterDesignator = "L"c
ElseIf (-16 > Lat) AndAlso (Lat >= -24) Then
LetterDesignator = "K"c
ElseIf (-24 > Lat) AndAlso (Lat >= -32) Then
LetterDesignator = "J"c
ElseIf (-32 > Lat) AndAlso (Lat >= -40) Then
LetterDesignator = "H"c
ElseIf (-40 > Lat) AndAlso (Lat >= -48) Then
LetterDesignator = "G"c
ElseIf (-48 > Lat) AndAlso (Lat >= -56) Then
LetterDesignator = "F"c
ElseIf (-56 > Lat) AndAlso (Lat >= -64) Then
LetterDesignator = "E"c
ElseIf (-64 > Lat) AndAlso (Lat >= -72) Then
LetterDesignator = "D"c
ElseIf (-72 > Lat) AndAlso (Lat >= -80) Then
LetterDesignator = "C"c
Else 'Latitude is outside the UTM limits
LetterDesignator = "Z"c
End If
Return LetterDesignator
End Function

Friend Class Ellipsoid
Public ellipsoidName As String
Public eccentricitySquared As Double
Public Sub New(ByVal name As String, ByVal radius As Double, ByVal ecc As Double)
ellipsoidName = name
eccentricitySquared = ecc
End Sub
End Class
0

Author Commented:
@Bigboj...Thanks this looks great!
It seems that i will be able to tweak the code to fit my exact needs.
However i do not really understand what deg2rad variable is...
Thank you very much
0

Commented:
Based on URL : http://www.uwgb.edu/dutchs/usefuldata/utmformulas.htm I have made simple code (in C#) that converts from decima degrees format into dd mm ss.ss.
Be aware - this is not completely tested !

``````public string convertLatLong(double inData) {

string fresult = "";
string dd = "00";
string mm = "00";
string ss = "00";
int _dd = 0;
int _mm = 0;
double __mm = 0.00;
double _ss = 0.00;

try {

if (inData == 0.00) return "00" + ((char)176).ToString() + " 00'" + " 00" + ((char)34).ToString();

_dd = (int)(inData);
__mm = (inData - _dd) * 60.0;
_mm = (int)__mm;

_ss = Math.Round((__mm - ((double)_mm)) * 60.00, 3);

dd = _dd.ToString();
mm = _mm.ToString();
ss = _ss.ToString();

fresult = dd + ((char)176).ToString() + " " + mm + "' " + ss + ((char)34).ToString();

} catch (Exception ex) {
fresult = "Error conversion degrees:" + ex.Message;
}
return fresult;
}
``````
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.