【问题标题】:Open source PHP function for converting UTM coordinates to latitude and longitude?用于将UTM坐标转换为纬度和经度的开源PHP函数?
【发布时间】:2012-02-08 23:38:51
【问题描述】:

我正在制作一个涉及 Google 地图的 PHP 应用程序。地图只接受 lat&lng 对,而我要显示的数据仅带有 UTM 样式坐标。是否有一个开源的 PHP 函数可以从一种转换到另一种?

这样的东西会很棒:

$UTM_ZONE = '32';
$UTMX = '60329834,34';
$UTMY = '67382984,9';

$latlng = convert($UTM_ZONE, $UTMX, $UTMY);

// $latlng = now looks like
// array('lat' => '59.4472917501', 'lng' => '5.3928572425')

【问题讨论】:

    标签: php latitude-longitude utm


    【解决方案1】:

    这是PHP中的代码,非常感谢,很好用!

    <?php
    function ToLL($north, $east, $utmZone)
    { 
      // This is the lambda knot value in the reference
      $LngOrigin = Deg2Rad($utmZone * 6 - 183);
    
      // The following set of class constants define characteristics of the
      // ellipsoid, as defined my the WGS84 datum.  These values need to be
      // changed if a different dataum is used.    
    
      $FalseNorth = 0;   // South or North?
      //if (lat < 0.) FalseNorth = 10000000.  // South or North?
      //else          FalseNorth = 0.   
    
      $Ecc = 0.081819190842622;       // Eccentricity
      $EccSq = $Ecc * $Ecc;
      $Ecc2Sq = $EccSq / (1. - $EccSq);
      $Ecc2 = sqrt($Ecc2Sq);      // Secondary eccentricity
      $E1 = ( 1 - sqrt(1-$EccSq) ) / ( 1 + sqrt(1-$EccSq) );
      $E12 = $E1 * $E1;
      $E13 = $E12 * $E1;
      $E14 = $E13 * $E1;
    
      $SemiMajor = 6378137.0;         // Ellipsoidal semi-major axis (Meters)
      $FalseEast = 500000.0;          // UTM East bias (Meters)
      $ScaleFactor = 0.9996;          // Scale at natural origin
    
      // Calculate the Cassini projection parameters
    
      $M1 = ($north - $FalseNorth) / $ScaleFactor;
      $Mu1 = $M1 / ( $SemiMajor * (1 - $EccSq/4.0 - 3.0*$EccSq*$EccSq/64.0 - 5.0*$EccSq*$EccSq*$EccSq/256.0) );
    
      $Phi1 = $Mu1 + (3.0*$E1/2.0 - 27.0*$E13/32.0) * sin(2.0*$Mu1);
        + (21.0*$E12/16.0 - 55.0*$E14/32.0)           * sin(4.0*$Mu1);
        + (151.0*$E13/96.0)                          * sin(6.0*$Mu1);
        + (1097.0*$E14/512.0)                        * sin(8.0*$Mu1);
    
      $sin2phi1 = sin($Phi1) * sin($Phi1);
      $Rho1 = ($SemiMajor * (1.0-$EccSq) ) / pow(1.0-$EccSq*$sin2phi1,1.5);
      $Nu1 = $SemiMajor / sqrt(1.0-$EccSq*$sin2phi1);
    
      // Compute parameters as defined in the POSC specification.  T, C and D
    
      $T1 = tan($Phi1) * tan($Phi1);
      $T12 = $T1 * $T1;
      $C1 = $Ecc2Sq * cos($Phi1) * cos($Phi1);
      $C12 = $C1 * $C1;
      $D  = ($east - $FalseEast) / ($ScaleFactor * $Nu1);
      $D2 = $D * $D;
      $D3 = $D2 * $D;
      $D4 = $D3 * $D;
      $D5 = $D4 * $D;
      $D6 = $D5 * $D;
    
      // Compute the Latitude and Longitude and convert to degrees
      $lat = $Phi1 - $Nu1*tan($Phi1)/$Rho1 * ( $D2/2.0 - (5.0 + 3.0*$T1 + 10.0*$C1 - 4.0*$C12 - 9.0*$Ecc2Sq)*$D4/24.0 + (61.0 + 90.0*$T1 + 298.0*$C1 + 45.0*$T12 - 252.0*$Ecc2Sq - 3.0*$C12)*$D6/720.0 );
    
      $lat = Rad2Deg($lat);
    
      $lon = $LngOrigin + ($D - (1.0 + 2.0*$T1 + $C1)*$D3/6.0 + (5.0 - 2.0*$C1 + 28.0*$T1 - 3.0*$C12 + 8.0*$Ecc2Sq + 24.0*$T12)*$D5/120.0) / cos($Phi1);
    
      $lon = Rad2Deg($lon);
    
      // Create a object to store the calculated Latitude and Longitude values
      $PC_LatLon['lat'] = $lat;
      $PC_LatLon['lon'] = $lon;
    
      // Returns a PC_LatLon object
      return $PC_LatLon;
    }
    
    ?>
    

    【讨论】:

      【解决方案2】:

      我发现了一个可以完成这项工作的肮脏类。脏我的意思是函数名称很奇怪,代码的格式也不是很漂亮,但它确实可以完成这项工作。

      如果我找到更好的课程,我一定会更新这个答案

      【讨论】:

      • 一个如何使用它的例子。我从这里提取文件:gist.github.com/degerstrom/5180824 并使用它:$easting = 505716.941; $northing = 6961780.872; $zone = 56; $gPoint = new gPoint("Australian National"); $gPoint-&gt;setUTM($easting, $northing, $zone); $gPoint-&gt;convertTMtoLL(); print "Lat/Lng:" . $gPoint-&gt;Lat() . ", " . $gPoint-&gt;Long() . "\n";
      【解决方案3】:

      我知道现在回答这个问题已经很晚了,但是由于我无法使用上述任何代码,所以我编写了自己的版本,它实际上非常易于使用。 这是地址: https://github.com/maroofi/coordinates 要将 UTM 转换为 LatLong:

      utm2ll(729286.9550018794,4021544.8279992654,40,true); 
      

      输出:

      {"success":true,"attr":{"lat":36.311665575271,"lon":59.553858137274}} 
      

      将 LatLong 转换为 UTM:

      ll2utm(36.311665575277935,59.55385813725379);
      

      输出:

      {"success":true,"attr":{"x":729286.95500188,"y":4021544.8279993,"zone":40,"aboveEquator":true}} 
      

      希望对你有帮助。

      【讨论】:

      • 哥们,你是最棒的!
      【解决方案4】:

      您要求使用 PHP,但这里是 javascript。只需输入一些'$',你应该会很好;)。这将返回 WGS84 中的纬度/经度。无担保,使用风险自负。

      ////////////////////////////////////////////////////////////////////////////////////////////
      //
      // ToLL - function to compute Latitude and Longitude given UTM Northing and Easting in meters
      //
      //  Description:
      //    This function converts input north and east coordinates (meters)
      //    to the corresponding WGS84 Lat/Lon values relative to the defined
      //    UTM zone.  
      //
      //  Parameters:
      //    north   - (i) Northing (meters)
      //    east    - (i) Easting (meters)
      //    utmZone - (i) UTM Zone of the North and East parameters
      //    lat     - (o) Latitude in degrees 
      //    lon     - (o) Longitude in degrees
      //
      function ToLL(north,east,utmZone)
      { 
        // This is the lambda knot value in the reference
        var LngOrigin = DegToRad(utmZone * 6 - 183)
      
        // The following set of class constants define characteristics of the
        // ellipsoid, as defined my the WGS84 datum.  These values need to be
        // changed if a different dataum is used.    
      
        var FalseNorth = 0.   // South or North?
        //if (lat < 0.) FalseNorth = 10000000.  // South or North?
        //else          FalseNorth = 0.   
      
        var Ecc = 0.081819190842622       // Eccentricity
        var EccSq = Ecc * Ecc
        var Ecc2Sq = EccSq / (1. - EccSq)
        var Ecc2 = Math.sqrt(Ecc2Sq)      // Secondary eccentricity
        var E1 = ( 1 - Math.sqrt(1-EccSq) ) / ( 1 + Math.sqrt(1-EccSq) )
        var E12 = E1 * E1
        var E13 = E12 * E1
        var E14 = E13 * E1
      
        var SemiMajor = 6378137.0         // Ellipsoidal semi-major axis (Meters)
        var FalseEast = 500000.0          // UTM East bias (Meters)
        var ScaleFactor = 0.9996          // Scale at natural origin
      
        // Calculate the Cassini projection parameters
      
        var M1 = (north - FalseNorth) / ScaleFactor
        var Mu1 = M1 / ( SemiMajor * (1 - EccSq/4.0 - 3.0*EccSq*EccSq/64.0 -
          5.0*EccSq*EccSq*EccSq/256.0) )
      
        var Phi1 = Mu1 + (3.0*E1/2.0 - 27.0*E13/32.0) * Math.sin(2.0*Mu1)
          + (21.0*E12/16.0 - 55.0*E14/32.0)           * Math.sin(4.0*Mu1)
          + (151.0*E13/96.0)                          * Math.sin(6.0*Mu1)
          + (1097.0*E14/512.0)                        * Math.sin(8.0*Mu1)
      
        var sin2phi1 = Math.sin(Phi1) * Math.sin(Phi1)
        var Rho1 = (SemiMajor * (1.0-EccSq) ) / Math.pow(1.0-EccSq*sin2phi1,1.5)
        var Nu1 = SemiMajor / Math.sqrt(1.0-EccSq*sin2phi1)
      
        // Compute parameters as defined in the POSC specification.  T, C and D
      
        var T1 = Math.tan(Phi1) * Math.tan(Phi1)
        var T12 = T1 * T1
        var C1 = Ecc2Sq * Math.cos(Phi1) * Math.cos(Phi1)
        var C12 = C1 * C1
        var D  = (east - FalseEast) / (ScaleFactor * Nu1)
        var D2 = D * D
        var D3 = D2 * D
        var D4 = D3 * D
        var D5 = D4 * D
        var D6 = D5 * D
      
        // Compute the Latitude and Longitude and convert to degrees
        var lat = Phi1 - Nu1*Math.tan(Phi1)/Rho1 *
          ( D2/2.0 - (5.0 + 3.0*T1 + 10.0*C1 - 4.0*C12 - 9.0*Ecc2Sq)*D4/24.0
           + (61.0 + 90.0*T1 + 298.0*C1 + 45.0*T12 - 252.0*Ecc2Sq - 3.0*C12)*D6/720.0 )
      
        lat = RadToDeg(lat)
      
        var lon = LngOrigin + 
          ( D - (1.0 + 2.0*T1 + C1)*D3/6.0
            + (5.0 - 2.0*C1 + 28.0*T1 - 3.0*C12 + 8.0*Ecc2Sq + 24.0*T12)*D5/120.0) /     Math.cos(Phi1)
      
        lon = RadToDeg(lon)
      
        // Create a object to store the calculated Latitude and Longitude values
        var sendLatLon = new PC_LatLon(lat,lon)
      
        // Returns a PC_LatLon object
        return sendLatLon
      }
      

      【讨论】:

        【解决方案5】:

        source link

        <?php
        function LatLonPointUTMtoLL($f, $f1, $j = 32) {
            
            $d = 0.99960000000000004;
            $d1 = 6378137;
            $d2 = 0.0066943799999999998;
            
            $d4 = (1 - sqrt(1 - $d2)) / (1 + sqrt(1 - $d2));
            $d15 = $f1 - 500000;
            $d16 = $f;
            $d11 = (($j - 1) * 6 - 180) + 3;
            $d3 = $d2 / (1 - $d2);
            $d10 = $d16 / $d;
            $d12 = $d10 / ($d1 * (1 - $d2 / 4 - (3 * $d2 * $d2) / 64 - (5 * pow($d2, 3)) / 256));
            $d14 = $d12 + ((3 * $d4) / 2 - (27 * pow($d4, 3)) / 32) * sin(2 * $d12) + ((21 * $d4 * $d4) / 16 - (55 * pow($d4, 4)) / 32) * sin(4 * $d12) + ((151 * pow($d4, 3)) / 96) * sin(6 * $d12);
            $d5 = $d1 / sqrt(1 - $d2 * sin($d14) * sin($d14));
            $d6 = tan($d14) * tan($d14);
            $d7 = $d3 * cos($d14) * cos($d14);
            $d8 = ($d1 * (1 - $d2)) / pow(1 - $d2 * sin($d14) * sin($d14) , 1.5);
            $d9 = $d15 / ($d5 * $d);
            $d17 = $d14 - (($d5 * tan($d14)) / $d8) * ((($d9 * $d9) / 2 - (((5 + 3 * $d6 + 10 * $d7) - 4 * $d7 * $d7 - 9 * $d3) * pow($d9, 4)) / 24) + (((61 + 90 * $d6 + 298 * $d7 + 45 * $d6 * $d6) - 252 * $d3 - 3 * $d7 * $d7) * pow($d9, 6)) / 720);
            $d17 = rad2deg($d17);
            $d18 = (($d9 - ((1 + 2 * $d6 + $d7) * pow($d9, 3)) / 6) + (((((5 - 2 * $d7) + 28 * $d6) - 3 * $d7 * $d7) + 8 * $d3 + 24 * $d6 * $d6) * pow($d9, 5)) / 120) / cos($d14);
            $d18 = $d11 + rad2deg($d18);
            return array(
                'lat' => $d17,
                'lng' => $d18
            );
        }
        ?>
        

        【讨论】:

          【解决方案6】:

          为了完整起见,在 Composer 中打包的另一个选项是 https://packagist.org/packages/php-coord/php-coord

          它的文档记录不是很好,但看起来结合了东向、北向和区域,您可以返回纬度和经度。例如:

          $easting = 505716.941;
          $northing =  6961780.872;
          $zone = 56;
          
          $UTMRef = new PHPCoord\UTMRef($easting, $northing, NULL, $zone, $zone);
          $LatLng = $UTMRef->toLatLng();
          
          print "Lat/Lng:" . $LatLng->getLat() . ", " . $LatLng->getLng() . "\n";
          

          请注意,它似乎不如上面提到的 gPoint 准确。

          【讨论】:

            【解决方案7】:

            发布的脚本的结果与我预期的有点不同,但我在http://www.uwgb.edu/dutchs/usefuldata/ConvertUTMNoOZ.HTM 上找到了一个工具,它给了我预期的结果。 我在这里做了一个 PHP 版本:https://gist.github.com/datagutten/8083549

            【讨论】:

              【解决方案8】:

              另一种可能性是包 proj4php (https://github.com/proj4php/proj4php)。非常强大,它允许在许多不同的坐标系之间进行转换。

              【讨论】:

                猜你喜欢
                • 2011-02-11
                • 1970-01-01
                • 2021-07-18
                • 2019-12-04
                • 2015-07-13
                • 2013-09-09
                • 2013-02-14
                • 1970-01-01
                • 2018-08-30
                相关资源
                最近更新 更多