170 lines
7.1 KiB
C#
170 lines
7.1 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Text;
|
||
|
|
||
|
namespace Safedispatch_4_0
|
||
|
{
|
||
|
class LatLngUTM
|
||
|
{
|
||
|
Double deg2rad = 3.141592654 / 180;
|
||
|
|
||
|
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());
|
||
|
}
|
||
|
|
||
|
public 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(LatRad));
|
||
|
T = Math.Tan(LatRad) * Math.Tan(LatRad);
|
||
|
C = eccPrimeSquared * Math.Cos(LatRad) * Math.Cos(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;
|
||
|
}
|
||
|
|
||
|
//LatLongtoUTM(42.1325, 25.3641, out UTMn, out UTMe, out s);
|
||
|
//RadMessageBox.Show("UTM N:" + UTMn.ToString("###,###,### meters") + " UTM E: " + UTMe.ToString("###,###,### meters") + " s: " + s);
|
||
|
|
||
|
public void LatLongtoDeg(double Lat, double Long, out String LatDeg, out String LongDeg)
|
||
|
{
|
||
|
String s;
|
||
|
int tmpint;
|
||
|
Double tmp;
|
||
|
tmpint = (int)System.Math.Truncate(Lat);
|
||
|
s = "";
|
||
|
s = s+tmpint.ToString()+Convert.ToChar(176);//grad
|
||
|
tmp = System.Math.Abs(Lat) - System.Math.Abs(tmpint);
|
||
|
tmp = tmp * 60;
|
||
|
tmpint = (int)System.Math.Truncate(tmp);
|
||
|
s = s + tmpint.ToString() + Convert.ToChar(39);//minute
|
||
|
tmp = tmp - tmpint;
|
||
|
tmp = tmp * 60;
|
||
|
tmpint = (int)System.Math.Truncate(tmp);
|
||
|
s = s + tmpint.ToString() + Convert.ToChar(34);//sec
|
||
|
LatDeg = s;
|
||
|
tmpint = (int)System.Math.Truncate(Long);
|
||
|
s = "";
|
||
|
s = s + tmpint.ToString() + Convert.ToChar(176);//grad
|
||
|
tmp = System.Math.Abs(Long) - System.Math.Abs(tmpint);
|
||
|
tmp = tmp * 60;
|
||
|
tmpint = (int)System.Math.Truncate(tmp);
|
||
|
s = s + tmpint.ToString() + Convert.ToChar(39);//minute
|
||
|
tmp = tmp - tmpint;
|
||
|
tmp = tmp * 60;
|
||
|
tmpint = (int)System.Math.Truncate(tmp);
|
||
|
s = s + tmpint.ToString() + Convert.ToChar(34);//sec
|
||
|
LongDeg = s;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
};
|
||
|
}
|