Lambert72到LatLong C#

时间:2016-11-06 09:55:39

标签: c# coordinate-transformation

我正在搜索将Lambet72坐标转换为纬度/经度的算法。 因此,例如Lambert72坐标148990,169450必须转换为50.83546802746704,4.354415218851164,但大多数算法都有一点偏移(见附件)。

Image 1

Image 2

这是我发现的算法之一,它很接近,但仍有错误。

有人有更好的算法吗?

static void Lambert72ToLatLong(double x, double y, ref double longitude, ref double latitude)
    {
        const double n = 0.77164219;
        const double F = 1.81329763;
        const double thetaFudge = 0.00014204;
        const double e = 0.08199189;
        const double a = 6378388;
        const double xDiff = 150000;
        const double yDiff = 5400088.44;
        const double theta0 = 0.07604294;

        double xReal = xDiff-x;
        double yReal = yDiff-y;

        double rho = Math.Sqrt(xReal*xReal + yReal * yReal);
        double theta = Math.Atan(xReal/-yReal);

        longitude = (theta0 + (theta + thetaFudge) / n) * 180 / Math.PI;
        latitude = 0;
        for(int i=0; i<10; ++i)
        {
            latitude = (2 * Math.Atan(Math.Pow(F * a / rho, 1 / n) * Math.Pow((1 + e * Math.Sin(latitude)) / (1 - e * Math.Sin(latitude)), e / 2))) - Math.PI / 2;
        }
        latitude *= 180 / Math.PI;
    }

2 个答案:

答案 0 :(得分:0)

您必须更正

的值
         xDiff

      yDiff

正确的值应为

        xDiff=149910;
        yDiff=5400150;

您还必须更正

        i<10 

成为

        i<5
用于计算纬度的for循环内部的

。然后你会得到想要的结果。 希望这些帮助!

答案 1 :(得分:0)

您似乎正在尝试将Lambert72(比利时Dattum 72 LCC 3p)转换为 WGS84 GPS坐标。因此,在转换为球面纬度后 经度坐标,必须执行额外的步骤才能结束 使用WGS84坐标。这是C#中的替代代码,具有完整转换 Lambert72到WGS74的符合所需的十进制数,如 您可以轻松验证引用图像中显示的坐标。

 static void Lambert72toWGS84latlong(double X, double Y)
 {
 double LongRef = 0.076042943;        //
 double nLamb = 0.7716421928;
 double aCarre = Math.Pow(6378388.0,2.0);
 double bLamb  = 6378388.0 * (1.0 - (1.0 / 297.0));
 double eCarre = (aCarre - Math.Pow(bLamb,  2.0)) / aCarre;
 double KLamb = 11565915.812935;

 double eLamb = Math.Sqrt(eCarre);
 double eSur2 = eLamb / 2.0;

 double Tan1 = (X - 150000.012) / (5400088.437 - Y);
 double Lambda = LongRef + (1.0 / nLamb) * (0.000142043 + Math.Atan(Tan1));
 double RLamb = Math.Sqrt(Math.Pow((X - 150000.012) , 2.0) + Math.Pow   ((5400088.437 - Y) ,2.0));

 double TanZDemi = Math.Pow((RLamb / KLamb),(1.0 / nLamb));
 double Lati1 = 2.0 * Math.Atan(TanZDemi);

 double eSin;
 double Mult1, Mult2, Mult;
 double LatiN, Diff;

 double lat, lng ;
 int i=0; 
 do
  {
   eSin = eLamb * Math.Sin(Lati1);
   Mult1 = 1.0 - eSin;
   Mult2 = 1.0 + eSin;
   Mult = Math.Pow((Mult1 / Mult2) , (eLamb / 2.0));
   LatiN = (Math.PI / 2.0) - (2.0 * (Math.Atan(TanZDemi * Mult)));
   Diff = LatiN - Lati1;
   Lati1 = LatiN;
   i++;
  } while (Math.Abs(Diff)> 0.0000000277777);


  lat=LatiN;
  lng=Lambda;

  double SinLat = Math.Sin(lat);
  double SinLng = Math.Sin(lng);
  double CoSinLat = Math.Cos(lat);
  double CoSinLng = Math.Cos(lng);

  double dx = -125.8;
  double dy = 79.9;
  double dz = -100.5;
  double da = -251.0;
  double df = -0.000014192702;

  double LWf = 1.0 / 297.0;
  double LWa = 6378388.0;
  double LWb = (1 - LWf) * LWa;
  double LWe2 = (2.0 * LWf) - (LWf * LWf);
  double Adb = 1.0 / (1.0 - LWf);

  double Rn = LWa / Math.Sqrt(1.0 - LWe2 * SinLat * SinLat);    
  double Rm = LWa * (1 - LWe2) /Math.Pow((1.0 - LWe2 * lat * lat) ,1.5); 
  double DLat = -dx * SinLat * CoSinLng - dy * SinLat * SinLng + dz * CoSinLat;
  DLat = DLat + da * (Rn * LWe2 * SinLat * CoSinLat) / LWa;
  DLat = DLat + df * (Rm * Adb + Rn / Adb) * SinLat * CoSinLat;
  DLat = DLat / (Rm + 0.0);

  double DLng = (-dx * SinLng + dy * CoSinLng) / ((Rn + 0.0) * CoSinLat);
  double Dh = dx * CoSinLat * CoSinLng + dy * CoSinLat * SinLng + dz * SinLat;
  Dh = Dh - da * LWa / Rn + df * Rn * lat * lat / Adb;

  double LatWGS84 = ((lat + DLat) * 180.0) / Math.PI;
  double LngWGS84 = ((lng + DLng) * 180.0) / Math.PI;

  MessageBox.Show("WGS84-Latitude=" + LatWGS84.ToString("###.######") + 
  "--WGS84 Longitude=" + LngWGS84.ToString("###.######"));

  }

希望这些有用。

相关问题