[C#] UTM to DD and DD to UTM.

Necuno

Court Jester
Joined
Sep 27, 2005
Messages
58,566
Reaction score
3,437
Has one done this before?

Using this to check my calculations
http://www.latlong.net/lat-long-utm.html
http://www.uwgb.edu/dutchs/UsefulData/ConvertUTMNoOZ.HTM

Here's more information on the the conversion
http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.HTM
http://www.uwgb.edu/dutchs/FieldMethods/UTMSystem.htm

Most of the c# exmaples I could find are using doubles, but when I look at this one's javascript (http://www.uwgb.edu/dutchs/UsefulData/ConvertUTMNoOZ.HTM) and I go through Declarations() (line 9), at f = 1/DatumFlat[Item];//polar flattening.

Code:
	DatumEqRad = [[COLOR="#FF0000"]6378137.0[/COLOR],6378137.0,6378137.0,6378135.0,6378160.0,6378245.0,6378206.4,6378388.0,6378388.0,6378249.1,6378206.4,6377563.4,6377397.2,6377276.3];	
	DatumFlat = [[COLOR="#FF0000"]298.2572236[/COLOR], 298.2572236, 298.2572215,	298.2597208, 298.2497323, 298.2997381, 294.9786982,296.9993621, 296.9993621, 293.4660167, 294.9786982, 299.3247788, 299.1527052, 300.8021499]; 
	Item = 0;//Default
	k0 = 0.9996;//scale on central meridian
	a = DatumEqRad[Item];//equatorial radius, meters. 
[COLOR="#FF0000"]	f = 1/DatumFlat[Item];//polar flattening.[/COLOR]
	b = a*(1-f);//polar axis.
	e = Math.sqrt(1 - b*b/a*a);//eccentricity

It would be 1/298.2572236: (using WSG82, which is Item 0 of DatumFlat)

js: 0.0033528106643315514
double: 0.003352810664331551
decimal: 0.0033528106643315511638122819
calculator: 0.00335281066433155116381228192993

The thing is, the page's value at f (JS) is different from what I have at f (C#) which with a zone of 43, easting of 337183.35, northing of 218617.85 and South of Equator gives me: LON: 1.971278 / LAT: -73.536107 instead of LON: 37.857547 / LAT: -87.540331.

I know that the double thing is about precision and capacity, but js AFAIK is using a float number type? The short so far I could not get an example that actually gives same results as the two websites I use to double check it with....

Here's the rough code, I do a pologise, but it is a literal copy and paste from JS

Declarations:
Code:
      int item = 0;//WSG84
      double k0 = 0.9996;//scale on central meridian
      double a = DatumEqRad[item];//equatorial radius, meters. 
      double f = 1 / DatumFlat[item];//polar flattening.
      double b = a * (1 - f);//polar axis.
      double e = Math.Sqrt(1 - b * b / a * a);//eccentricity
      double drad = Math.PI / 180;//Convert degrees to radians)
      double latd = 0;//latitude in degrees
      double phi = 0;//latitude (north +, south -), but uses phi in reference
      double e0 = e / Math.Sqrt(1 - e * e);//e prime in reference
      double N = a / Math.Sqrt(1 - Math.Pow(e * Math.Sin(phi), 2));
      double T = Math.Pow(Math.Tan(phi), 2);
      double C = Math.Pow(e * Math.Cos(phi), 2);
      double lng = 0;//Longitude (e = +, w = -) - can't use long - reserved word
      double lng0 = 0;//longitude of central meridian
      double lngd = 0;//longitude in degrees
      double M = 0;//M requires calculation
      double x = 0;//x coordinate
      double y = 0;//y coordinate
      double k = 1;//local scale
      double utmz = 30;//utm zone
      double zcm = 0;//zone central meridian
      string DigraphLetrsE = "ABCDEFGHJKLMNPQRSTUVWXYZ";
      string DigraphLetrsN = "ABCDEFGHJKLMNPQRSTUV";
      //document.getElementById("EqRadBox").value = a;
      //document.getElementById("PolRadBox").value = b;
      //document.getElementById("FlatBox").value = f;
      //ocument.getElementById("RecipBox").value = 1 / f;
      bool OOZok = false;

UTMToDD
Code:
 //Convert UTM Coordinates to Geographic
      k0 = 0.9996;//scale on central meridian
      b = a * (1 - f);//polar axis.
      e = Math.Sqrt(1 - (b / a) * (b / a));//eccentricity
      e0 = e / Math.Sqrt(1 - e * e);//Called e prime in reference
      double esq = (1 - (b / a) * (b / a));//e squared for use in expansions
      double e0sq = e * e / (1 - e * e);// e0 squared - always even powers
      x = double.Parse(txtEasting.Text.Trim());// parseFloat(document.getElementById("UTMeBox1").value);

      //if (x<160000 || x>840000){alert("Outside permissible range of easting values \n Results may be unreliable \n Use with caution");} 
      y = double.Parse(txtNorthing.Text.Trim()); //parseFloat(document.getElementById("UTMnBox1").value);

      //alert(y)
      //if (y<0){alert("Negative values not allowed \n Results may be unreliable \n Use with caution");}
      //if (y>10000000){alert("Northing may not exceed 10,000,000 \n Results may be unreliable \n Use with caution");}

      utmz = int.Parse(txtZone.Text.Trim());// (t parseFloat(document.getElementById("UTMzBox1").value);
      zcm = 3 + 6 * (utmz - 1) - 180;//Central meridian of zone
      double e1 = (1 - Math.Sqrt(1 - e * e)) / (1 + Math.Sqrt(1 - e * e));//Called e1 in USGS PP 1395 also
      double M0 = 0;//In case origin other than zero lat - not needed for standard UTM
      M = M0 + y / k0;//Arc length along standard meridian. 

      if (chkSouth.Checked) { M = M0 + (y - 10000000) / k; }
      //if (document.getElementById("SHemBox").checked === true){M=M0+(y-10000000)/k;}

      double mu = M / (a * (1 - esq * (1 / 4 + esq * (3 / 64 + 5 * esq / 256))));
      double phi1 = mu + e1 * (3 / 2 - 27 * e1 * e1 / 32) * Math.Sin(2 * mu) + e1 * e1 * (21 / 16 - 55 * e1 * e1 / 32) * Math.Sin(4 * mu);//Footprint Latitude
      phi1 = phi1 + e1 * e1 * e1 * (Math.Sin(6 * mu) * 151 / 96 + e1 * Math.Sin(8 * mu) * 1097 / 512);
      double C1 = e0sq * Math.Pow(Math.Cos(phi1), 2);
      double T1 = Math.Pow(Math.Tan(phi1), 2);
      double N1 = a / Math.Sqrt(1 - Math.Pow(e * Math.Sin(phi1), 2));
      double R1 = N1 * (1 - e * e) / (1 - Math.Pow(e * Math.Sin(phi1), 2));
      double D = (x - 500000) / (N1 * k0);
      phi = (D * D) * (1 / 2 - D * D * (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * e0sq) / 24);
      phi = phi + Math.Pow(D, 6) * (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * e0sq - 3 * C1 * C1) / 720;
      phi = phi1 - (N1 * Math.Tan(phi1) / R1) * phi;

      //Output Latitude
      lblLatitude.Text = (Math.Floor(1000000 * phi / drad) / 1000000).ToString();
      //	document.getElementById("DDLatBox0").value = Math.Floor(1000000*phi/drad)/1000000;

      //Longitude
      lng = D * (1 + D * D * ((-1 - 2 * T1 - C1) / 6 + D * D * (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * e0sq + 24 * T1 * T1) / 120)) / Math.Cos(phi1);
      lngd = zcm + lng / drad;

      //Output Longitude
      lbllongitude.Text = (Math.Floor(1000000 * lngd) / 1000000).ToString();
      //  document.getElementById("DDLonBox0").value = Math.Floor(1000000*lngd)/1000000;


:edit
Found something that seems to be working in this thread
http://forum.worldwindcentral.com/s...TM-here-it-is-!!&p=66142&viewfull=1#post66142
 
Last edited:
Top
Sign up to the MyBroadband newsletter
X