我正在尝试编写一个函数,将我的十进制度数(纬度或经度)转换为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);
}
我走得正确吗?
我正在尝试编写一个函数,将我的十进制度数(纬度或经度)转换为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);
}
我走得正确吗?
function ConvertDDToDMS(D, lng) {
return {
dir: D < 0 ? (lng ? "W" : "S") : lng ? "E" : "N",
deg: 0 | (D < 0 ? (D = -D) : D),
min: 0 | (((D += 1e-9) % 1) * 60),
sec: (0 | (((D * 60) % 1) * 6000)) / 100,
};
}
{deg, min, sec, dir}
,其中秒数被截断为两位小数(例如 3.14
),而方向则根据你是否将参数 lng
(经度)设置为 true 而确定,可能是 N
、E
、S
或 W
。例如:ConvertDDToDMS(-18.213, true) == {
deg : 18,
min : 12,
sec : 46.79,
dir : 'W'
}
或者如果你只需要基本字符串:
function ConvertDDToDMS(D){
return [0|D, 'd ', 0|(D=(D<0?-D:D)+1e-4)%1*60, "' ", 0|D*60%1*60, '"'].join('');
}
ConvertDDToDMS(-18.213) == `-18d 12' 47"`
[2019年6月修订] -- 修复了一个8年前的错误,当转换精确分钟时,由于浮点数计算,有时会导致结果相差1分钟,例如ConvertDDToDMS(4 + 20/60)
。
[2021年12月修订] -- 糟糕。修复#2。回到原始代码并添加1e-9
到值中,a)将任何稍微低的浮点误差提升到下一个最高数字,b)小于.01
秒,因此对输出没有影响。在“字符串”版本中添加1e-4
,这是相同的修复,但也四舍五入秒数(接近1/2秒)。
ConvertLatToDMS = (d) => ConvertDDToDMS(d, false)
和 ConvertLngToDMS = (d) => ConvertDDToDMS(d, true)
。 - user578895不清楚您需要什么输出。这里是返回所有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 + "\"";
}
/* 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);
}
N
和E
之间的差异。 - user578895提供一种解决方案,可选指定输出秒数的小数位,并纠正由于四舍五入导致的秒和分钟边缘情况。
// @ 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"
尝试这个,完美运行!!!
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
ConvertDDToDMS(deg: number, lng: boolean): string {
var d = parseInt(deg.toString());
var minfloat = Math.abs((deg - d) * 60);
var m = Math.floor(minfloat);
var secfloat = (minfloat - m) * 60;
var s = Math.round((secfloat + Number.EPSILON) * 100) / 100
d = Math.abs(d);
if (s == 60) {
m++;
s = 0;
}
if (m == 60) {
d++;
m = 0;
}
let dms = {
dir: deg < 0 ? lng ? 'W' : 'S' : lng ? 'E' : 'N',
deg: d,
min: m,
sec: s
};
return `${dms.deg}\u00B0 ${dms.min}' ${dms.sec}" ${dms.dir}`
}
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);
}
输入:22.4229541515 输出:22:25:22.63
function coordToStr(coord)
{
let seconds = Math.round(Math.abs(coord) * 3600)
let sec = Math.floor(seconds % 60)
let minutes = Math.floor(seconds / 60)
let min = minutes % 60
let deg = Math.floor(minutes / 60)
return deg + "°" + ((min < 10) ? "0" : "") + min + "'" + ((sec < 10) ? "0" : "") + sec
}
抱歉,这个没有包含N/S和E/W部分,需要一些额外的方法来调用它。
如果你想要秒级别的精度,可以使用以下代码:
function coordToStrWithDecimals(coord)
{
let centiSecs = Math.round(Math.abs(coord) * 360000)
let frac = Math.floor(centiSecs % 100)
let seconds = Math.floor(centiSecs / 100)
let sec = Math.floor(seconds % 60)
let minutes = Math.floor(seconds / 60)
let min = minutes % 60
let deg = Math.floor(minutes / 60)
return deg + "°" + ((min < 10) ? "0" : "") + min + "'" + ((sec < 10) ? "0" : "") + sec + "." + ((frac < 10) ? "0" : "") + frac + '"'
}
根据上面的答案,我已经将它们写成了JavaScript和PHP风格。
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-
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;
}
无法让上面的脚本运行,在一段时间后得出了这个解决方案;直接给脚本提供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;
}
反之亦然,只需将度数提供给脚本,并为纬度(lat)提供真或假的值
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;
}
希望这能帮助到大家。