gPoint Class v1.2 Documentation
Copyright © 2006, 2007 Brenor Brophy

The source code included in this package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Contents

About the gPoint Class

A gPoint object is a point on the Earth's surface. Its location is defined by a Longitude and a Latitude coordinate. These coordinates define a point on the surface of a sphere. However, computer screens like paper are flat surfaces and so we face a problem if we wish to represent data whose location is defined by Lat/Longs onto a such a surface. For example, you have an array of Lat/Long points that you want to plot on an image of a map. So how do you calculate the X/Y pixel on the image to plot your point? What you need is a transformation from a Lat/Long coordinate to an X/Y coordinate. This is called a map projection. There are many different types of projection. This class provides functions for working with two of the most useful; Universal Transverse Mercator (UTM) and Lambert Conformal Conic. The class also supports a variant of UTM, that I call Local Transverse Mercator. It is very useful when you just need to plot a few points on an arbitrary image that covers a modest amount of the Earth (10x10 degrees) and you don't have to deal with UTM zones.

At a high level converting a Long/Lat coordinate in degrees thru a projection will return an Easting/Northing coordinate in meters. That is meters measured on the 'flat' ground that you can convert to pixels and plot on an image. Broadly speaking Transverse Mercator (and UTM) is useful for modest sized areas of about 10x10degrees or less. Lambert is useful for large areas in the mid latitudes (Like the whole USA or Europe for example). Neither projection works well for areas near the poles.

 

gPoint Class Methods
 

$pt =& new gPoint(["DATUM"]);

Creates a new gPoint object. The DATUM parameter may be one of the following:

"Airy"
"Australian National"
"Bessel 1841"
"Bessel 1841 Nambia"
"Clarke 1866"
"Clarke 1880"
"Everest"
"Fischer 1960 Mercury"
"Fischer 1968"
"GRS 1967"
"GRS 1980"
"Helmert 1906"
"Hough"
"International"
"Krassovsky"
"Modified Airy"
"Modified Everest"
"Modified Fischer 1960"
"South American 1969"
"WGS 60"
"WGS 66"
"WGS 72"
"WGS 84"

If left empty, then the default DATUM is "WGS 84". The datum reference ellipsoids were derived from Peter Dana's web page (now moved to) at http://www.colorado.edu/geography/gcraft/notes/datum/datum_f.html. According to the original source this data is from Defense Mapping Agency. 1987b. DMA Technical Report: Supplement to Department of Defense World Geodetic System 1984 Technical Report. Part I and II. Washington, DC: Defense Mapping Agency.

$pt->setLongLat($long, $lat);

Method to set the latitude and longitude of the gPoint object. Longitudes east of the prime meridian (i.e. east of Greenwich) are positive, longitudes west of the prime meridian are negative. North latitudes are positive, South latitudes are negative. $long and $lat should be in decimal degrees.

$long = $pt->Long(); $lat = $pt->Lat();

Methods to get the values of the Long and Lat properties.

$pt->printLatLong();

Method to print out the current values of the Long and Lat properties.

$pt->setUTM($easting, $northing, [$zone]);

Method to set the easting, northing and optionally the zone properties of the gPoint. Easting and northing are in decimal meters. Zone is in ASCII, for example "10S". If zone is left out then only "local" TM mapping can be performed.

$easting = $pt->E(); $northing = $pt->N(); $zone = $pt->Z();

Methods to get the values of the Northing, Easting and Zone properties.

$pt->printUTM();

Method to print out the current values of the Northing, Easting and Zone properties.

$pt->setLambert($northing, $easting);

Method to set the easting and northing properties of the gPoint for the Lambert projection. Easting and northing are in decimal meters.

$easting = $pt->lccE(); $northing = $pt->lccN();

Methods to get the values of the Lambert Northing and Easting properties.

$pt->printLambert()

Method to print out the current values of the Lambert Northing and Easting properties.

$pt->configLambertProjection ($falseEasting, $falseNorthing, $longOfOrigin, $latOfOrigin, $firstStdParallel, $secondStdParallel);

This function sets up a number of important parameters needed to define and calculate a particular Lambert Projection. $falseEasting & $falseNorthing are just an offset in meters added to the final coordinate calculated. $longOfOrigin & $LatOfOrigin are the "center" latitude and longitude of the area being projected. All coordinates will be calculated in meters relative to this point on the earth. $firstStdParallel & $secondStdParallel are the two lines of longitude (that is they run east-west) that define where the "cone" intersects the earth. Simply put they should bracket the area being projected.

$pt->convertLLtoTM([$LongOrigin]);

This method converts Longitude/Latitude values to UTM. The equations used are from from USGS Bulletin 1532. The original code upon which this method is based was written in C by Chuck Gantz- chuck.gantz@globalstar.com and is available at http://www.gpsy.com/gpsinfo/geotoutm/ along with much additional useful information.

UTM coordinates are useful when dealing with paper maps. Basically the map will can cover a single UTM zone which is 6 degrees on longitude. So you really don't care about an object crossing two zones. You just get a second map of the other zone. However, if you happen to live in a place that straddles two zones (For example the Santa Barbara area in CA straddles zone 10 and zone 11) Then it can become a real pain having to have two maps all the time. So relatively small parts of the world (like say California) create their own version of UTM coordinates that are adjusted to convert the whole area of interest on a single map. These are called state grids. The projection system is the usually same as UTM (i.e. Transverse Mercator), but the central meridian aka Longitude of Origin is selected to suit the longitude of the area being mapped (like being moved to the central meridian of the area) and the grid may cover more than the 6 degrees of longitude found on a UTM map. Areas that are wide rather than long - think Montana as an example. May still have to have a couple of maps to cover the whole state because TM projection looses accuracy as you move further away from the Longitude of Origin, 15 degrees is usually the limit.

Now, in the case where we want to generate electronic maps that may be placed pretty much anywhere on the globe we really don't to deal with the issue of UTM zones in our coordinate system. We would really just like a grid that is fully contiguous over the area of the map we are drawing. Similar to the state grid, but local to the area we are interested in. I call this Local Transverse Mercator and I have modified the function below to also make this conversion. If you pass the optional Longitude value to the function as $LongOrigin then that is the Longitude of Origin that will be used for the projection. Easting coordinates will be returned (in meters) relative to that line of longitude - So an Easting coordinate for a point located East of the longitude of origin will be a positive value in meters, an Easting coordinate for a point West of the longitude of Origin will have a negative value in meters. Northings will always be returned in meters from the equator same as the UTM system. The UTMZone value will be valid for Long/Lat given - thought it is not meaningful in the context of Local TM. If a NULL value is passed for $LongOrigin then the standard UTM coordinates are calculated.

$pt->convertTMtoLL([$longOrigin]);

If a value is passed for $longOrigin then the method assumes that a Local (to the Longitude of Origin passed in) Transverse Mercator coordinates is to be converted - not a UTM coordinate. This is the complementary method to the previous one. The function cannot tell if a set of Northing/Easting coordinates are in the North or South hemisphere - they just give distance from the equator not direction - so only northern hemisphere lat/long coordinates are returned. If you live south of the equator there is a note later in the code explaining how to have it just return southern hemisphere lat/longs.

$pt->convertLLtoLCC();

This method will convert a Latitude/Longitude coordinate to an Northing/Easting coordinate on a Lambert Conic Projection. The configLambertProjection() method should have been called prior to this one to setup the specific parameters for the projection. The Northing/Easting parameters calculated are in meters (because the datum used is in meters) and are relative to the falseNorthing/falseEasting coordinate. Which in turn is relative to the Lat/Long of origin The formula were obtained from URL: http://www.ihsenergy.com/epsg/guid7_2.html but appear to be no longer available at that URL.

$pt->convertLCCtoLL();

The inverse to the previous method.

$dist = $pt->distanceFrom($lon1, $lat1);

This is a useful method that returns the Great Circle distance from the gPoint to another Long/Lat coordinate

$dist = $pt->distanceFromTM(&$pt);

This method also calculates the distance between this point and another gPoint object. In this case it just uses Pythagoras's theorem using TM coordinates.

$pt->gRef($rX, $rY, $rE, $rN, $Scale, $LongOrigin);

This method geo-references a gPoint to a given map. This means that it calculates the x,y pixel coordinate on the map that corresponds to the Lat/Long value of the gPoint. A map is of course just an image file like a jpeg or gif. This method is quite limited. It assumes that the scale of map is identical in both X & Y directions; that the map is in the northern hemisphere and that the 0,0 pixel coordinate is the top left corner of the image.

You need to know two things about your map image in order to use this method. First you must know the scale of the map. The scale is a number in meters per pixel. For example, if your image is 200 pixels wide and the distance it covers is 1000km, then the scale is (1000x1000)/200 = 5000 meters per pixel. That is, every little pixel on your image represents a patch of ground 5000 meters wide and 5000 meters long. The second thing you need is a reference point on the image. This is a point for which you know both the pixel coordinate and the latitude/longitude.

First you need to convert the Lat/Long of your reference point to a Easting/Northing coordinate in a local TM projection. I suggest you use the Longitude of the reference point as you $LongOrigin parameter. If you do this then the Easting value of the reference point will be zero.

The parameters $rX & $rY are the pixel coordinates of the reference point, these correspond to the parameters $rE & $rN which are the Northing/Easting coordinate of the same point. The $Scale parameter is the scale of the map in meters/pixel. The $LongOrigin parameter is whatever value was used to convert the reference point.

 

Code Examples
 

Create a new gPoint and set its Longitude and Latitude

$myHome =& new gPoint(); // Create an empty point with the default datum
//
// Set the point's Longitude & Latitude.
//
$myHome->setLongLat(-121.85831, 37.42104); // I live in sunny California :-)
echo "I live at: "; $myHome->printLatLong(); echo "<br>";


Calculate the coordinates of the point in a UTM projection

$myHome->convertLLtoTM();
echo "Which in a UTM projection is: "; $myHome->printUTM(); echo "<br>";


Set the UTM coordinates of the point to check the reverse conversion
$myHome->setUTM( 601034, 4142188, "10S"); // Easting/Northing from a GPS
echo "My GPS says it is this: "; $myHome->printUTM(); echo "<br>";
Calculate the Longitude Latitude of the point
$myHome->convertTMtoLL();
echo "Which converts back to: "; $myHome->printLatLong(); echo "<br>";

Now lets try the same conversion, only this time we will user a "Local" Transverse Mercator projection. -122 degrees longitude is close to the area of interest so lets use that as our Longitude of Origin
$longOrigin = -122;
$myHome->convertLLtoTM($longOrigin);
echo "In a Local TM projection centered at longitude $longOrigin it is: "; $myHome->printUTM(); echo "<br>";
//
// Now check the reverse conversion
//

$myHome->convertTMtoLL($longOrigin);
echo "Converting back gives us: "; $myHome->printLatLong(); echo "<br>";

Setup a Lambert Conformal Conic projection for Northern California

falseEasting = 20000000, falseNorthing = 0
Longitude of origin = -122, Latitude of origin 35 30',
First Standard Parallel = 33 20', Second Standard Parallel = 38 40'
$myHome->configLambertProjection(2000000, 0, -122, 35.5, 33.33333, 38.6666);
$myHome->convertLLtoLCC();
echo "In a Lambert Projection: "; $myHome->printLambert(); echo "<br>";
//
// And convert back to Longitude / Latitude
//

$myHome->convertLCCtoLL();
echo "And is still: "; $myHome->printLatLong(); echo "<br>";

 

Revision History
 
Revison Date Details
1.0 25th August, 2005 Initial Release.
1.1 15th May, 2006 Added software license language to header comments Fixed an error in the convertTMtoLL() method. The latitude calculation had a bunch of variables without $ symbols. Fixed an error in convertLLtoTM() method, The $this-> was missing in front of a couple of variables. Thanks to Bob Robins of Maryland for catching the bugs. Also created this readme file to improve the documentation.
1.2 18th May, 2007 Added default of NULL to $LongOrigin arguement in convertTMtoLL() and convertLLtoTM() to eliminate warning messages when the methods are called without a value for $LongOrigin.