mirror of
https://frontier.innolan.net/rainlance/amiga-tz.git
synced 2025-11-21 15:38:57 +00:00
tzselect: improve heuristic in Africa
Add the product of the longitude difference and the cosine of the latitude farther from the equator to the distance measure. This works better for the Congolese test case noted by Alan Barrett in: http://mm.icann.org/pipermail/tz/2014-July/021229.html The new heuristic is not perfect, but no heuristic is. * tzselect.ksh (abs, min): New functions (convert_coord): Rename local to avoid name clash. (gcdist): Rename from dist. (pardist, dist): New functions. * NEWS: Document this.
This commit is contained in:
5
NEWS
5
NEWS
@ -19,6 +19,11 @@ Unreleased, experimental changes
|
|||||||
|
|
||||||
Asia/Dakha ended DST on 2009-12-31 at 24:00, not 23:59.
|
Asia/Dakha ended DST on 2009-12-31 at 24:00, not 23:59.
|
||||||
|
|
||||||
|
Changes affecting code
|
||||||
|
|
||||||
|
tzselect -c now uses a hybrid distance measure that works better
|
||||||
|
in Africa. (Thanks to Alana Barrett for noting the problem.)
|
||||||
|
|
||||||
Changes affecting distribution tarballs
|
Changes affecting distribution tarballs
|
||||||
|
|
||||||
The files checktab.awk and zoneinfo2tdf.pl are now distributed in
|
The files checktab.awk and zoneinfo2tdf.pl are now distributed in
|
||||||
|
|||||||
27
tzselect.ksh
27
tzselect.ksh
@ -192,7 +192,13 @@ output_distances='
|
|||||||
country[$1] = $2
|
country[$1] = $2
|
||||||
country["US"] = "US" # Otherwise the strings get too long.
|
country["US"] = "US" # Otherwise the strings get too long.
|
||||||
}
|
}
|
||||||
function convert_coord(coord, deg, min, ilen, sign, sec) {
|
function abs(x) {
|
||||||
|
return x < 0 ? -x : x;
|
||||||
|
}
|
||||||
|
function min(x, y) {
|
||||||
|
return x < y ? x : y;
|
||||||
|
}
|
||||||
|
function convert_coord(coord, deg, minute, ilen, sign, sec) {
|
||||||
if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9][0-9][0-9]([^0-9]|$)/) {
|
if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9][0-9][0-9]([^0-9]|$)/) {
|
||||||
degminsec = coord
|
degminsec = coord
|
||||||
intdeg = degminsec < 0 ? -int(-degminsec / 10000) : int(degminsec / 10000)
|
intdeg = degminsec < 0 ? -int(-degminsec / 10000) : int(degminsec / 10000)
|
||||||
@ -203,8 +209,8 @@ output_distances='
|
|||||||
} else if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9]([^0-9]|$)/) {
|
} else if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9]([^0-9]|$)/) {
|
||||||
degmin = coord
|
degmin = coord
|
||||||
intdeg = degmin < 0 ? -int(-degmin / 100) : int(degmin / 100)
|
intdeg = degmin < 0 ? -int(-degmin / 100) : int(degmin / 100)
|
||||||
min = degmin - intdeg * 100
|
minute = degmin - intdeg * 100
|
||||||
deg = (intdeg * 60 + min) / 60
|
deg = (intdeg * 60 + minute) / 60
|
||||||
} else
|
} else
|
||||||
deg = coord
|
deg = coord
|
||||||
return deg * 0.017453292519943296
|
return deg * 0.017453292519943296
|
||||||
@ -220,7 +226,7 @@ output_distances='
|
|||||||
# Great-circle distance between points with given latitude and longitude.
|
# Great-circle distance between points with given latitude and longitude.
|
||||||
# Inputs and output are in radians. This uses the great-circle special
|
# Inputs and output are in radians. This uses the great-circle special
|
||||||
# case of the Vicenty formula for distances on ellipsoids.
|
# case of the Vicenty formula for distances on ellipsoids.
|
||||||
function dist(lat1, long1, lat2, long2, dlong, x, y, num, denom) {
|
function gcdist(lat1, long1, lat2, long2, dlong, x, y, num, denom) {
|
||||||
dlong = long2 - long1
|
dlong = long2 - long1
|
||||||
x = cos (lat2) * sin (dlong)
|
x = cos (lat2) * sin (dlong)
|
||||||
y = cos (lat1) * sin (lat2) - sin (lat1) * cos (lat2) * cos (dlong)
|
y = cos (lat1) * sin (lat2) - sin (lat1) * cos (lat2) * cos (dlong)
|
||||||
@ -228,6 +234,19 @@ output_distances='
|
|||||||
denom = sin (lat1) * sin (lat2) + cos (lat1) * cos (lat2) * cos (dlong)
|
denom = sin (lat1) * sin (lat2) + cos (lat1) * cos (lat2) * cos (dlong)
|
||||||
return atan2(num, denom)
|
return atan2(num, denom)
|
||||||
}
|
}
|
||||||
|
# Parallel distance between points with given latitude and longitude.
|
||||||
|
# This is the product of the longitude difference and the cosine
|
||||||
|
# of the latitude of the point that is further from the equator.
|
||||||
|
# I.e., it considers longitudes to be further apart if they are
|
||||||
|
# nearer the equator.
|
||||||
|
function pardist(lat1, long1, lat2, long2) {
|
||||||
|
return abs (long1 - long2) * min (cos (lat1), cos (lat2))
|
||||||
|
}
|
||||||
|
# The distance function is the sum of the great-circle distance and
|
||||||
|
# the parallel distance. It could be weighted.
|
||||||
|
function dist(lat1, long1, lat2, long2) {
|
||||||
|
return gcdist (lat1, long1, lat2, long2) + pardist (lat1, long1, lat2, long2)
|
||||||
|
}
|
||||||
BEGIN {
|
BEGIN {
|
||||||
coord_lat = convert_latitude(coord)
|
coord_lat = convert_latitude(coord)
|
||||||
coord_long = convert_longitude(coord)
|
coord_long = convert_longitude(coord)
|
||||||
|
|||||||
Reference in New Issue
Block a user