PHP: Форматуйте широту і довжину з градусами, менуетами і секундами

Як перетворити це:

26.72773551940918

У щось подібне:

22°12'42"N

Хитрість тут полягає в тому, що координати, насправді широта і довгота, мені просто потрібно їх правильно відформатувати.

6

4 Відповіді

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

?>
14
додано
@SERPRO: Ви знаєте, як зменшити різницю, викликану перетворенням між градусами і DMS?
додано Автор secretlm, джерело
Ласкаво просимо! :)
додано Автор SERPRO, джерело
Дякую! Це, здається, працює!
додано Автор ragulka, джерело

Координати lat/lon написані в (грубо кажучи) базовій 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°%d'%d\"%s", $deg, $min, $sec, $isnorth ? 'N' : 'S');
}

Я кажу, що моя функція має кращу числову стабільність, ніж @ SeRPRo.

6
додано
На жаль, це помилка.
додано Автор Leonid Shevtsov, джерело
@ragulka, en.wikipedia.org/wiki/Longitude : "Для розрахунків, Східний суфікс замінюється негативним знаком у західній півкулі.
додано Автор Leonid Shevtsov, джерело
Код у моїй відповіді не є моїм, це функція, знайдена. Що стосується вашої функції, я не можу сказати, краще чи ні, але я не знаю, звідки походить змінна "$ whole".
додано Автор SERPRO, джерело
Гей, як щодо того, якщо я хочу дізнатися, чи це захід чи схід?
додано Автор ragulka, джерело

Ось тут ви переходите по широті, довготі в значеннях 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
    );

}
2
додано

Ось протилежне, якщо у вас є рядок DMS і він потребує його як плаваючого числа (містить символи Unicode):

//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;
}
0
додано
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php