modulereview
orbital
<p>I just recently started using the <a href="http://search.cpan.org/search?dist=perl-GPS">GPS::Garmin</a> module by Joao Pedro B Gonçalves , <a href="mailto:joaop@iscsp.utl.pt">joaop@iscsp.utl.pt</a> to dump my GPS data directly into my perl scripts. This module works great but unfortantly the Module gave me Lat. and Long. in degrees.minutes and I wanted it in UTM (<a href="http://www.maptools.com/UsingUTM/index.html">Universal Transverse Mercator</a>). <p><ul><li>UTM is the standard used by multiple organizations around the world to locate a specific point on earth. UTM is calculated by one central orgin on earth, everything thing from that point is represent in meters. The first set of numbers is refered to as the Easting (East-West postion) and the second number is refered to as the Northing (North-South position).<p>Advantages of having your data in UTM is that you are able to use USGS data in conjuction with your newly aquired data. You can obtain the data at <a href="http://edc.usgs.gov/doc/edchome/ndcdb/ndcdb.html">EROS</a> The DEM (Digital Elevation Models) data in my opinion the most useful, it allows you to grab a 3D snap shot of an area, in which you can then overlay your data on top of it.( here are the file specs for <a href="http://mcmcweb.er.usgs.gov/sdts/standard.html">SDTS dem data</a> Unfortantly there is no perl modules that will convert sdts information, but there are some great C libraries and programs already avaliable.</li></ul>
<p>
<b><h2>Coordinate Module</h2></b><hr><p>
This little gem by Curtis Mills is not on CPAN, however you can download it from his site at: <a href="http://www.eskimo.com/~archer">http://www.eskimo.com/~archer</a> or <a href="ftp://ftp.eskimo.com/u/a/archer/aprs/xastir/">ftp://ftp.eskimo.com/u/a/archer/aprs/xastir/</a><br>Curtis has converted several C GNU libraries into pure perl code with this module. However be aware that this is still a work in progress and has some small errors:<code>
Please note that I didn't pay a lot of attention to
keeping the "double" notation in the form of higher
precision floating point routines. This means that
the Perl5 code won't be as accurate as the original
C-code. It doesn't matter for my purposes. If
anyone converts to Math::BigFloat for higher precision,
please send me the changes. As it is I did a
quick check and found a difference of only 1.4 meters
between my Perl results and the results from a web-based
datum-shift calculator on the 'net. -- Curt.</code><br>
If you want to check the accuracy of the results generated by <b>Coordinate</b> I suggest submiting your data to this <a href="http://www.geod.nrcan.gc.ca/products/html-public/GSDapps/English/gsrug.html#GSRUGdemo">web form</a><p>
<h3>What does it exactly do?</h3><p>
<ul>
<li>Creating and manipulating Coordinate objects</li>
<li>Translating coordinates between UTM and Latitude/Longitude</li>
<li>Translating coordinates between ~231 different datums (Datums are used to "describe" the surface of Earth since its not a perfect Geometric shape, its Geodetic.</li>
<li>Formatting coordinates into decimal degrees, degrees/minutes, and degrees/minutes/seconds.</li></ul><p>
Here is a chunk of sample code provided by Curtis:<p>
<code>
use Coordinate;
my $position = Coordinate->new();
$position->latitude(48.125);
$position->longitude(-122.500);
$position->datum("NAD27 CONUS MEAN:W of Mississippi/Except Louisiana/Minnesota/Missouri"); # Datum
printf("Starting position(Lat, Long): %s %s\n",
$position->latitude(),
$position->longitude() );
$position->degrees_minutes_seconds(); # Convert to DD MM SS format
printf("Starting position(Lat, Long): %s %s\n",
$position->formatted_latitude(),
$position->formatted_longitude() );
$position->lat_lon_to_utm();
printf("Calculated UTM position(Easting, Northing, Zone): %f %f %s\n",
$position->easting(),
$position->northing(),
$position->zone() );
$position->utm_to_lat_lon();
printf("Calculated Lat, Long position(Lat, Long): %f %f\n",
$position->latitude(),
$position->longitude() );
print "Changing from NAD27 to WGS84 datum...\n";
$position = $position->datum_shift_to_wgs84();
printf("Calculated Lat, Long position(Lat, Long): %f %f\n",
$position->latitude(),
$position->longitude() );
$position->degrees_minutes_seconds(); # Convert to DD MM SS
printf("Calculated Lat, Long position(Lat, Long): %s %s\n",
$position->formatted_latitude(),
$position->formatted_longitude() );
print "Changing from WGS84 to NAD27 datum...\n";
$position = $position->datum_shift_from_wgs84_to( "NAD27 CONUS MEAN:W of Mississippi/Except Louisiana/Minnesota/Missouri" );
printf("Calculated Lat, Long position(Lat, Long): %f %f\n",
$position->latitude(),
$position->longitude() );
print "\n0\n";
my $temp = CoordinateFormat->new( "0" );
printf(" decimal_degrees: %s\n", $temp->decimal_degrees( ) );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes( ) );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds() );
print "180\n";
$temp->raw( "180" );
printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "180") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "180") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180") );
print "180 30\n";
$temp->raw( "180 30" );
printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "180 30") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "180 30") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30") );
print "180.50\n";
$temp->raw( "180.50" );
printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "180.50") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "180.50") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180.50") );
$temp->raw( "180 30.50" );
print "180 30.50\n";
printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "180 30.50") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "180 30.50") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30.50") );
$temp->raw( "180 30 30" );
print "180 30 30\n";
printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "180 30 30") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "180 30 30") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30 30") );
$temp->raw( "180 30 30.5" );
print "180 30 30.5\n";
printf(" decimal_degrees: %s\n", $temp->decimal_degrees("180 30 30.5") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes("180 30 30.5") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30 30.5") );
$temp->raw( "-180 30 30.5" );
print "-180 30 30.5\n";
printf(" decimal_degrees: %s\n", $temp->decimal_degrees("-180 30 30.5") );
printf(" degrees_minutes: %s\n", $temp->degrees_minutes("-180 30 30.5") );
printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("-180 30 30.5") );</code>
The output from this looks like following:<p>
<code>
Starting position(Lat, Long): 48.125 -122.5
Starting position(Lat, Long): 48 07 30.00000000 -122 30 0.00000000
Calculated UTM position(Easting, Northing, Zone): 537208.685551 5330095.589079 10U
Calculated Lat, Long position(Lat, Long): 48.124997 -122.500000
Changing from NAD27 to WGS84 datum...
Calculated Lat, Long position(Lat, Long): 48.124789 -122.501238
Calculated Lat, Long position(Lat, Long): 48 07 29.23995960 -122 30 4.45751911
Changing from WGS84 to NAD27 datum...
Calculated Lat, Long position(Lat, Long): 48.124997 -122.500000
0
decimal_degrees: 0
degrees_minutes: 00 0.00000000
degrees_minutes_seconds: 00 00 0.00000000
180
decimal_degrees: 180
degrees_minutes: 180 0.00000000
degrees_minutes_seconds: 180 00 0.00000000
180 30
decimal_degrees: 180.50000000
degrees_minutes: 180 30
degrees_minutes_seconds: 180 30 0.00000000
180.50
decimal_degrees: 180.50
degrees_minutes: 180 30.00000000
degrees_minutes_seconds: 180 30 0.00000000
180 30.50
decimal_degrees: 180.50833333
degrees_minutes: 180 30.50
degrees_minutes_seconds: 180 30 30.00000000
180 30 30
decimal_degrees: 180.50833333
degrees_minutes: 180 30.50000000
degrees_minutes_seconds: 180 30 30
180 30 30.5
decimal_degrees: 180.50847222
degrees_minutes: 180 30.50833333
degrees_minutes_seconds: 180 30 30.5
-180 30 30.5
decimal_degrees: -180.50847222
degrees_minutes: -180 30.50833333
degrees_minutes_seconds: -180 30 30.5</code>
<p>
Curtis has also provide a few other methods that maybe useful,
<code>
EllipsoidTable->enumerate();
DatumTable->enumerate();
</code>
Both of these methods display the data tables that the program is basing its calculations on.
Creating and manipulating Coordinate objects