Open source PHP function for converting UTM coordinates to latitude and longitude?

后端 未结 8 1660
别那么骄傲
别那么骄傲 2020-12-16 04:53

I\'m making a PHP application involving Google Maps. Maps only accepts lat&lng pairs, and the data I want to display comes only with UTM style coordinat

相关标签:
8条回答
  • 2020-12-16 05:17

    You asked for PHP, but here is javascript. Just throw in some '$' and you should be good ;). This returns Lat/Lon in WGS84. No warranties, use at your own risk.

    ////////////////////////////////////////////////////////////////////////////////////////////
    //
    // 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
    }
    
    0 讨论(0)
  • 2020-12-16 05:17

    Another possibility is the package proj4php (https://github.com/proj4php/proj4php). Very powerful and it allows converting from and to many different coordinate systems.

    0 讨论(0)
  • 2020-12-16 05:21

    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);
        $d13 = rad2deg($d14);
        $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
        );
    }
    ?>
    
    0 讨论(0)
  • 2020-12-16 05:21

    For completeness another option for people that is packaged up in Composer is https://packagist.org/packages/php-coord/php-coord

    It's not that well documented but it looks like with a combination of Easting, Northing and Zone you can return the Latitude and Longitude. eg:

    $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";
    

    Note it doesn't seem as accurate as gPoint mentioned above.

    0 讨论(0)
  • 2020-12-16 05:22

    I know it's late to answer this question but since I couldn't use any of the above codes, I wrote my own version which is actually very easy to use. This is the address: https://github.com/maroofi/coordinates To convert UTM to LatLong:

    utm2ll(729286.9550018794,4021544.8279992654,40,true); 
    

    output:

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

    To convert LatLong to UTM:

    ll2utm(36.311665575277935,59.55385813725379);
    

    output:

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

    Hope it helps.

    0 讨论(0)
  • 2020-12-16 05:23

    The results from the script posted is a little of what i expected, but i found a tool on http://www.uwgb.edu/dutchs/usefuldata/ConvertUTMNoOZ.HTM which give me the results i expect. I have made a PHP version of it here: https://gist.github.com/datagutten/8083549

    0 讨论(0)
提交回复
热议问题