# Google Relative Pixel algorithm 
# Author. John D. Coryat 11/2007 USNaviguide.com...
# Adapted from: http://mapki.com/coordtotile.2.phps
##
# In order to correctly locate objects of interest on a GGroundOverlay image for Google Maps, 
# the relative pixel location on that image is the best method.
##

package USNaviguide_Google_RelPix ;
require 5.003 ;
use strict ;

BEGIN {
 use Exporter ;
 use vars qw ( $VERSION @ISA @EXPORT) ;
 $VERSION	= 1.1 ;
 @ISA		= qw ( Exporter ) ;
 @EXPORT	= qw ( 
 Google_RelPix
 ) ;
}

#
# Call as: (<Y Pixel (Latitude)>,<X Pixel (Longitude)>) = &Google_RelPix(<Latitude>, <Longitude>, <Zoom>) ;
#

sub Google_RelPix
{
 my $lat	= shift ;
 my $lng	= shift ;
 my $zoom	= shift ;
 my $e		= 0 ;
 my @d		= ( ) ;				# 0:x 1:y

 my $PI		= 3.1415926536 ;
 my $bc		= 2 * $PI;
 my $Wa		= $PI / 180;
 my $cp		= 2 ** ($zoom + 8) ;
 my $pixLngDeg	= $cp / 360;
 my $pixLngRad	= $cp / $bc ;
 my $bmO	= $cp / 2 ;

 $d[1] = sprintf("%0.0f", $bmO + $lng * $pixLngDeg ) ;

 $e = sin($lat * $Wa) ;

 if( $e > 0.99999 )
 {
  $e = 0.99999 ;
 }

 if( $e < -0.99999 )
 {
  $e = -0.99999 ;
 }

 $d[0] = sprintf("%0.0f", $bmO + 0.5 * log((1 + $e) / (1 - $e)) * (-1) * $pixLngRad ) ;

 return (@d) ;
}

1;

__END__

=head1 SYNOPSIS

#!/usr/bin/perl -w
# Test Program:

# Google Relative Pixel Test Program...
# Author. John D. Coryat 11/2007 USNaviguide.com

use strict;
use USNaviguide_Google_RelPix ;

my $sw		= '34.177442,-91.318359' ;
my $ne		= '35.797300,-88.681641' ;
my $zoom	= 8 ;
my @d1		= ( ) ;
my @d2		= ( ) ;
my $lat		= 0 ;
my $lng		= 0 ;

$sw =~ /(.*),(.*)/ ;

$lat = $1 ;
$lng = $2 ;
@d1 = &Google_RelPix($lat, $lng, $zoom);

$ne =~ /(.*),(.*)/ ;
$lat = $1 ;
$lng = $2 ;
@d2 = &Google_RelPix($lat, $lng, $zoom);

print "Theoretical Width: 480 Height: 360\n" ;
print "Calculated  Width: " . abs( $d1[1] - $d2[1] ) . " Height: " . abs( $d1[0] - $d2[0] ) . "\n" ;

=cut
