格式化双纬度/经度人类可读的格式 [英] Formatting double to latitude/longitude human readable format
问题描述
如果公式转换经纬度翻一番是
((度)+(分钟)/ 60 +(二)/ 3600)*((南||西)-1:1)
再有什么公式解析度,分,秒,从双?
这将会有道理对解析经纬度两个不同的方法,但我不知道如何从双重解析度,分,秒。
ParseLatitude(double值)
{
//值是南如果为负,否则就是北方。
}
ParseLongitude(double值)
{
//值是西如果为负,否则就是东。
}
例如坐标:
纬度:43.81234123
经度:-119.8374747
最后code再来回转换,这要归功于彼得和詹姆斯的答案。我不得不转换的值的为十进制因为这是正在Silverlight和Math.Truncate(双)采用的是不可用):
公共类坐标
{
公共双学位{获得;组; }
公共双分钟{获得;组; }
公共双秒{获得;组; }
公共CoordinatesPosition位置{获得;组; }
公共坐标(){}
公共坐标(双精度值,CoordinatesPosition位置)
{
//神智
如果(值小于0安培;&安培;仓位== CoordinatesPosition.N)
位置= CoordinatesPosition.S;
//神智
如果(值小于0安培;&安培;仓位== CoordinatesPosition.E)
位置= CoordinatesPosition.W;
//神智
如果(值大于0和放大器;&安培;仓位== CoordinatesPosition.S)
位置= CoordinatesPosition.N;
//神智
如果(值大于0和放大器;&安培;仓位== CoordinatesPosition.W)
位置= CoordinatesPosition.E;
VAR decimalValue = Convert.ToDecimal(值);
decimalValue = Math.Abs(decimalValue);
VAR度= Decimal.Truncate(decimalValue);
decimalValue =(decimalValue - 度)* 60;
VAR分钟= Decimal.Truncate(decimalValue);
VAR秒=(decimalValue - 分钟)* 60;
度= Convert.ToDouble(度);
分钟= Convert.ToDouble(分钟);
秒= Convert.ToDouble(秒);
位置=地位;
}
公共坐标(双学位,双分,双秒,CoordinatesPosition位置)
{
度=度;
分钟=分钟;
秒=秒;
位置=地位;
}
公共双ToDouble()
{
VAR的结果=(度)+(分钟)/ 60 +(秒)/ 3600;
返回位置== CoordinatesPosition.W ||位置== CoordinatesPosition.S? -result:结果;
}
公共重写字符串的ToString()
{
返回度+º+分钟+'+秒+''+位置;
}
}
公共枚举CoordinatesPosition
{
N,E,S,W
}
单元测试(NUnit的)
[的TestFixture]
公共类CoordinateTests
{
[测试]
公共无效ShouldConvertDoubleToCoordinateAndBackToDouble()
{
常量双baseLatitude = 43.81234123;
常量双baseLongitude = -119.8374747;
VAR latCoordN =新坐标(baseLatitude,CoordinatesPosition.N);
VAR latCoordS =新坐标(baseLatitude,CoordinatesPosition.S);
VAR lonCoordE =新坐标(baseLongitude,CoordinatesPosition.E);
VAR lonCoordW =新坐标(baseLongitude,CoordinatesPosition.W);
变种convertedLatitudeS = latCoordS.ToDouble();
变种convertedLatitudeN = latCoordN.ToDouble();
变种convertedLongitudeW = lonCoordW.ToDouble();
变种convertedLongitudeE = lonCoordE.ToDouble();
Assert.AreEqual(convertedLatitudeS,convertedLatitudeN);
Assert.AreEqual(baseLatitude,convertedLatitudeN);
Assert.AreEqual(convertedLongitudeE,convertedLongitudeW);
Assert.AreEqual(baseLongitude,convertedLongitudeE);
}
}
ParseLatitude(double值)
{
VAR方向=值小于; 0? Direction.South:Direction.North;
值= Math.Abs(值);
VAR度= Math.Truncate(值);
值=(值 - 度)* 60; //不是值=(值 - 度)/ 60;
VAR分钟= Math.Truncate(值);
VAR秒=(值 - 分钟)* 60; //不是值=(值 - 度)/ 60;
// ...
}
ParseLongitude(双值)
{
VAR方向=值小于; 0? Direction.West:Direction.East;
值= Math.Abs(值);
VAR度= Math.Truncate(值);
值=(值 - 度)* 60; //不是值=(值 - 度)/ 60;
VAR分钟= Math.Truncate(值);
VAR秒=(值 - 分钟)* 60; //不是值=(值 - 度)/ 60;
// ...
}
修改
我来是因为最近一个upvote回本。这里有一个DRY-ER的版本,与值
参数重新命名,以反映最常用的编码惯例,其中的参数开始与小写字母:
ParseLatitude(double值)
{
VAR方向=值小于; 0? Direction.South:Direction.North;
返回ParseLatituteOrLongitude(价值方向);
}
ParseLongitude(double值)
{
VAR方向=值小于; 0? Direction.West:Direction.East;
返回ParseLatituteOrLongitude(价值方向);
}
//这必须是一个私人的方法,因为它要求调用者保证
//该方向的参数是正确的。
ParseLatitudeOrLongitude(双重价值,方向方向)
{
值= Math.Abs(值);
VAR度= Math.Truncate(值);
值=(值 - 度)* 60; //不是值=(值 - 度)/ 60;
VAR分钟= Math.Truncate(值);
VAR秒=(价值 - 分钟)* 60; //不是值=(值 - 度)/ 60;
// ...
}
If the formula for converting latitude or longitude to double is
((Degree) + (Minute) / 60 + (Second) / 3600) * ((South || West) ? -1 : 1)
then what's the formula for parsing degrees, minutes, seconds from a double?
It'd make sense to have two separate methods for parsing latitude and longitude, but I'm not sure how to parse the degrees, minutes, seconds from the double.
ParseLatitude(double value)
{
//value is South if negative, else is North.
}
ParseLongitude(double value)
{
//value is West if negative, else is East.
}
Example coordinates:
latitude: 43.81234123
longitude: -119.8374747
The final code to convert back and forth, thanks again to Peter and James for the answer. I had to convert value to Decimal because this is being used in Silverlight and Math.Truncate(double) is not available):
public class Coordinate
{
public double Degrees { get; set; }
public double Minutes { get; set; }
public double Seconds { get; set; }
public CoordinatesPosition Position { get; set; }
public Coordinate() { }
public Coordinate(double value, CoordinatesPosition position)
{
//sanity
if (value < 0 && position == CoordinatesPosition.N)
position = CoordinatesPosition.S;
//sanity
if (value < 0 && position == CoordinatesPosition.E)
position = CoordinatesPosition.W;
//sanity
if (value > 0 && position == CoordinatesPosition.S)
position = CoordinatesPosition.N;
//sanity
if (value > 0 && position == CoordinatesPosition.W)
position = CoordinatesPosition.E;
var decimalValue = Convert.ToDecimal(value);
decimalValue = Math.Abs(decimalValue);
var degrees = Decimal.Truncate(decimalValue);
decimalValue = (decimalValue - degrees) * 60;
var minutes = Decimal.Truncate(decimalValue);
var seconds = (decimalValue - minutes) * 60;
Degrees = Convert.ToDouble(degrees);
Minutes = Convert.ToDouble(minutes);
Seconds = Convert.ToDouble(seconds);
Position = position;
}
public Coordinate(double degrees, double minutes, double seconds, CoordinatesPosition position)
{
Degrees = degrees;
Minutes = minutes;
Seconds = seconds;
Position = position;
}
public double ToDouble()
{
var result = (Degrees) + (Minutes) / 60 + (Seconds) / 3600;
return Position == CoordinatesPosition.W || Position == CoordinatesPosition.S ? -result : result;
}
public override string ToString()
{
return Degrees + "º " + Minutes + "' " + Seconds + "'' " + Position;
}
}
public enum CoordinatesPosition
{
N, E, S, W
}
Unit Test (nUnit)
[TestFixture]
public class CoordinateTests
{
[Test]
public void ShouldConvertDoubleToCoordinateAndBackToDouble()
{
const double baseLatitude = 43.81234123;
const double baseLongitude = -119.8374747;
var latCoordN = new Coordinate(baseLatitude, CoordinatesPosition.N);
var latCoordS = new Coordinate(baseLatitude, CoordinatesPosition.S);
var lonCoordE = new Coordinate(baseLongitude, CoordinatesPosition.E);
var lonCoordW = new Coordinate(baseLongitude, CoordinatesPosition.W);
var convertedLatitudeS = latCoordS.ToDouble();
var convertedLatitudeN = latCoordN.ToDouble();
var convertedLongitudeW = lonCoordW.ToDouble();
var convertedLongitudeE = lonCoordE.ToDouble();
Assert.AreEqual(convertedLatitudeS, convertedLatitudeN);
Assert.AreEqual(baseLatitude, convertedLatitudeN);
Assert.AreEqual(convertedLongitudeE, convertedLongitudeW);
Assert.AreEqual(baseLongitude, convertedLongitudeE);
}
}
ParseLatitude(double Value)
{
var direction = Value < 0 ? Direction.South : Direction.North;
Value = Math.Abs(Value);
var degrees = Math.Truncate(Value);
Value = (Value - degrees) * 60; //not Value = (Value - degrees) / 60;
var minutes = Math.Truncate(Value);
var seconds = (Value - minutes) * 60; //not Value = (Value - degrees) / 60;
//...
}
ParseLongitude(double Value)
{
var direction = Value < 0 ? Direction.West : Direction.East;
Value = Math.Abs(Value);
var degrees = Math.Truncate(Value);
Value = (Value - degrees) * 60; //not Value = (Value - degrees) / 60;
var minutes = Math.Truncate(Value);
var seconds = (Value - minutes) * 60; //not Value = (Value - degrees) / 60;
//...
}
EDIT
I came back to this because of a recent upvote. Here's a DRY-er version, with the Value
parameter renamed to reflect the most common coding convention, in which parameters start with lower-case letters:
ParseLatitude(double value)
{
var direction = value < 0 ? Direction.South : Direction.North;
return ParseLatituteOrLongitude(value, direction);
}
ParseLongitude(double value)
{
var direction = value < 0 ? Direction.West : Direction.East;
return ParseLatituteOrLongitude(value, direction);
}
//This must be a private method because it requires the caller to ensure
//that the direction parameter is correct.
ParseLatitudeOrLongitude(double value, Direction direction)
{
value = Math.Abs(value);
var degrees = Math.Truncate(value);
value = (value - degrees) * 60; //not Value = (Value - degrees) / 60;
var minutes = Math.Truncate(value);
var seconds = (value - minutes) * 60; //not Value = (Value - degrees) / 60;
//...
}
这篇关于格式化双纬度/经度人类可读的格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!