Simple perl script for calculating a tile path based on lon/lat. Does
not depend on SimGear, but doesn't handle objects right on the poles either.
This commit is contained in:
parent
743b4848cf
commit
3b3102d7c8
1 changed files with 159 additions and 0 deletions
159
scripts/perl/scenery/calc-tile.pl
Normal file
159
scripts/perl/scenery/calc-tile.pl
Normal file
|
@ -0,0 +1,159 @@
|
|||
#!/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 POSIX;
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# Constants.
|
||||
########################################################################
|
||||
|
||||
my $EPSILON = 0.0000001;
|
||||
my $DIRSEP = '/';
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# Functions.
|
||||
########################################################################
|
||||
|
||||
#
|
||||
# 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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# Main program.
|
||||
########################################################################
|
||||
|
||||
my ($lon, $lat) = (@ARGV);
|
||||
|
||||
my $dir = directory_name($lon, $lat);
|
||||
my $index = tile_index($lon, $lat);
|
||||
my $path = "$dir$DIRSEP$index.stg";
|
||||
|
||||
print "Longitude: $lon\n";
|
||||
print "Latitude: $lat\n";
|
||||
print "Tile: $index\n";
|
||||
print "Path: \"$path\"\n";
|
||||
|
||||
1;
|
Loading…
Add table
Reference in a new issue