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