World Wind Forums

Go Back   World Wind Forums > WorldWind Development (Other) > Add-on & Script Development

Add-on & Script Development Creating add-ons and scripts for World Wind.

Reply
 
Thread Tools Display Modes
Old 06-18-2007, 01:55 PM   #1
Hactic
Member
 
Join Date: May 2007
Posts: 48
Hactic is on a distinguished road
Default C# code to convert DD to UTM .. here it is !!

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 . 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;
}
};
Hactic is offline   Reply With Quote
Old 06-18-2007, 02:01 PM   #2
TomServo
God. Root. What is difference?
 
TomServo's Avatar
 
Join Date: Sep 2004
Location: Eastern Pennsylvania
Posts: 2,847
TomServo
Default

Nice.. I posted the URL to the forum to let the other devs take a peak.
__________________


Earth is Square blog

PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this forum post, in any manner whatsoever, will increase the amount of disorder in the universe. Although no liability is implied herein, the consumer is warned that this process will ultimately lead to the heat death of the universe.
TomServo is offline   Reply With Quote
Old 06-18-2007, 02:02 PM   #3
what_nick
Worldwind Developer
 
Join Date: Jan 2006
Location: Hobart, Australia
Posts: 754
what_nick is an unknown quantity at this point
Default Reprojection

General purpose reprojection is rather tricky. We use proj.4 as a standard reprojection library. It is part of the WorldWind SVN I was planning to make a similar method in PluginSDK.
http://proj.maptools.org/
__________________
Coding This and That in World Wind and helping new people out, as long as they don't pester too much.
Currently blogging at: http://whatnicklife.blogspot.com
Working at:
Aerometrex - http://aerometrex.com.au/blog/
Impact so far:


what_nick is offline   Reply With Quote
Old 06-18-2007, 03:49 PM   #4
Hactic
Member
 
Join Date: May 2007
Posts: 48
Hactic is on a distinguished road
Default

I couldn't agree more. I need this particular conversion for a DLL that I'm writing. I don't want to blow the DLL out of proportion so I 'hardcoded' the conversion. I couldn't see any harm in posting it.

What are you suggesting ? .. for the sake of standarisation quit posting customised code. I could go with that .. not a problem
Hactic is offline   Reply With Quote
Old 06-19-2007, 04:32 AM   #5
mdsumner
Member
 
Join Date: Dec 2004
Posts: 59
mdsumner
Default

Thanks for posting this, arguably it's better solved by other means but it's always great to find other's solutions via this or that code.

BTW, there are C# examples of running GDAL/OGR/PROJ.4 in the /csharp directory of FWTools. Not relevant given your immediate need, but they might be of interest.
mdsumner is offline   Reply With Quote
Old 06-19-2007, 04:36 AM   #6
withak
What?
 
withak's Avatar
 
Join Date: Apr 2005
Location: San Francisco, California
Posts: 2,461
withak
Default

Also keep in mind with OGR that the C# bindings are based off of the OGR C libs, so the detailed C++ documentation and examples on the fwtools site aren't of much use.
withak is offline   Reply With Quote
Old 06-19-2007, 07:12 AM   #7
nigel_ht
Senior Member
 
Join Date: Aug 2005
Posts: 337
nigel_ht
Default Nice

Nice. Using proj.4 would be nice too if reduced to a set of simple calls in pluginSDK for common stuff... That way we would abstract out what library or implementation were using.

Nigel

PS Here's a set of conversions written in PERL

http://search.cpan.org/src/GRAHAMC/G...TM-0.06/UTM.pm

Last edited by nigel_ht; 06-19-2007 at 07:17 AM.
nigel_ht is offline   Reply With Quote
Old 06-21-2007, 08:02 PM   #8
Hactic
Member
 
Join Date: May 2007
Posts: 48
Hactic is on a distinguished road
Default

Thank you all for posting back at me. I value the input. It may look like I'm re-inventing the wheel and to be honest .. that's exactly what I'm doing. I finished the code to convert UTM to Lat/long and it's working well.

I know that What_nick is making a similar projection conversion in pluginSDK, so I might as well wait to prevent me from doing double work. Currently I'm working on implementing this in MathEngine.cs. I'm thinking about posting that instead of continiously dumping code in here. Two birds with one stone. Perhaps I'm going to rattle a few dev cages and run this particular topic by them, if they're not reading it already. Although it's an open forum and that bits of code are always more than welcome , I'm still fairly new on WW and therefore unaware of any code of conduct and/or the hierachie in here.

Cheers

Last edited by Hactic; 06-21-2007 at 08:05 PM.
Hactic is offline   Reply With Quote
Old 06-21-2007, 08:09 PM   #9
withak
What?
 
withak's Avatar
 
Join Date: Apr 2005
Location: San Francisco, California
Posts: 2,461
withak
Default

Quote:
Originally Posted by Hactic View Post
I know that What_nick is making a similar projection conversion in pluginSDK, so I might as well wait to prevent me from doing double work.
Go ahead and do it anyway, I bet you finish before he does.

You can post patches here or in the irc channel. If you are going to be making a lot of changes then check with Bull_[UK] on irc to see about getting commit access.
withak is offline   Reply With Quote
Old 06-22-2007, 10:31 PM   #10
nigel_ht
Senior Member
 
Join Date: Aug 2005
Posts: 337
nigel_ht
Default

Yah, post it. Should be interesting to fiddle with.

Nigel

Quote:
Originally Posted by Hactic View Post
Thank you all for posting back at me. I value the input. It may look like I'm re-inventing the wheel and to be honest .. that's exactly what I'm doing. I finished the code to convert UTM to Lat/long and it's working well.

I know that What_nick is making a similar projection conversion in pluginSDK, so I might as well wait to prevent me from doing double work. Currently I'm working on implementing this in MathEngine.cs. I'm thinking about posting that instead of continiously dumping code in here. Two birds with one stone. Perhaps I'm going to rattle a few dev cages and run this particular topic by them, if they're not reading it already. Although it's an open forum and that bits of code are always more than welcome , I'm still fairly new on WW and therefore unaware of any code of conduct and/or the hierachie in here.

Cheers
nigel_ht is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may post new threads
You may post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
source code documentation party! ghchinoy Developers' Corner 8 10-21-2008 10:10 AM
problems buillding the Source Code asbayomie Developers' Corner 2 05-08-2007 04:01 PM
Can I code this plugin...?? Unregistered Add-on & Script Development 3 11-14-2006 03:43 PM
Code for generating trail add-ons from gpx files miguel Add-ons & Scripts 13 04-20-2005 12:32 PM
Code documentation ? grenouille Developers' Corner 1 09-24-2004 05:46 PM


All times are GMT +1. The time now is 01:25 PM.


Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.