http://qs1969.pair.com?node_id=65592

Item Description: Creating and manipulating Coordinate objects

Review Synopsis:

I just recently started using the GPS::Garmin module by Joao Pedro B Gonçalves , joaop@iscsp.utl.pt 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 (Universal Transverse Mercator).

Coordinate Module


This little gem by Curtis Mills is not on CPAN, however you can download it from his site at: http://www.eskimo.com/~archer or ftp://ftp.eskimo.com/u/a/archer/aprs/xastir/
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:

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.

If you want to check the accuracy of the results generated by Coordinate I suggest submiting your data to this web form

What does it exactly do?

Here is a chunk of sample code provided by Curtis:

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 f +ormat 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_sec +onds() ); print "180\n"; $temp->raw( "180" ); printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "1 +80") ); printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "1 +80") ); printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_sec +onds("180") ); print "180 30\n"; $temp->raw( "180 30" ); printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "1 +80 30") ); printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "1 +80 30") ); printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_sec +onds("180 30") ); print "180.50\n"; $temp->raw( "180.50" ); printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "1 +80.50") ); printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "1 +80.50") ); printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_sec +onds("180.50") ); $temp->raw( "180 30.50" ); print "180 30.50\n"; printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "1 +80 30.50") ); printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "1 +80 30.50") ); printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_sec +onds("180 30.50") ); $temp->raw( "180 30 30" ); print "180 30 30\n"; printf(" decimal_degrees: %s\n", $temp->decimal_degrees( "1 +80 30 30") ); printf(" degrees_minutes: %s\n", $temp->degrees_minutes( "1 +80 30 30") ); printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_sec +onds("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_sec +onds("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_sec +onds("-180 30 30.5") );
The output from this looks like following:

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 533 +0095.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

Curtis has also provide a few other methods that maybe useful,

EllipsoidTable->enumerate(); DatumTable->enumerate();
Both of these methods display the data tables that the program is basing its calculations on.

Replies are listed 'Best First'.
Re: Coordinate
by beretboy (Chaplain) on Aug 17, 2001 at 14:00 UTC
    COOL! I had been looking for something to do just this ++

    "Sanity is the playground of the unimaginative" -Unknown