Closes gh-31 Fix decimal to degree, minute, second conversion by making seconds more precice and supporting negative values
This commit is contained in:
		
							parent
							
								
									c4e817bde8
								
							
						
					
					
						commit
						f1787d5a16
					
				| @ -12,13 +12,11 @@ from elodie import constants | |||||||
| 
 | 
 | ||||||
| class Fraction(fractions.Fraction): | class Fraction(fractions.Fraction): | ||||||
|     """Only create Fractions from floats. |     """Only create Fractions from floats. | ||||||
| 
 |  | ||||||
|     >>> Fraction(0.3) |     >>> Fraction(0.3) | ||||||
|     Fraction(3, 10) |     Fraction(3, 10) | ||||||
|     >>> Fraction(1.1) |     >>> Fraction(1.1) | ||||||
|     Fraction(11, 10) |     Fraction(11, 10) | ||||||
|     """ |     """ | ||||||
| 
 |  | ||||||
|     def __new__(cls, value, ignore=None): |     def __new__(cls, value, ignore=None): | ||||||
|         """Should be compatible with Python 2.6, though untested.""" |         """Should be compatible with Python 2.6, though untested.""" | ||||||
|         return fractions.Fraction.from_float(value).limit_denominator(99999) |         return fractions.Fraction.from_float(value).limit_denominator(99999) | ||||||
| @ -47,28 +45,20 @@ def coordinates_by_name(name): | |||||||
|     return None |     return None | ||||||
| 
 | 
 | ||||||
| def decimal_to_dms(decimal): | def decimal_to_dms(decimal): | ||||||
|     """Convert decimal degrees into degrees, minutes, seconds. |     # if decimal is negative we need to make the degrees and minutes negative also | ||||||
|  |     sign = 1 | ||||||
|  |     if(decimal < 0): | ||||||
|  |         sign = -1 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     >>> decimal_to_dms(50.445891) |  | ||||||
|     [Fraction(50, 1), Fraction(26, 1), Fraction(113019, 2500)] |  | ||||||
|     >>> decimal_to_dms(-125.976893) |  | ||||||
|     [Fraction(125, 1), Fraction(58, 1), Fraction(92037, 2500)] |  | ||||||
|     """ |  | ||||||
|     # @TODO figure out a better and more proper way to do seconds |  | ||||||
|     degrees = int(decimal) |     degrees = int(decimal) | ||||||
|     subminutes = abs((decimal - int(decimal)) * 60) |     subminutes = abs((decimal - int(decimal)) * 60) | ||||||
|     minutes = int(subminutes) |     minutes = int(subminutes) * sign | ||||||
|     subseconds = abs((subminutes - int(subminutes)) * 60) |     subseconds = abs((subminutes - int(subminutes)) * 60) * sign | ||||||
|     return (pyexiv2.Rational(degrees, 1), pyexiv2.Rational(minutes, 1), pyexiv2.Rational(subseconds, 1)) |     subseconds_fraction = Fraction(subseconds) | ||||||
|  |     return (pyexiv2.Rational(degrees, 1), pyexiv2.Rational(minutes, 1), pyexiv2.Rational(subseconds_fraction.numerator, subseconds_fraction.denominator)) | ||||||
| 
 | 
 | ||||||
| def dms_to_decimal(degrees, minutes, seconds, sign=' '): | def dms_to_decimal(degrees, minutes, seconds, sign=' '): | ||||||
|     """Convert degrees, minutes, seconds into decimal degrees. |  | ||||||
| 
 |  | ||||||
|     >>> dms_to_decimal(10, 10, 10) |  | ||||||
|     10.169444444444444 |  | ||||||
|     >>> dms_to_decimal(8, 9, 10, 'S') |  | ||||||
|     -8.152777777777779 |  | ||||||
|     """ |  | ||||||
|     return (-1 if sign[0] in 'SWsw' else 1) * ( |     return (-1 if sign[0] in 'SWsw' else 1) * ( | ||||||
|         float(degrees)        + |         float(degrees)        + | ||||||
|         float(minutes) / 60   + |         float(minutes) / 60   + | ||||||
|  | |||||||
| @ -1,8 +1,8 @@ | |||||||
| # Project imports | # Project imports | ||||||
| import os | import os | ||||||
| import sys | import random | ||||||
| 
 |  | ||||||
| import re | import re | ||||||
|  | import sys | ||||||
| 
 | 
 | ||||||
| sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))) | sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))) | ||||||
| 
 | 
 | ||||||
| @ -12,9 +12,16 @@ from elodie import geolocation | |||||||
| os.environ['TZ'] = 'GMT' | os.environ['TZ'] = 'GMT' | ||||||
| 
 | 
 | ||||||
| def test_decimal_to_dms(): | def test_decimal_to_dms(): | ||||||
|     target_decimal_value = 37.383336725 | 
 | ||||||
|  |     for x in range(0, 1000): | ||||||
|  |         target_decimal_value = random.uniform(0.0, 180.0) | ||||||
|  |         if(x % 2 == 1): | ||||||
|  |             target_decimal_value = target_decimal_value * -1 | ||||||
|      |      | ||||||
|         dms = geolocation.decimal_to_dms(target_decimal_value) |         dms = geolocation.decimal_to_dms(target_decimal_value) | ||||||
|         check_value = dms[0].to_float() + dms[1].to_float() / 60 + dms[2].to_float() / 3600 |         check_value = dms[0].to_float() + dms[1].to_float() / 60 + dms[2].to_float() / 3600 | ||||||
| 
 | 
 | ||||||
|  |         target_decimal_value = round(target_decimal_value, 8) | ||||||
|  |         check_value = round(check_value, 8) | ||||||
|  | 
 | ||||||
|         assert target_decimal_value == check_value, '%s does not match %s' % (check_value, target_decimal_value) |         assert target_decimal_value == check_value, '%s does not match %s' % (check_value, target_decimal_value) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jaisen Mathai
						Jaisen Mathai