#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #::: ::: #::: TITLE: Calculate Latitude and Longitude from Rate Center V&H in Perl ::: #::: ::: #::: This function calculates the latitude and longitude coordinates ::: #::: from Vertical and Horizontal (V&H) coordinates. V&H's are used to ::: #::: identify locations and hence relative distances between network ::: #::: elements and between rate centers listed in AreaCodeWorld(tm) Gold ::: #::: Edition in http://www.zipcodeworld.com. ::: #::: ::: #::: Function Input Parameters: ::: #::: V = Vertical value from 0 to 10000 ::: #::: H = Horizontal value from 0 to 10000 ::: #::: ::: #::: Function Output Parameters: ::: #::: Lat = Latitude from Vertical value ::: #::: Long = Longitude from Horizontal value ::: #::: ::: #::: North American Area Code NPA NXX database with V&H values is ::: #::: available at http://www.zipcodeworld.com. This sample code is ::: #::: provided to database subscribers "AS IS" without warranty of any kind. ::: #::: ::: #::: Email: sales@zipcodeworld.com ::: #::: ::: #::: URL: http://www.zipcodeworld.com ::: #::: ::: #::: ZIPCodeWorld.com © All Rights Reserved 2002-2005 ::: #::: ::: #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: use Math::Trig; #my ($lat, $lon) = vh2latlong(5079,1444); sub vh2latlong { my $v = 0; my $h = 0; ($v, $h) = @_; my $m_pi = 3.14159265358979323846; my $transv = 6363.235; my $transh = 2250.7; my $rotc = 0.23179040; my $rots = 0.97276575; my $radius = 12481.103; my $ex = 0.40426992; my $ey = 0.68210848; my $ez = 0.60933887; my $wx = 0.65517646; my $wy = 0.37733790; my $wz = 0.65449210; my $px = -0.555977821730048699; my $py = -0.345728488161089920; my $pz = 0.755883902605524030; my $gx = 0.216507961908834992; my $gy = -0.134633014879368199; my $a = 0.151646645621077297; my $q = -0.294355056616412800; my $q2 = 0.0866448993556515751; my @bi = ( 1.00567724920722457, -0.00344230425560210245, 0.000713971534527667990, -0.0000777240053499279217, 0.00000673180367053244284, -0.000000742595338885741395, 0.0000000905058919926194134 ); my $x = 0; my $y = 0; my $z = 0; my $delta =0; my $t1 = ($v - $transv) / $radius; my $t2 = ($h - $transh) / $radius; my $vhat = $rotc * $t2 - $rots * $t1; my $hhat = $rots * $t2 + $rotc * $t1; my $e = cos(sqrt($vhat * $vhat + $hhat * $hhat)); my $w = cos(sqrt($vhat * $vhat + ($hhat - 0.4) * ($hhat - 0.4))); my $fx = $ey * $w - $wy * $e; my $fy = $ex * $w - $wx * $e; my $b = $fx * $gx + $fy * $gy; my $c = $fx * $fx + $fy * $fy - $q2; my $disc = $b * $b - $a * $c; if ($disc == 0.0) { $z = $b / $a; $x = ($gx * $z - $fx) / $q; $y = ($fy - $gy * $z) / $q; } else { $delta = sqrt($disc); $z = ($b + $delta)/$a; $x = ($gx * $z - $fx) / $q; $y = ($fy - $gy * $z) / $q; if ( $vhat * ( $px * $x + $py * $y + $pz * $z) < 0 ) { $z = ($b - $delta) / $a; $x = ($gx * $z - $fx) / $q; $y = ($fy - $gy * $z) / $q; }; }; my $lat = asin($z); my $lat2 = $lat * $lat; my $earthlat = 0; for (my $i=6; $i>=0 ; $i--) { $earthlat = ($earthlat + $bi[$i]) * ($i? $lat2 : $lat); }; $earthlat *= 180/$m_pi; my $lon = atan2($x, $y) * 180 / $m_pi; my $earthlon = $lon + 52.0000000000000000; return ($earthlat, $earthlon); };