Generated: Tue Feb 2 17:54:55 2010 from set-bucket.pl 2009/03/25 6.7 KB.
#!/perl -w # NAME: set-bucket.pl # AIM: A perl rendering of the set_bucket() function in Simgear # 04/03/2009 geoff mclane http://geoffair.net/mperl use strict; use warnings; require 'logfile.pl' or die "Unable to load logfile.pl ...\n"; # log file stuff my ($LF); my $pgmname = $0; if ($pgmname =~ /\w{1}:\\.*/) { my @tmpsp = split(/\\/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = "temp.$pgmname.txt"; open_log($outfile); prt( "$0 ... Hello, World ...\n" ); # features my $out_all = 0; my $sample = '150.249900000008:-30: lon=150, lat=-30, x=0, y=0 '; ###my $sample = '-112:-47: lon=-112, lat=-47, x=0, y=0 '; my $min_len = length($sample); my $SG_BUCKET_SPAN = 0.125; #/** # * half of a standard SG_BUCKET_SPAN # */ my $SG_HALF_BUCKET_SPAN = ( 0.5 * $SG_BUCKET_SPAN ); #/** For divide by zero avoidance, this will be close enough to zero */ my $SG_EPSILON = 0.0000001; my ($lon, $lat, $x, $y, $path, $ind); sub gen_index() { return (($lon + 180) << 14) + (($lat + 90) << 6) + ($y << 3) + $x; } #// return the horizontal tile span factor based on latitude #static double sg_bucket_span( double l ) { sub sg_bucket_span($) { my ($l) = shift; if ( $l >= 89.0 ) { return 360.0; } elsif ( $l >= 88.0 ) { return 8.0; } elsif ( $l >= 86.0 ) { return 4.0; } elsif ( $l >= 83.0 ) { return 2.0; } elsif ( $l >= 76.0 ) { return 1.0; } elsif ( $l >= 62.0 ) { return 0.5; } elsif ( $l >= 22.0 ) { return 0.25; } elsif ( $l >= -22.0 ) { return 0.125; } elsif ( $l >= -62.0 ) { return 0.25; } elsif ( $l >= -76.0 ) { return 0.5; } elsif ( $l >= -83.0 ) { return 1.0; } elsif ( $l >= -86.0 ) { return 2.0; } elsif ( $l >= -88.0 ) { return 4.0; } elsif ( $l >= -89.0 ) { return 8.0; } # else { return 360.0; #} } sub get_tile { # $alon, $alat my ($lon, $lat) = @_; my $tile = 'e'; if ($lon < 0) { $tile = 'w'; $lon = -$lon; } my $ilon = int($lon / 10) * 10; if ($ilon < 10) { $tile .= "00$ilon"; } elsif ($ilon < 100) { $tile .= "0$ilon"; } else { $tile .= "$ilon" } if ($lat < 0) { $tile .= 's'; $lat = -$lat; } else { $tile .= 'n'; } my $ilat = int($lat / 10) * 10; if ($ilat < 10) { $tile .= "0$ilat"; } elsif ($ilon < 100) { $tile .= "$ilat"; } else { $tile .= "$ilat" } return $tile; } #// Set the bucket params for the specified lat and lon #void SGBucket::set_bucket( double dlon, double dlat ) { sub set_bucket($$) { my ($dlon, $dlat) = @_; # // # // latitude first # // # double span = sg_bucket_span( dlat ); # double diff = dlon - (double)(int)dlon; my $span = sg_bucket_span( $dlat ); my $diff = $dlon - int($dlon); #// cout << "diff = " << diff << " span = " << span << endl; if ( ($dlon >= 0) || (abs($diff) < $SG_EPSILON) ) { $lon = int($dlon); } else { $lon = int($dlon - 1); } #// find subdivision or super lon if needed if ( $span < $SG_EPSILON ) { #// polar cap $lon = 0; $x = 0; } elsif ( $span <= 1.0 ) { $x = int(($dlon - $lon) / $span); } else { if ( ($dlon >= 0) || (abs($diff) < $SG_EPSILON) ) { $lon = int( int($lon / $span) * $span); } else { #// cout << " lon = " << lon #// << " tmp = " << (int)((lon-1) / span) << endl; $lon = int( int(($lon + 1) / $span) * $span - $span); if ( $lon < -180 ) { $lon = -180; } } $x = 0; } # // # // then latitude # // $diff = $dlat - int($dlat); if ( ($dlat >= 0) || (abs($diff) < $SG_EPSILON) ) { $lat = int($dlat); } else { $lat = int($dlat - 1); } $y = int(($dlat - $lat) * 8); } #// Build the path name for this bucket #string SGBucket::gen_base_path() const { sub gen_base_path() { #// long int index; my ($top_lon, $top_lat, $main_lon, $main_lat); my ($hem, $pole); # char raw_path[256]; $top_lon = $lon / 10; $main_lon = $lon; if ( ($lon < 0) && ($top_lon * 10 != $lon) ) { $top_lon -= 1; } $top_lon *= 10; if ( $top_lon >= 0 ) { $hem = 'e'; } else { $hem = 'w'; $top_lon *= -1; } if ( $main_lon < 0 ) { $main_lon *= -1; } $top_lat = $lat / 10; $main_lat = $lat; if ( ($lat < 0) && ($top_lat * 10 != $lat) ) { $top_lat -= 1; } $top_lat *= 10; if ( $top_lat >= 0 ) { $pole = 'n'; } else { $pole = 's'; $top_lat *= -1; } if ( $main_lat < 0 ) { $main_lat *= -1; } return sprintf("$hem%03d$pole%02d/$hem%03d$pole%02d", $top_lon, $top_lat, $main_lon, $main_lat); # SGPath path( raw_path ); # return path.str(); } sub show_bucket($$$) { my ($ii, $jj, $disp) = @_; set_bucket( $ii, $jj ); $path = gen_base_path(); my $msg = "$ii:$jj: lon=$lon, lat=$lat, x=$x, y=$y"; $msg .= ' ' while (length($msg) < $min_len); $ind = gen_index(); prt( "$msg [$path] $ind\n" ) if ($disp); } # 0 KSFO San Francisco Intl (37.6208607739872,-122.381074803838) tile=w120n30 show_bucket(-122.381074803838, 37.6208607739872, 1); my $cnt = 0; my $max = 8; my $test_lon = 150.0; my $test_lat = -30; my ($last_lon, $last_lat, $next_lon, $next_lat); prt( "$cnt: " ); show_bucket($test_lon, $test_lat, 1); my $test_path = $path; my $test_ind = $ind; my ($ti, $tj); my $new_path = $path; my $new_ind = $ind; $last_lon = $test_lon; $last_lat = $test_lat; for ($ti = $test_lon; ; $ti += 0.0001) { $tj = $test_lat; show_bucket( $ti, $tj, 0 ); if (($new_path ne $path)||($new_ind != $ind)) { $new_path = $path; $new_ind = $ind; $cnt++; prt( "$cnt: " ); show_bucket( $last_lon, $last_lat, 1 ); if ($cnt > $max) { last; } } $last_lon = $ti; $last_lat = $tj; } prt( "\nAnd back wards...\n" ); $next_lon = $test_lon; $next_lat = $test_lat; $cnt = 0; prt( "$cnt: " ); show_bucket($test_lon, $test_lat, 1); $new_path = $path; $new_ind = $ind; $last_lon = $test_lon; $last_lat = $test_lat; for ($ti = $test_lon; ; $ti -= 0.0001) { show_bucket( $ti, $tj, 0 ); if (($new_path ne $path)||($new_ind != $ind)) { $new_path = $path; $new_ind = $ind; $cnt++; prt( "$cnt: " ); show_bucket( $next_lon, $next_lat, 1 ); if ($cnt > $max) { last; } } $next_lon = $ti; $next_lat = $tj; } if ($out_all) { for (my $i = -180; $i <= 180; $i++) { for (my $j = -90; $j <= 90; $j++) { show_bucket( $i, $j, 1 ); } } } close_log($outfile,1); exit(0); # eof