Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Coordinate

by orbital (Scribe)
on Mar 20, 2001 at 04:14 UTC ( [id://65592]=modulereview: print w/replies, xml ) Need Help??

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

  • 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: 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?

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

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
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: modulereview [id://65592]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-03-29 10:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found