Solved

Conversion to UTM

Posted on 2010-09-15
5
1,535 Views
Last Modified: 2012-05-10
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
Comment
Question by:ioustinos_sarris
5 Comments
 
LVL 3

Accepted Solution

by:
Bigboj earned 500 total points
ID: 33680463
Hi!

This is the C# code:

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

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 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 EquatorialRadius;
public double eccentricitySquared;

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

Expert Comment

by:klakkas
ID: 33680504
In general, when I need to convert between Coordinate Systems, I use proj4:
http://trac.osgeo.org/proj/
The .NET api is here:
http://download.osgeo.org/proj/proj446_win32_bin.zip

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
 
LVL 3

Expert Comment

by:Bigboj
ID: 33680509
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 LatRad As Double = Lat*deg2rad
Dim LongRad As Double = LongTemp*deg2rad
Dim LongOriginRad As Double
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
LongOriginRad = LongOrigin * deg2rad
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_Renamed = 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 = 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)
UTMNorthing = CDbl(k0*(M+N*Math.Tan(LatRad)*(A_Renamed*A_Renamed/2+(5-T+9*C+4*C*C)*A_Renamed*A_Renamed*A_Renamed*A_Renamed/24+ (61-58*T+T*T+600*C-330*eccPrimeSquared)*A_Renamed*A_Renamed*A_Renamed*A_Renamed*A_Renamed*A_Renamed/720)))
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 EquatorialRadius As Double
Public eccentricitySquared As Double
Public Sub New(ByVal name As String, ByVal radius As Double, ByVal ecc As Double)
ellipsoidName = name
EquatorialRadius = radius
eccentricitySquared = ecc
End Sub
End Class
0
 

Author Comment

by:ioustinos_sarris
ID: 33680851
@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
 
LVL 3

Expert Comment

by:pnedic
ID: 33681013
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;

}

Open in new window

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This video discusses moving either the default database or any database to a new volume.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now