PHP: Format Latitude and Longitude with degrees, m

2019-01-24 14:07发布

问题:

How can I convert this:

26.72773551940918

Into something like this:

22°12'42"N

The trick here is that the coordinates are, actually Latitude and Longitude, I just need to format them correctly.

回答1:

You can find functions to do that here

<?php

function DMStoDEC($deg,$min,$sec)
{

// Converts DMS ( Degrees / minutes / seconds ) 
// to decimal format longitude / latitude

    return $deg+((($min*60)+($sec))/3600);
}    

function DECtoDMS($dec)
{

// Converts decimal longitude / latitude to DMS
// ( Degrees / minutes / seconds ) 

// This is the piece of code which may appear to 
// be inefficient, but to avoid issues with floating
// point math we extract the integer part and the float
// part by using a string function.

    $vars = explode(".",$dec);
    $deg = $vars[0];
    $tempma = "0.".$vars[1];

    $tempma = $tempma * 3600;
    $min = floor($tempma / 60);
    $sec = $tempma - ($min*60);

    return array("deg"=>$deg,"min"=>$min,"sec"=>$sec);
}    

?>


回答2:

The lat/lon coords are written in (roughly speaking) a base-60 numeral system. Here's how you convert them:

function fraction_to_min_sec($coord)
{
  $isnorth = $coord>=0;
  $coord = abs($coord);
  $deg = floor($coord);
  $coord = ($coord-$deg)*60;
  $min = floor($coord);
  $sec = floor(($coord-$min)*60);
  return array($deg, $min, $sec, $isnorth ? 'N' : 'S');
  // or if you want the string representation
  return sprintf("%d&deg;%d'%d\"%s", $deg, $min, $sec, $isnorth ? 'N' : 'S');
}

I say my function has better numerical stability than @SeRPRo's one.



回答3:

Here's one where you pass in the latitude,longitude in DMS values and returns the converted DMS string. Easy and simple

function DECtoDMS($latitude, $longitude)
{
    $latitudeDirection = $latitude < 0 ? 'S': 'N';
    $longitudeDirection = $longitude < 0 ? 'W': 'E';

    $latitudeNotation = $latitude < 0 ? '-': '';
    $longitudeNotation = $longitude < 0 ? '-': '';

    $latitudeInDegrees = floor(abs($latitude));
    $longitudeInDegrees = floor(abs($longitude));

    $latitudeDecimal = abs($latitude)-$latitudeInDegrees;
    $longitudeDecimal = abs($longitude)-$longitudeInDegrees;

    $_precision = 3;
    $latitudeMinutes = round($latitudeDecimal*60,$_precision);
    $longitudeMinutes = round($longitudeDecimal*60,$_precision);

    return sprintf('%s%s° %s %s %s%s° %s %s',
        $latitudeNotation,
        $latitudeInDegrees,
        $latitudeMinutes,
        $latitudeDirection,
        $longitudeNotation,
        $longitudeInDegrees,
        $longitudeMinutes,
        $longitudeDirection
    );

}


回答4:

Here is the opposite when you have DMS string and need it as float number (contains unicode characters):

//e.g.
$dec = dms_to_dec("-18° 51' 30.5697\"");

/**
 * Convert a coordinate in dms to dec
 *
 * @param string $dms coordinate
 * @return float
 */
function dms_to_dec($dms)
{
    $dms = stripslashes($dms);
    $neg = (preg_match('/[SWO]/i', $dms) == 0) ? 1 : -1;
    $dms = preg_replace('/(^\s?-)|(\s?[NSEWO]\s?)/i', '', $dms);
    $pattern = "/(\\d*\\.?\\d+)(?:[°ºd: ]+)(\\d*\\.?\\d+)*(?:['m′: ])*(\\d*\\.?\\d+)*[\"s″ ]?/i";
    $parts = preg_split($pattern, $dms, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    if (!$parts) {
        return;
    }
    // parts: 0 = degree, 1 = minutes, 2 = seconds
    $d = isset($parts[0]) ? (float)$parts[0] : 0;
    $m = isset($parts[1]) ? (float)$parts[1] : 0;
    if (strpos($dms, ".") > 1 && isset($parts[2])) {
        $m = (float)($parts[1] . '.' . $parts[2]);
        unset($parts[2]);
    }
    $s = isset($parts[2]) ? (float)$parts[2] : 0;
    $dec = ($d + ($m/60) + ($s/3600))*$neg; 
    return $dec;
}