PHP: форматировать широту и долготу с градусами, менуэтами и секундами - PullRequest
6 голосов
/ 28 октября 2011

Как я могу преобразовать это:

26.72773551940918

На что-то вроде этого:

22°12'42"N

Хитрость в том, что координаты - это широта и долгота, мне просто нужно правильно их отформатировать.

Ответы [ 4 ]

14 голосов
/ 28 октября 2011

Вы можете найти функции для этого здесь

<?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);
}    

?>
7 голосов
/ 28 октября 2011

Координаты широты / долготы записываются (грубо говоря) в системе счисления base-60 . Вот как вы их конвертируете:

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');
}

Я говорю, что моя функция имеет лучшую числовую стабильность, чем функция @ SeRPRo.

2 голосов
/ 17 декабря 2014

Здесь вы передаете широту, долготу в значениях DMS и возвращаете преобразованную строку DMS. Легко и просто

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
    );

}
0 голосов
/ 07 января 2015

Здесь наоборот, если у вас есть строка DMS, и вам она нужна как число с плавающей запятой (содержит символы Юникода):

//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;
}
...