calc-tile.pl to HTML.

index -|- end

Generated: Sat Oct 24 16:35:10 2020 from calc-tile.pl 2016/10/08 8.6 KB. text copy

#!/usr/bin/perl -w
########################################################################
# calc-tile.pl
#
# Synopsis: Calculate a FlightGear tile base on longitude and latitude.
# Usage: perl calc-tile.pl <lon> <lat>
########################################################################

use strict;
use warnings;
use POSIX;



########################################################################
# Constants.
########################################################################

my $EPSILON = 0.0000001;
my $DIRSEP = '/';
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}


########################################################################
# Globals.
########################################################################
my $download = '';
my ($lon, $lat);

# user variables
my $VERS = "0.0.6 2016-10-08";
my $load_log = 0;
my $in_file = '';
my $verbosity = 0;
my $out_file = '';

# ### DEBUG ###
my $debug_on = 0;
my $def_file = 'def_file';

### program variables
my @warnings = ();

########################################################################
# Functions.
########################################################################

sub prt($) { print shift }

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    ### show_warnings($val);
    ### close_log($outfile,$load_log);
    exit($val);
}

#
# Calculate the number of columns of tiles in a degree of longitude.
#
sub bucket_span {
  my ($lat) = (@_);
  if ($lat>= 89.0 ) {
    return 360.0;
  } elsif ($lat>= 88.0 ) {
    return 8.0;
  } elsif ($lat>= 86.0 ) {
    return 4.0;
  } elsif ($lat>= 83.0 ) {
    return 2.0;
  } elsif ($lat>= 76.0 ) {
    return 1.0;
  } elsif ($lat>= 62.0 ) {
    return 0.5;
  } elsif ($lat>= 22.0 ) {
    return 0.25;
  } elsif ($lat>= -22.0 ) {
    return 0.125;
  } elsif ($lat>= -62.0 ) {
    return 0.25;
  } elsif ($lat>= -76.0 ) {
    return 0.5;
  } elsif ($lat>= -83.0 ) {
    return 1.0;
  } elsif ($lat>= -86.0 ) {
    return 2.0;
  } elsif ($lat>= -88.0 ) {
    return 4.0;
  } elsif ($lat>= -89.0 ) {
    return 8.0;
  } else {
    return 360.0;
  }
}

#
# Format longitude as e/w.
#
sub format_lon {
  my ($lon) = (@_);
  if ($lon < 0) {
    return sprintf("w%03d", int(0-$lon));
  } else {
    return sprintf("e%03d", int($lon));
  }
}

#
# Format latitude as n/s.
#
sub format_lat {
  my ($lat) = (@_);
  if ($lat < 0) {
    return sprintf("s%02d", int(0-$lat));
  } else {
    return sprintf("n%02d", int($lat));
  }
}

#
# Generate the directory name for a location.
#
sub directory_name {
  my ($lon, $lat) = (@_);
  my $lon_floor = POSIX::floor($lon);
  my $lat_floor = POSIX::floor($lat);
  my $lon_chunk = POSIX::floor($lon/10.0) * 10;
  my $lat_chunk = POSIX::floor($lat/10.0) * 10;
  $download = format_lon($lon_chunk) . format_lat($lat_chunk) . '.tgz';
  return format_lon($lon_chunk) . format_lat($lat_chunk) . $DIRSEP
    . format_lon($lon_floor) . format_lat($lat_floor);
}

#
# Generate the tile index for a location.
#
sub tile_index {
  my ($lon, $lat) = (@_);
  my $lon_floor = POSIX::floor($lon);
  my $lat_floor = POSIX::floor($lat);
  my $span = bucket_span($lat);

  my $x;
  if ($span < $EPSILON) {
    $lon = 0;
    $x = 0;
  } elsif ($span <= 1.0) {
    $x = int(($lon - $lon_floor) / $span);
  } else {
    if ($lon >= 0) {
      $lon = int(int($lon/$span) * $span);
    } else {
      $lon = int(int(($lon+1)/$span) * $span - $span);
      if ($lon < -180) {
        $lon = -180;
      }
    }
    $x = 0;
  }

  my $y;
  $y = int(($lat - $lat_floor) * 8);


  my $index = 0;
  $index += ($lon_floor + 180) << 14;
  $index += ($lat_floor + 90) << 6;
  $index += $y << 3;
  $index += $x;

  return $index;
}

my $PI = 3.1415926535897932384626433832795029;
my $D2R = $PI / 180;
my $R2D = 180 / $PI;

# function lon2tile( lon, zoom ) {
sub lon2tile($$) {
    my ($lon, $zoom) = @_;
    ##return Math.floor( ( lon + 180 ) / 360 * Math.pow( 2, zoom ) );
    return int( ( $lon + 180 ) / 360 * ($zoom * $zoom) );
}
# function lat2tile( lat, zoom ) {
sub lat2tile($$) {
    my ($lat, $zoom) = @_;
   my $pi = $PI
   # return Math.floor(( 1 - Math.log( Math.tan( lat * pi / 180) + 1 / Math.cos( lat * pi / 180)) / pi )/2 * Math.pow(2, zoom) );
   #return int(( 1 - Math.log( Math.tan( lat * pi / 180) + 1 / Math.cos( lat * pi / 180)) / pi )/2 * Math.pow(2, zoom) );
}
#function tile2lon( x, zoom ) {
#   return ( x / Math.pow( 2, zoom ) * 360 - 180 );
#}
#function tile2lat( y, zoom ) {
#var pi = Math.PI
#var n = pi - 2 * pi * y / Math.pow( 2, zoom );
#return 180 / pi * Math.atan( 0.5 * ( Math.exp( n ) - Math.exp( -n ) ));
#}



### if ((scalar @ARGV) < 2) {
###   print "Usage: perl calc-tile.pl lon lat\n";
###   exit(-1);
### }
########################################################################
# Main program.
########################################################################
parse_args(@ARGV);

my $dir = directory_name($lon, $lat);
my $index = tile_index($lon, $lat);
my $path = "$dir$DIRSEP$index.stg";

prt("Longitude: $lon\n");
prt("Latitude:  $lat\n");
prt("Tile:      $index\n");
prt("Path:      \"$path\"\n");
prt("Download:  $download\n");

exit 0;
########################################

sub usage {
    prt("Usage: $pgmname [options] lon lat\n");
}

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av);
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    my $verb = VERB2();
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                $verb = VERB2();
                prt("Verbosity = $verbosity\n") if ($verb);
            #} elsif ($sarg =~ /^l/) {
            #    if ($sarg =~ /^ll/) {
            #        $load_log = 2;
            #    } else {
            #        $load_log = 1;
            #    }
            #    prt("Set to load log at end. ($load_log)\n") if ($verb);
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if ($verb);
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            if ( ! defined $lon ) {
                $lon = $arg;
            } elsif ( ! defined $lat ) {
                $lat = $arg;
            } else {
                # todo: maybe list...
                usage();
                pgm_exit(1,"Error: Aleady have lon $lon and lat $lat!\nWhat is this $arg? At present only 2 bare args allowed.\n");
            }
            ### $in_file = $arg;
            ### prt("Set input to [$in_file]\n") if ($verb);
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        if (length($in_file) ==  0) {
            $in_file = $def_file;
            prt("Set DEFAULT input to [$in_file]\n");
        }
    }
    if ( !defined $lat || !defined $lon ) {
        # length($in_file) ==  0) {
        pgm_exit(1,"ERROR: No lon lat found in command!\n");
    }
    #if (! -f $in_file) {
    #    pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n");
    #}
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    usage();    # prt("Usage: $pgmname [options] lon lat\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    ### prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
}

# eof 1;

index -|- top

checked by tidy  Valid HTML 4.01 Transitional