Handle GEDCOM 5.5.1 formats for latitude and longitude (bug #3743)
svn: r14910
This commit is contained in:
parent
6fde03c4a0
commit
46abb12de5
@ -241,6 +241,38 @@ def __convert_using_classic_repr(stringValue, typedeg):
|
|||||||
|
|
||||||
return __convert_structure_to_float(sign, degs, mins, secs)
|
return __convert_structure_to_float(sign, degs, mins, secs)
|
||||||
|
|
||||||
|
def __convert_using_modgedcom_repr(val, typedeg):
|
||||||
|
""" helper function that tries to convert the string using the
|
||||||
|
modified GEDCOM representation where direction [NSEW] is appended
|
||||||
|
instead of prepended. This particular representation is the result
|
||||||
|
of value normalization done on values passed to this function
|
||||||
|
"""
|
||||||
|
if typedeg == 'lat':
|
||||||
|
pos = val.find('N')
|
||||||
|
if pos >= 0:
|
||||||
|
stringValue = val[:pos]
|
||||||
|
else:
|
||||||
|
pos = val.find('S')
|
||||||
|
if pos >= 0:
|
||||||
|
stringValue = '-' + val[:pos]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
pos = val.find('E')
|
||||||
|
if pos >= 0:
|
||||||
|
stringValue = val[:pos]
|
||||||
|
else:
|
||||||
|
pos = val.find('W')
|
||||||
|
if pos >= 0:
|
||||||
|
stringValue = '-' + val[:pos]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
try :
|
||||||
|
v = float(stringValue)
|
||||||
|
return v
|
||||||
|
except ValueError :
|
||||||
|
return None;
|
||||||
|
|
||||||
def __convert_float_val(val, typedeg = "lat"):
|
def __convert_float_val(val, typedeg = "lat"):
|
||||||
# function converting input to float, recognizing decimal input, or
|
# function converting input to float, recognizing decimal input, or
|
||||||
# degree notation input. Only english input
|
# degree notation input. Only english input
|
||||||
@ -271,6 +303,11 @@ def __convert_float_val(val, typedeg = "lat"):
|
|||||||
if v is not None :
|
if v is not None :
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
# format XX.YYYY[NSWE]
|
||||||
|
v = __convert_using_modgedcom_repr(val, typedeg)
|
||||||
|
if v is not None :
|
||||||
|
return v
|
||||||
|
|
||||||
# no format succeeded
|
# no format succeeded
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -364,6 +401,24 @@ def conv_lat_lon(latitude, longitude, format="D.D4"):
|
|||||||
else:
|
else:
|
||||||
return ("%.8f" % lat_float , str_lon)
|
return ("%.8f" % lat_float , str_lon)
|
||||||
|
|
||||||
|
if format == "GEDCOM":
|
||||||
|
# The 5.5.1 spec is inconsistent. Length is supposedly 5 to 8 chars,
|
||||||
|
# but the sample values are longer, using up to 6 fraction digits.
|
||||||
|
# As a compromise, we will produce up to 6 fraction digits, but only
|
||||||
|
# if necessary
|
||||||
|
# correct possible roundoff error
|
||||||
|
if lon_float >= 0:
|
||||||
|
str_lon = "%.6f" % (lon_float)
|
||||||
|
if str_lon == "180.000000":
|
||||||
|
str_lon ="W180.000000"
|
||||||
|
else:
|
||||||
|
str_lon = "E" + str_lon
|
||||||
|
else:
|
||||||
|
str_lon = "W" + "%.6f" % (-lon_float)
|
||||||
|
str_lon = str_lon[:-5] + str_lon[-5:].rstrip("0")
|
||||||
|
str_lat = ("%s%.6f" % (("N", lat_float) if lat_float >= 0 else ("S", -lat_float)))
|
||||||
|
str_lat = str_lat[:-5] + str_lat[-5:].rstrip("0")
|
||||||
|
return (str_lat, str_lon)
|
||||||
|
|
||||||
deg_lat = int(lat_float)
|
deg_lat = int(lat_float)
|
||||||
deg_lon = int(lon_float)
|
deg_lon = int(lon_float)
|
||||||
@ -624,6 +679,7 @@ if __name__ == '__main__':
|
|||||||
format5 = "ISO-DM"
|
format5 = "ISO-DM"
|
||||||
format6 = "ISO-DMS"
|
format6 = "ISO-DMS"
|
||||||
format7 = "RT90"
|
format7 = "RT90"
|
||||||
|
format8 = "GEDCOM"
|
||||||
print "Testing conv_lat_lon function, "+text+':'
|
print "Testing conv_lat_lon function, "+text+':'
|
||||||
res1, res2 = conv_lat_lon(lat1,lon1,format0)
|
res1, res2 = conv_lat_lon(lat1,lon1,format0)
|
||||||
print lat1,lon1,"in format",format0, "is ",res1,res2
|
print lat1,lon1,"in format",format0, "is ",res1,res2
|
||||||
@ -641,6 +697,8 @@ if __name__ == '__main__':
|
|||||||
print lat1,lon1,"in format",format6, "is",res
|
print lat1,lon1,"in format",format6, "is",res
|
||||||
res1, res2 = conv_lat_lon(lat1,lon1,format7)
|
res1, res2 = conv_lat_lon(lat1,lon1,format7)
|
||||||
print lat1,lon1,"in format",format7, "is",res1,res2,"\n"
|
print lat1,lon1,"in format",format7, "is",res1,res2,"\n"
|
||||||
|
res1, res2 = conv_lat_lon(lat1,lon1,format8)
|
||||||
|
print lat1,lon1,"in format",format8, "is",res1,res2,"\n"
|
||||||
|
|
||||||
def test_formats_fail(lat1,lon1,text=''):
|
def test_formats_fail(lat1,lon1,text=''):
|
||||||
print "This test should make conv_lat_lon function fail, "+text+":"
|
print "This test should make conv_lat_lon function fail, "+text+":"
|
||||||
@ -687,6 +745,8 @@ if __name__ == '__main__':
|
|||||||
# test precision
|
# test precision
|
||||||
lat, lon = u' 50°59.99"S', u' 2°59\'59.99"E'
|
lat, lon = u' 50°59.99"S', u' 2°59\'59.99"E'
|
||||||
test_formats_success(lat,lon)
|
test_formats_success(lat,lon)
|
||||||
|
lat, lon = 'N50.849888888888', 'E2.885897222222'
|
||||||
|
test_formats_success(lat,lon)
|
||||||
# to large value of lat
|
# to large value of lat
|
||||||
lat, lon = '90.849888888888', '2.885897222222'
|
lat, lon = '90.849888888888', '2.885897222222'
|
||||||
test_formats_fail(lat,lon)
|
test_formats_fail(lat,lon)
|
||||||
|
@ -47,6 +47,7 @@ from gen.updatecallback import UpdateCallback
|
|||||||
from Utils import media_path_full
|
from Utils import media_path_full
|
||||||
import gen.proxy
|
import gen.proxy
|
||||||
from QuestionDialog import ErrorDialog
|
from QuestionDialog import ErrorDialog
|
||||||
|
from PlaceUtils import conv_lat_lon
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -1366,6 +1367,8 @@ class GedcomWriter(UpdateCallback):
|
|||||||
self.__writeln(level, "PLAC", place_name.replace('\r', ' '))
|
self.__writeln(level, "PLAC", place_name.replace('\r', ' '))
|
||||||
longitude = place.get_longitude()
|
longitude = place.get_longitude()
|
||||||
latitude = place.get_latitude()
|
latitude = place.get_latitude()
|
||||||
|
if longitude and latitude:
|
||||||
|
(latitude, longitude) = conv_lat_lon(latitude, longitude, "GEDCOM")
|
||||||
if longitude and latitude:
|
if longitude and latitude:
|
||||||
self.__writeln(level+1, "MAP")
|
self.__writeln(level+1, "MAP")
|
||||||
self.__writeln(level+2, 'LATI', latitude)
|
self.__writeln(level+2, 'LATI', latitude)
|
||||||
|
Loading…
Reference in New Issue
Block a user