GLIMS ID format: Decision
Bruce Raup
braup at nsidc.org
Wed Jul 24 16:34:27 MDT 2002
The American-style count and recount of the votes has gone on long enough.
It's decision time.
After lots of input and discussion, it has been decided that the format for
the GLIMS glacier ID (primary key in the Glacier_Static table) shall be:
GnnnnnnEmmmmm[N|S]
where [N|S] means "either N or S", nnnnnn has the range [000000,359999],
and mmmmm has the range [00000,90000]. (For those who like W/E for
longitude, note that the longitude of the point lon/lat coordinate in the
Glacier_Static table will have the range [-180,180].) Note that this
differs a bit from what is documented on the GLIMS website; I hope to
update that sometime soon.
The ID has the following features:
- An ID can be assigned to a newly analyzed glacier independent of other
groups.
- The ID is not tied to any political boundaries or nationalities.
- It is human-readable.
- The implied 3-decimal-point precision defines a grid over the earth with
a maximum spacing of 111 m.
Attached is sample perl code to generate IDs from a list of lon/lat
coordinates. Given the test input file
# some test cases
0 0
360 10
-180 90
180 -90
-181 89.9999
-179 -89.9999
-360 89.999
-0.1 0.1
# some mostly real cases
12.71500 46.95167
12.90667 46.61167
89.86667 28.21667
-125.22383 49.20283
-125.22310 45.20283
8.77200 46.73967
8.81450 46.73633
-78.42000 -1.65333
-78.41333 -1.66667
-78.42333 -1.67667
169.87383 -43.99317
169.89667 -43.98967
-76.49850 -11.15967
-75.07533 -11.85917
-119.29167 37.75000
the output looks like:
0 0 G000000E00000N
360 10 G000000E10000N
-180 90 G180000E90000N
180 -90 G180000E90000S
-181 89.9999 G179000E90000N
-179 -89.9999 G181000E90000S
-360 89.999 G000000E89999N
-0.1 0.1 G359900E00100N
12.71500 46.95167 G012715E46952N
12.90667 46.61167 G012907E46612N
89.86667 28.21667 G089867E28217N
-125.22383 49.20283 G234776E49203N
-125.22310 45.20283 G234777E45203N
8.77200 46.73967 G008772E46740N
8.81450 46.73633 G008815E46736N
-78.42000 -1.65333 G281580E01653S
-78.41333 -1.66667 G281587E01667S
-78.42333 -1.67667 G281577E01677S
169.87383 -43.99317 G169874E43993S
169.89667 -43.98967 G169897E43990S
-76.49850 -11.15967 G283501E11160S
-75.07533 -11.85917 G284925E11859S
-119.29167 37.75000 G240708E37750N
Cheers,
Bruce
--
Bruce Raup
National Snow and Ice Data Center Phone: 303-492-8814
University of Colorado, 449 UCB Fax: 303-492-2468
Boulder, CO 80309-0449 braup at nsidc.org
-------------- next part --------------
#!/usr/bin/perl -w
# $Id: lonlat2glims_id,v 1.5 2002-07-24 15:21:31-06 braup Exp braup $
# Program to take a list of lon/lat values as input (filename on the
# command line or as standard input) and generate GLIMS glacier IDs,
# printed to standard output.
($progname = $0) =~ s!^.*/!!; # get basename of program
use Getopt::Std;
use POSIX;
$version = '$Revision: 1.5 $';
($version) = $version =~ /^\$Revision:\s*(\d+\.\d*)/;
$usage = "$progname version $version
Usage:
$progname -h (prints this help message and exits)
OR
$progname [-v] [-l] [lon_lat_filename]
where
-l Output will be 3 columns: lon, lat, and ID. Otherwise, only
the ID is output.
-v specifies verbose mode
This program reads a list of lon/lat coordinates and creates a GLIMS
glacier ID for each one, and prints the results to standard output. If
no files are specified on the command line, then standard input is read.
If the longitude is not in the range 0-360, then a warning is printed to
standard error, and it is fixed. If a latitude is outside the range
[-90,90], then processing is aborted.
The input is expected to have two columns, in lon lat order. Comments
are allowed, and are preceded by a '#' character. Blank lines are also
allowed.
";
$opt_h = $opt_v = $opt_l = '';
if (! getopts('lhv') ) {
die "$usage\n";
}
print STDERR "$progname version $version\n" if $opt_v;
die "$usage\n" if $opt_h;
while (<>) {
next if /^\s*#/; # skip comments
next if /^\s*$/; # skip blank lines
s/\s*#.*$//; # strip comments off of data lines
($lon,$lat) = split;
$id = &make_glims_id( $lon, $lat );
if ($opt_l) {
write;
} else {
print "$id\n";
}
}
sub make_glims_id {
my ($lon, $lat) = @_;
$lon = &fix_lon( $lon );
&check_lat( $lat );
my $SN = $lat < 0 ? "S" : "N";
$lat = abs($lat);
my $id = sprintf( "G%07.3fE%06.3f$SN", $lon, $lat );
$id =~ s/\.//g;
return $id;
}
sub fix_lon {
my $lon = $_[0];
my $absolute_lower_limit = -360;
my $absolute_upper_limit = 360;
if ($lon >= 0 && $lon < 360) {
return $lon;
} else {
warn "Input longitude not in range [0,360). Fixing.\n";
# This next check isn't necessary for the fix, but it might be a good
# idea for sanity.
if ($lon < $absolute_lower_limit || $lon > $absolute_upper_limit) {
die "Input longitude is outside the range [$absolute_lower_limit,$absolute_upper_limit].
Maybe something is really wrong! Aborting.\n";
}
$lon = fmod($lon, 360.0);
$lon += 360.0 if $lon < 0;
}
return $lon;
}
sub check_lat {
my $lat = $_[0];
if ($lat < -90 || $lat > 90) {
die "Input latitude is outside the range [-90,90]. Aborting.\n";
}
}
format STDOUT =
@<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<
$lon,$lat,$id
.
More information about the GLIMS
mailing list