如果公式转换经纬度翻一番是
((度)+(分钟)/ 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; //... }
更多推荐
格式化双纬度/经度人类可读的格式
发布评论