【问题标题】:Converting UTM (wsg84) coordinates to Latitude and Longitude将 UTM (wsg84) 坐标转换为纬度和经度
【发布时间】:2011-02-11 00:02:51
【问题描述】:

我一直在寻找一种将一组 UTM 坐标转换为纬度和经度的巧妙方法(显然在这里和谷歌上)。我有坐标,我知道它们在哪个区域,但是如何将其转换为纬度和经度?我希望会有某种课程至少可以为我带来一些魔力,但似乎并非如此:(

对此有何建议?

我知道可以做到,因为这个转换器似乎工作得很好Geographic/UTM Coordinate Converter

非常感谢任何输入! :)

谢谢!

【问题讨论】:

  • 两个很好的答案! :) 非常感谢。我通过从给定地址找到 Lat 和 Lon 来修复它有点不同。不是最简洁的编程方式,但它确实有效。不过,我将探索 ProjNet 库。再次感谢:)

标签: c# bing-maps latitude-longitude utm


【解决方案1】:

这里是:

 public static void ToLatLon(double utmX, double utmY, string utmZone, out double latitude, out double longitude)
    {
        bool isNorthHemisphere = utmZone.Last() >= 'N';

        var diflat = -0.00066286966871111111111111111111111111;
        var diflon = -0.0003868060578;

        var zone = int.Parse(utmZone.Remove(utmZone.Length - 1));
        var c_sa = 6378137.000000;
        var c_sb = 6356752.314245;
        var e2 = Math.Pow((Math.Pow(c_sa,2) - Math.Pow(c_sb,2)),0.5)/c_sb;
        var e2cuadrada = Math.Pow(e2,2);
        var c = Math.Pow(c_sa,2) / c_sb;
        var x = utmX - 500000;
        var y = isNorthHemisphere ? utmY : utmY - 10000000;

        var s = ((zone * 6.0) - 183.0);
        var lat = y / (c_sa * 0.9996);
        var v = (c / Math.Pow(1 + (e2cuadrada * Math.Pow(Math.Cos(lat), 2)), 0.5)) * 0.9996;
        var a = x / v;
        var a1 = Math.Sin(2 * lat);
        var a2 = a1 * Math.Pow((Math.Cos(lat)), 2);
        var j2 = lat + (a1 / 2.0);
        var j4 = ((3 * j2) + a2) / 4.0;
        var j6 = ((5 * j4) + Math.Pow(a2 * (Math.Cos(lat)), 2)) / 3.0;
        var alfa = (3.0 / 4.0) * e2cuadrada;
        var beta = (5.0 / 3.0) * Math.Pow(alfa, 2);
        var gama = (35.0 / 27.0) * Math.Pow(alfa, 3);
        var bm = 0.9996 * c * (lat - alfa * j2 + beta * j4 - gama * j6);
        var b = (y - bm) / v;
        var epsi = ((e2cuadrada * Math.Pow(a, 2)) / 2.0) * Math.Pow((Math.Cos(lat)), 2);
        var eps = a * (1 - (epsi / 3.0));
        var nab = (b * (1 - epsi)) + lat;
        var senoheps = (Math.Exp(eps) - Math.Exp(-eps)) / 2.0;
        var delt  = Math.Atan(senoheps/(Math.Cos(nab) ) );
        var tao = Math.Atan(Math.Cos(delt) * Math.Tan(nab));

        longitude = ((delt * (180.0 / Math.PI)) + s) + diflon;
        latitude = ((lat + (1 + e2cuadrada * Math.Pow(Math.Cos(lat), 2) - (3.0 / 2.0) * e2cuadrada * Math.Sin(lat) * Math.Cos(lat) * (tao - lat)) * (tao - lat)) * (180.0 / Math.PI)) + diflat;
    }

【讨论】:

  • 感谢顽皮!我只是为我改变这条线,因为我在巴西 udng。 bool isNorthHemisphere = utmZone.Last() == 'N' ?真假; var diflat = 0.0000628696687111111111111111111111111; //-0.0006628696687111111111111111111111111; var diflon = -0.0003868060578;
  • 我的 diff 长度为 1.6+。你能解释变量,如 s、v、a、a1、a2、j2、j4 等吗?我的位置可能有不同的值,如下所示:角度单位:度数(0.017453292519943299) Central_Meridian:55.333333 逆展平:298.257223563
【解决方案2】:

看看这个 .NET 库 http://projnet.codeplex.com/ 。这应该对你的情况有所帮助

【讨论】:

【解决方案3】:

此网站上有可用的 c++ 代码: http://www.gpsy.com/gpsinfo/geotoutm/

将页面向下移动到“源代码”标题,然后在底部查找这些文件:

查克·甘茨

附件:LatLong-UTMconversion.cpp(以文本文件形式在线查看) LatLong-UTMconversion.h(以文本文件形式在线查看) UTMConversions.cpp(以文本文件形式在线查看) SwissGrid.cpp(以文本文件形式在线查看) constants.h(以文本文件形式在线查看)

例如第一个文件链接到: www.gpsy.com/gpsinfo/geotoutm/gantz/LatLong-UTMconversion.cpp 等等

这里有双向的功能:UTM 到 Lat Long,反之亦然。 如果你在别处看,有此代码的 python 版本。 例如 在 code.google.com/p/pys60gps/source/browse/trunk/lib/LatLongUTMconversion.py?r=246

其中一些还有 c# 版本: 在 mediakey.dk/~cc/convert-northing-and-easting-utm-to-longitude-and-latitude/

祝你好运。

【讨论】:

    【解决方案4】:

    我做了一个从 javascript 库到 C# 的移植,我已经测试过它并且运行良好,你可以看看它here

    【讨论】:

    • 警告:您的端口有错误;我已经针对不同的在线转换器进行了测试。
    • 对不起,我没有时间更正它,据我所知,utm 的 latlng 工作正常,你能帮忙让它正常工作吗?
    【解决方案5】:

    在 NuGet 上结帐 CoordinateSharp。使用它真的很容易做到这一点。

     //Example
     UniversalTransverseMercator utm = new UniversalTransverseMercator("Q", 14, 581943.5, 2111989.8);
     Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
    

    【讨论】:

    • 仅供参考,这是为商业用途付费。
    • 仅当商业软件是闭源的。如果不是,这只是终身使用和无限分发的一小笔一次性费用。
    【解决方案6】:

    使用此代码:

         public static void UTMToLatLon(double Easting, double Northing, double Zone, double Hemi, out double latitude, out double longitude)
        {
            double DtoR = Math.PI / 180, RtoD = 180 / Math.PI;
            double a = 6378137, f = 0.00335281066474748071984552861852, northernN0 = 0, southernN0 = 10000000, E0 = 500000, 
                n = f / (2 - f), k0 = 0.9996,
                A = a * (1 + (1 / 4) * Math.Pow(n, 2) + (1 / 64) * Math.Pow(n, 4) + (1 / 256) * Math.Pow(n, 6) + (25 / 16384) * Math.Pow(n, 8) + (49 / 65536) * Math.Pow(n, 10)) / (1 + n),             
                beta1 = n / 2 - (2 / 3) * Math.Pow(n, 2) + (37 / 96) * Math.Pow(n, 3) - (1 / 360) * Math.Pow(n, 4) - (81 / 512) * Math.Pow(n, 5) + (96199 / 604800) * Math.Pow(n, 6) - (5406467 / 38707200) * Math.Pow(n, 7) + (7944359 / 67737600) * Math.Pow(n, 8) - (7378753979 / 97542144000) * Math.Pow(n, 9) + (25123531261 / 804722688000) * Math.Pow(n, 10), 
                beta2 = (1 / 48) * Math.Pow(n, 2) + (1 / 15) * Math.Pow(n, 3) - (437 / 1440) * Math.Pow(n, 4) + (46 / 105) * Math.Pow(n, 5) - (1118711 / 3870720) * Math.Pow(n, 6) + (51841 / 1209600) * Math.Pow(n, 7) + (24749483 / 348364800) * Math.Pow(n, 8) - (115295683 / 1397088000) * Math.Pow(n, 9) + (5487737251099 / 51502252032000) * Math.Pow(n, 10), 
                beta3 = (17 / 480) * Math.Pow(n, 3) - (37 / 840) * Math.Pow(n, 4) - (209 / 4480) * Math.Pow(n, 5) + (5569 / 90720) * Math.Pow(n, 6) + (9261899 / 58060800) * Math.Pow(n, 7) - (6457463 / 17740800) * Math.Pow(n, 8) + (2473691167 / 9289728000) * Math.Pow(n, 9) - (852549456029 / 20922789888000) * Math.Pow(n, 10), 
                beta4 = (4397 / 161280) * Math.Pow(n, 4) - (11 / 504) * Math.Pow(n, 5) - (830251 / 7257600) * Math.Pow(n, 6) + (466511 / 2494800) * Math.Pow(n, 7) + (324154477 / 7664025600) * Math.Pow(n, 8) - (937932223 / 3891888000) * Math.Pow(n, 9) - (89112264211 / 5230697472000) * Math.Pow(n, 10),
                beta5 = (4583 / 161280) * Math.Pow(n, 5) - (108847 / 3991680) * Math.Pow(n, 6) - (8005831 / 63866880) * Math.Pow(n, 7) + (22894433 / 124540416) * Math.Pow(n, 8) + (112731569449 / 557941063680) * Math.Pow(n, 9) - (5391039814733 / 10461394944000) * Math.Pow(n, 10),
                beta6 = (20648693 / 638668800) * Math.Pow(n, 6) - (16363163 / 518918400) * Math.Pow(n, 7) - (2204645983 / 12915302400) * Math.Pow(n, 8) + (4543317553 / 18162144000) * Math.Pow(n, 9) + (54894890298749 / 167382319104000) * Math.Pow(n, 10),
                beta7 = (219941297 / 5535129600) * Math.Pow(n, 7) - (497323811 / 12454041600) * Math.Pow(n, 8) - (79431132943 / 332107776000) * Math.Pow(n, 9) + (4346429528407 / 12703122432000) * Math.Pow(n, 10),
                beta8 = (191773887257 / 3719607091200) * Math.Pow(n, 8) - (17822319343 / 336825216000) * Math.Pow(n, 9) - (497155444501631 / 1422749712384000) * Math.Pow(n, 10),
                beta9 = (11025641854267 / 158083301376000) * Math.Pow(n, 9) - (492293158444691 / 6758061133824000) * Math.Pow(n, 10),
                beta10 = (7028504530429621 / 72085985427456000) * Math.Pow(n, 10),
                delta1 = 2 * n - (2 / 3) * Math.Pow(n, 2) - 2 * Math.Pow(n, 3), 
                delta2 = (7 / 3) * Math.Pow(n, 2) - (8 / 5) * Math.Pow(n, 3), 
                delta3 = (56 / 15) * Math.Pow(n, 3),
                ksi = (Northing / 100 - northernN0) / (k0 * A), eta = (Easting / 100 - E0) / (k0 * A),
                ksi_prime = ksi - (beta1 * Math.Sin(2 * ksi) * Math.Cosh(2 * eta) + beta2 * Math.Sin(4 * ksi) * Math.Cosh(4 * eta) + beta3 * Math.Sin(6 * ksi) * Math.Cosh(6 * eta) + beta4 * Math.Sin(8 * ksi) * Math.Cosh(8 * eta) + beta5 * Math.Sin(10 * ksi) * Math.Cosh(10 * eta) + 
                            beta6 * Math.Sin(12 * ksi) * Math.Cosh(12 * eta) + beta7 * Math.Sin(14 * ksi) * Math.Cosh(14 * eta) + beta8 * Math.Sin(16 * ksi) * Math.Cosh(16 * eta) + beta9 * Math.Sin(18 * ksi) * Math.Cosh(18 * eta) + beta10 * Math.Sin(20 * ksi) * Math.Cosh(20 * eta)),
                eta_prime = eta - (beta1 * Math.Cos(2 * ksi) * Math.Sinh(2 * eta) + beta2 * Math.Cos(4 * ksi) * Math.Sinh(4 * eta) + beta3 * Math.Cos(6 * ksi) * Math.Sinh(6 * eta)),
                sigma_prime = 1 - (2 * beta1 * Math.Cos(2 * ksi) * Math.Cosh(2 * eta) + 2 * beta2 * Math.Cos(4 * ksi) * Math.Cosh(4 * eta) + 2 * beta3 * Math.Cos(6 * ksi) * Math.Cosh(6 * eta)),
                taw_prime = 2 * beta1 * Math.Sin(2 * ksi) * Math.Sinh(2 * eta) + 2 * beta2 * Math.Sin(4 * ksi) * Math.Sinh(4 * eta) + 2 * beta3 * Math.Sin(6 * ksi) * Math.Sinh(6 * eta),
                ki = Math.Asin(Math.Sin(ksi_prime) / Math.Cosh(eta_prime));
    
            latitude = (ki + delta1 * Math.Sin(2 * ki) + delta2 * Math.Sin(4 * ki) + delta3 * Math.Sin(6 * ki)) * RtoD;
            double longitude0 = Zone * 6 * DtoR  - 183 * DtoR ;
            longitude = (longitude0 + Math.Atan(Math.Sinh(eta_prime) / Math.Cos(ksi_prime))) * RtoD;
        }
    

    此代码比其他代码准确得多。

    【讨论】:

    • 您需要解释代码并且可能是源代码。至少证明你的答案比其他部分“更准确”。
    • 我用来获取这些方程的来源是:linklink我将此代码与为 C# 准备的一些标头进行了比较,我发现这些更准确。我还将它与页面中的其他答案进行了比较。
    • Re“我也把它和页面中的其他答案进行了比较。” 比较如何?你有任何具体的测试结果证明这更准确吗?
    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2015-07-13
    • 2013-09-09
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2020-02-23
    相关资源
    最近更新 更多