#!/usr/bin/perl -w # # # This program converts the lat/long on the clipboard, which # is assumed to be in NAD27 datum to the WGS84 datum, or at # least the NAD83 datum. The lat/long on the clipboard can # be in any format recognized by Geo::ExtractDD. The longitudes # in this program are all kept in the positive sign (no negative numbers). # # This program uses the simple grid-based shift method, with bilinear # interpolation between 0.25 degree grid points. The program NADCON # # # use strict; use warnings; use Text::CSV; use Win32::Clipboard; use Geo::ExtractDD; use Geo::WebService::Elevation::USGS; use Geo::Coordinates::Converter; $| = 1; #Autoflush STDOUT my $infile1 = 'conus-lat.txt'; my $infile2 = 'conus-long.txt'; chdir 'C:/Perl64/DB/NAD27 to WGS84'; my ($latlow, $longlow, $latdifflow1, $latdifflow2, $latdiffhi1, $latdiffhi2, $longdifflow1, $longdifflow2, $longdiffhi1, $longdiffhi2); my (@fields1, @fields2); #my $latd = '38.898748'; #my $longd = '-77.037684'; my $clip = Win32::Clipboard(); my $latlong = $clip->GetText(); my ($latd, $longd) = extractdd($latlong); die "\nLat/long given is outside the continental US.\nThe program only works within the continental US.\n\n" if ($latd < 20 or $latd > 50 or $longd < 64 or $longd > 132); if ($latd) { # $longd = 0 - $longd; # die "\$latd = $latd\n\$longd = $longd\n\n"; my $intlatd = int $latd; if ($latd - $intlatd < 0.25) { $latlow = $intlatd; } elsif ($latd - $intlatd < 0.5 and $latd - $intlatd >= 0.25) { $latlow = $intlatd + 0.25; } elsif ($latd - $intlatd < 0.75 and $latd - $intlatd >= 0.5) { $latlow = $intlatd + 0.5; } elsif ($latd - $intlatd < 0.999999999999 and $latd - $intlatd >= 0.75) { $latlow = $intlatd + 0.75; } my $lathi = $latlow + 0.25; $latlow = sprintf("%.2f", $latlow); $lathi = sprintf("%.2f", $lathi); my $intlongd = int $longd; if ($longd - $intlongd < 0.25) { $longlow = $intlongd; } elsif ($longd - $intlongd < 0.5 and $longd - $intlongd >= 0.25) { $longlow = $intlongd + 0.25; } elsif ($longd - $intlongd < 0.75 and $longd - $intlongd >= 0.5) { $longlow = $intlongd + 0.5; } elsif ($longd - $intlongd < 0.999999999999 and $longd - $intlongd >= 0.75) { $longlow = $intlongd + 0.75; } my $longhi = $longlow + 0.25; $longlow = sprintf("%.2f", $longlow); $longhi = sprintf("%.2f", $longhi); my $csv1 = Text::CSV->new({ sep_char => "\t" }); open(INLAT, '<', $infile1) or die "Can't open '$infile1': $!"; while (my $line = ) { chomp $line; if ($csv1->parse($line)) { @fields1 = $csv1->fields(); if ($fields1[0] =~ /$latlow/ and $fields1[1] =~ /$longlow/) { $latdifflow1 = $fields1[2]; $latdifflow2 = $fields1[3]; $latdifflow1 = $latdifflow1 * 1 / 60 / 60; $latdifflow2 = $latdifflow2 * 1 / 60 / 60; } if ($fields1[0] =~ /$lathi/ and $fields1[1] =~ /$longlow/) { $latdiffhi1 = $fields1[2]; $latdiffhi2 = $fields1[3]; $latdiffhi1 = $latdiffhi1 * 1 / 60 / 60; $latdiffhi2 = $latdiffhi2 * 1 / 60 / 60; } } } close INLAT; my $csv2 = Text::CSV->new({ sep_char => "\t" }); open(INLONG, '<', $infile2) or die "Can't open '$infile2': $!"; while (my $line = ) { chomp $line; if ($csv2->parse($line)) { @fields2 = $csv2->fields(); if ($fields2[0] =~ /$latlow/ and $fields2[1] =~ /$longlow/) { $longdifflow1 = $fields2[2]; $longdifflow2 = $fields2[3]; $longdifflow1 = $longdifflow1 * 1 / 60 / 60; $longdifflow2 = $longdifflow2 * 1 / 60 / 60; } if ($fields2[0] =~ /$latlow/ and $fields2[1] =~ /$longhi/) { $longdiffhi1 = $fields2[2]; $longdiffhi2 = $fields2[3]; $longdiffhi1 = $longdiffhi1 * 1 / 60 / 60; $longdiffhi2 = $longdiffhi2 * 1 / 60 / 60; } } } close INLONG; # print "$latlow, $lathi, $longlow, $longhi, $latd, $longd\n"; # print "\n$latdiffhi2 - $latdiffhi1\n$latdifflow2 - $latdifflow1\n$longdiffhi2 - $longdiffhi1\n$longdifflow2 - $longdifflow1\n\n"; my $latinterp = ($latd - $latlow) / ($lathi - $latlow); my $longinterp = ($longd - $longlow) / ($longhi - $longlow); my $latcalc1 = $latinterp * ($latdiffhi2 - $latdifflow2) + $latdifflow2; my $latcalc2 = $latinterp * ($latdiffhi1 - $latdifflow1) + $latdifflow1; my $latdiff = $longinterp * ($latcalc1 - $latcalc2) + $latcalc2; my $longcalc1 = $longinterp * ($longdifflow2 - $longdifflow1) + $longdifflow1; my $longcalc2 = $longinterp * ($longdiffhi2 - $longdiffhi1) + $longdiffhi1; my $longdiff = $latinterp * ($longcalc2 - $longcalc1) + $longcalc1; # print "\n\n$latdiff - $longdiff\n\n"; my $wgslat = $latd + $latdiff; my $wgslong = $longd + $longdiff; $wgslat = sprintf("%.7f", $wgslat); $wgslong = sprintf("%.7f", $wgslong); print "\n\nWGS84 = $wgslat, $wgslong\n\n"; $clip->Empty(); $clip->Set("$wgslat, $wgslong"); print "\nAll done. \n\n"; } else { print "Did not match on lat/long $latlong\n\n"; } __END__