Javascript 中的十进制度到度分和秒

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5786025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:50:19  来源:igfitidea点击:

Decimal Degrees to Degrees Minutes And Seconds in Javascript

javascriptfunctionangle

提问by Christopher

Im trying to write a function that takes my decimal degrees (lat or long) and converts them to DMS degrees minutes seconds. I know I am meant to times the decimal point number by 60 then it's decimal again. But am a noob. Would I split the number?

我正在尝试编写一个函数,该函数采用我的十进制度数(纬度或经度)并将它们转换为 DMS 度数分秒。我知道我的意思是将小数点数字乘以 60,然后它又是小数。但我是菜鸟。我会拆分数字吗?

function ConvertDDToDMS(DD) {
    eg. DD =-42.4
    D= 42;
    M= 4*60;
    S= .M * 60;
    var DMS =

    return DMS //append Direction (N, S, E, W);
}

Am I on the right track?

我在正确的轨道上吗?

采纳答案by Aleadam

Update: I remove the part that did not make any sense (thanks cwolves!).

更新:我删除了没有任何意义的部分(感谢 cwolves!)。

Here you have yet another implementation. It won't be as short nor efficient as the previous ones, but hopefully much easier to understand.

在这里,您还有另一个实现。它不会像以前的那样简短或高效,但希望更容易理解。

To get it right, first you need to understand how the calculations are done and only then attempt to implement them. For that, pseudocode is a great option, since you write down the steps in plain English or a simplified syntax that is easy to understand, and then translate it onto the programming language of choice.

要做到正确,首先您需要了解计算是如何完成的,然后才尝试实施它们。为此,伪代码是一个很好的选择,因为您用简单的英语或易于理解的简化语法写下步骤,然后将其翻译成选择的编程语言。

I hope it's useful!

我希望它有用!

/* This is the pseudocode you need to follow:
 * It's a modified version from 
 * http://en.wikipedia.org/wiki/Geographic_coordinate_conversion#Conversion_from_Decimal_Degree_to_DMS

function deg_to_dms ( degfloat )
   Compute degrees, minutes and seconds:
   deg ← integerpart ( degfloat )
   minfloat ← 60 * ( degfloat - deg )
   min ← integerpart ( minfloat )
   secfloat ← 60 * ( minfloat - min )
   Round seconds to desired accuracy:
   secfloat ← round( secfloat, digits )
   After rounding, the seconds might become 60. These two
   if-tests are not necessary if no rounding is done.
   if secfloat = 60
      min ← min + 1
      secfloat ← 0
   end if
   if min = 60
      deg ← deg + 1
      min ← 0
   end if
   Return output:
   return ( deg, min, secfloat )
end function
*/

function deg_to_dms (deg) {
   var d = Math.floor (deg);
   var minfloat = (deg-d)*60;
   var m = Math.floor(minfloat);
   var secfloat = (minfloat-m)*60;
   var s = Math.round(secfloat);
   // After rounding, the seconds might become 60. These two
   // if-tests are not necessary if no rounding is done.
   if (s==60) {
     m++;
     s=0;
   }
   if (m==60) {
     d++;
     m=0;
   }
   return ("" + d + ":" + m + ":" + s);
}

回答by Mark Kahn

function ConvertDDToDMS(D, lng){
    const M=0|(D%1)*60e7;

    return {
        dir : D<0?lng?'W':'S':lng?'E':'N',
        deg : 0|(D<0?D=-D:D),
        min : 0|M/1e7,
        sec : (0|M/1e6%1*6e4)/100
    };
}

The above gives you an object {deg:, min:, sec:, dir:}with sec truncated to two digits (e.g. 3.14) and dir being one of N, E, S, Wdepending on whether you set the lng(longitude) parameter to true. e.g.:

以上为您提供了一个对象,{deg:, min:, sec:, dir:}其中 sec 被截断为两位数(例如3.14),而 dir 是N, E, 之一SW具体取决于您是否将lng(longitude) 参数设置为 true。例如:

ConvertDDToDMS(-18.213, true) == {
   deg : 18,
   min : 12,
   sec : 46.79,
   dir : 'W'
}

Or if you just want the basic string:

或者,如果您只想要基本字符串:

function ConvertDDToDMS(D){
    return [0|D, 'd ', 0|(D<0?D=-D:D)%1*60, "' ", 0|D*60%1*60, '"'].join('');
}

ConvertDDToDMS(-18.213) == `-18d 12' 46"`

[edit June 2019] -- fixing an 8 year old bug that would sometimes cause the result to be 1 minute off due to floating point math when converting an exact minute, e.g. ConvertDDToDMS(4 + 20/60). Updated code still has a slight issue, but will round to 19min 59.99 sec in this case, which is fine and not fixable due to the way floating points work

[编辑 2019 年 6 月] - 修复了一个 8 年前的错误,该错误有时会由于转换精确分钟时的浮点数学而导致结果偏离 1 分钟,例如ConvertDDToDMS(4 + 20/60). 更新后的代码仍然有一个小问题,但在这种情况下将四舍五入为 19 分 59.99 秒,这很好,并且由于浮点的工作方式而无法修复

回答by Gabe

It's not clear how you need the output. Here's a version that returns all 3 values as a string:

目前尚不清楚您如何需要输出。这是一个将所有 3 个值作为字符串返回的版本:

function ConvertDDToDMS(dd)
{
    var deg = dd | 0; // truncate dd to get degrees
    var frac = Math.abs(dd - deg); // get fractional part
    var min = (frac * 60) | 0; // multiply fraction by 60 and truncate
    var sec = frac * 3600 - min * 60;
    return deg + "d " + min + "' " + sec + "\"";
}

回答by Ralph

Based on above answer, i've written them into javascript and php style.

基于上述答案,我已将它们写入 javascript 和 php 样式。

JS-

JS-

function convertDDToDMS(deg, lng){
    var d = parseInt(deg);
    var minfloat  = Math.abs((deg-d) * 60); 
    var m = Math.floor(minfloat);
    var secfloat = (minfloat-m)*60;
    var s = Math.round(secfloat); 
    d = Math.abs(d);

    if (s==60) {
        m++;
        s=0;
    }
    if (m==60) {
        d++;
        m=0;
    }

    return {
        dir : deg<0?lng?'W':'S':lng?'E':'N',
        deg : d,
        min : m,
        sec : s
    };
}

PHP-

PHP-

function convertDDtoDMS($deg, $lng){
    $dd = intval($deg);
    $minfloat = abs(($deg - $dd) * 60);
    $mm = floor($minfloat);
    $secfloat = ($minfloat - $mm) * 60;
    $ss = round($secfloat);
    $dd = abs($dd);

    if($ss == 60){
        $mm++;
        $ss = 0;
    }

    if($mm == 60){
        $dd++;
        $mm = 0;
    }

    $dd = array(
        'dir' => $deg < 0 ? ($lng ? 'W' : 'S') : ($lng ? 'E' : 'N'),
        'deg' => abs($dd),
        'min' => $mm,
        'sec' => $ss,
    );

    return $dd;
}

回答by Rohit Sukumar

private static DecimalFormat DecimalFormat = new DecimalFormat(".##");
public static void main(String[] args){
    double decimal_degrees = 22.4229541515;

    System.out.println(getDMS(decimal_degrees));
}
public static String getDMS(double decimal_degrees) {
    double degree =  Math.floor(decimal_degrees);
    double minutes = ((decimal_degrees - Math.floor(decimal_degrees)) * 60.0); 
    double seconds = (minutes - Math.floor(minutes)) * 60.0;
    return ((int)degree)+":"+((int)minutes)+":"+decimalFormat.format(seconds);

}

INPUT : 22.4229541515 OUTPUT: 22:25:22.63

输入:22.4229541515 输出:22:25:22.63

回答by Marco Tibben

couldnt get the script above working, after some time came up with this; just give the dms to the script

无法让上面的脚本工作,一段时间后想出了这个;只需将 dms 提供给脚本

function ConvertDMSToDEG(dms) {   
    var dms_Array = dms.split(/[^\d\w\.]+/); 
    var degrees = dms_Array[0];
    var minutes = dms_Array[1];
    var seconds = dms_Array[2];
    var direction = dms_Array[3];

    var deg = (Number(degrees) + Number(minutes)/60 + Number(seconds)/3600).toFixed(6);

    if (direction == "S" || direction == "W") {
        deg = deg * -1;
    } // Don't do anything for N or E
    return deg;
}

and visa versa just give the degrees to the script, and true of false for lat (latitude)

反之亦然,只是为脚本提供度数,而 lat(纬度)则为 true 或 false

function ConvertDEGToDMS(deg, lat) {
    var absolute = Math.abs(deg);

    var degrees = Math.floor(absolute);
    var minutesNotTruncated = (absolute - degrees) * 60;
    var minutes = Math.floor(minutesNotTruncated);
    var seconds = ((minutesNotTruncated - minutes) * 60).toFixed(2);

    if (lat) {
        var direction = deg >= 0 ? "N" : "S";
    } else {
        var direction = deg >= 0 ? "E" : "W";
    }

    return degrees + "°" + minutes + "'" + seconds + "\"" + direction;
}

hope this helps people..

希望这可以帮助人们..

回答by siva.picky

Try this working perfect!!!

试试这个工作完美!!!

function truncate(n) {
    return n > 0 ? Math.floor(n) : Math.ceil(n);
}

function getDMS(dd, longOrLat) {
    let hemisphere = /^[WE]|(?:lon)/i.test(longOrLat)
    ? dd < 0
      ? "W"
      : "E"
    : dd < 0
      ? "S"
      : "N";

    const absDD = Math.abs(dd);
    const degrees = truncate(absDD);
    const minutes = truncate((absDD - degrees) * 60);
    const seconds = ((absDD - degrees - minutes / 60) * Math.pow(60, 2)).toFixed(2);

    let dmsArray = [degrees, minutes, seconds, hemisphere];
    return `${dmsArray[0]}°${dmsArray[1]}'${dmsArray[2]}" ${dmsArray[3]}`;
}

var lat = 13.041107;
var lon = 80.233232;

var latDMS = getDMS(lat, 'lat'); 
var lonDMS = getDMS(lon, 'long');
console.log('latDMS: '+ latDMS);
console.log('lonDMS: '+ lonDMS);

Output:
latDMS: 13°2'27.99" N
lonDMS: 80°13'59.64" E 

回答by Mohsen Alyafei

A solution with the option for specifying the decimal places in output seconds and correction of any edge cases due to rounding seconds and minutes.

一种解决方案,可以指定输出秒中的小数位并纠正由于舍入秒和分钟而导致的任何边缘情况。

// @ input {deg}     Numeric; degrees number to convert
// @ input {dplaces} Decimal places to use for output seconds
//                   Default 0 places
// @ return {DMS} string degrees (°) minutes (') seconds (")
//
function degToDMS (deg, dplaces=0) {
  var d = Math.floor (deg);          // make degrees
  var m = Math.floor((deg-d)*60);    // make minutes
  var s = Math.round(((deg-d)*60-m)*60*Math.pow(10,dplaces))/Math.pow(10,dplaces); // Make sec rounded
  s == 60 && (m++, s=0 );            // if seconds rounds to 60 then increment minutes, reset seconds
  m == 60 && (d++, m=0 );            // if minutes rounds to 60 then increment degress, reset minutes
  return (d + "° " + m + "' " + s+'"');   // create output DMS string
}

// ----- tests ------
console.log(degToDMS(55.23456));         // 55° 14' 4"
console.log(degToDMS(55.23456   ,3));    // 55° 14' 4.416"
console.log(degToDMS(4 + 20/60  ,2));    // 4° 20' 0"
console.log(degToDMS(89.64789   ,2));    // 89° 38' 52.4"
console.log(degToDMS(-23.1234567,3));    // -24° 52' 35.556"

回答by archi pelago

just for remark, the answer

仅供参考,答案

function ConvertDDToDMS(D){
return [0|D, 'd ', 0|(D<0?D=-D:D)%1*60, "' ", 0|D*60%1*60, '"'].join('');

}

}

does notwork for angles between -1° and 0°. Bad luck! hc

没有对之间-1°和0°的角度工作。厄运!慧聪