Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I just recently started using the GPS::Garmin module by Joao Pedro B Gonçalves , 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).

  • 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).

    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 EROS 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 SDTS dem data Unfortantly there is no perl modules that will convert sdts information, but there are some great C libraries and programs already avaliable.

Coordinate Module

This little gem by Curtis Mills is not on CPAN, however you can download it from his site at: or
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?

  • Creating and manipulating Coordinate objects
  • Translating coordinates between UTM and Latitude/Longitude
  • Translating coordinates between ~231 different datums (Datums are used to "describe" the surface of Earth since its not a perfect Geometric shape, its Geodetic.
  • Formatting coordinates into decimal degrees, degrees/minutes, and degrees/minutes/seconds.

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.

In reply to Coordinate by orbital

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others meditating upon the Monastery: (4)
    As of 2021-03-02 18:10 GMT
    Find Nodes?
      Voting Booth?
      My favorite kind of desktop background is:

      Results (57 votes). Check out past polls.