![]() |
|
|||||||
| Add-on & Script Development Creating add-ons and scripts for World Wind. |
![]() |
|
|
Thread Tools | Display Modes |
|
|
|
|
#1 |
|
Member
Join Date: May 2007
Posts: 48
![]() |
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; } }; |
|
|
|
|
|
#2 |
|
God. Root. What is difference?
Join Date: Sep 2004
Location: Eastern Pennsylvania
Posts: 2,847
![]() |
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. |
|
|
|
|
|
#3 |
|
Worldwind Developer
Join Date: Jan 2006
Location: Hobart, Australia
Posts: 754
![]() |
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: ![]() |
|
|
|
|
|
#4 |
|
Member
Join Date: May 2007
Posts: 48
![]() |
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 ![]() |
|
|
|
|
|
#5 |
|
Member
Join Date: Dec 2004
Posts: 59
![]() |
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. |
|
|
|
|
|
#6 |
|
What?
Join Date: Apr 2005
Location: San Francisco, California
Posts: 2,461
![]() |
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.
|
|
|
|
|
|
#7 |
|
Senior Member
Join Date: Aug 2005
Posts: 337
![]() |
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. |
|
|
|
|
|
#8 |
|
Member
Join Date: May 2007
Posts: 48
![]() |
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. |
|
|
|
|
|
#9 | |
|
What?
Join Date: Apr 2005
Location: San Francisco, California
Posts: 2,461
![]() |
Quote:
![]() 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. |
|
|
|
|
|
|
#10 | |
|
Senior Member
Join Date: Aug 2005
Posts: 337
![]() |
Yah, post it. Should be interesting to fiddle with.
Nigel Quote:
|
|
|
|
|
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
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 |