Geographic Distance and Azimuth Calculations

This code was "ported" to PHP from Visual C++ by Steven Brendtro of www.imaginerc.com. The original article and source code, written by andyf4i can be found here on CodeGuru.com.

Download PHP GeoCalc

Download the class: geocalc-php-2.1.tar.gz
(Includes a bug fix in getLonPerKmAtLat method.)

Download FREE Zip Code Data: PostalCodes.zip

Methods

Basic Methods:
GeoCalc() Default Constructor
GCDistance($lat1, $lon1, $lat2, $lon2) Using the Great Circle formula, calculate the distance in kilometers between Latitude/Longitude 1 and Latitude/Longitude 2
GCAzimuth($lat1, $lon1, $lat2, $lon2) Using the Great Circle formula, calculate the azimuth between Latitude/Longitude 1 and Latitude/Longitude 2
ApproxDistance($lat1, $lon1, $lat2, $lon2) Using the Ellipsoidal Approximation formula, calculate the distance in kilometers between Latitude/Longitude 1 and Latitude/Longitude 2
EllipsoidDistance($lat1, $lon1, $lat2, $lon2) Using the Ellipsoidal Distance formula, calculate the distance in kilometers between Latitude/Longitude 1 and Latitude/Longitude 2. This formula is the most accurate.

Other Methods:
getKmPerLonAtLat($dLatitude) Get the number of Kilometers per degree longitude at the given latitude.
getLonPerKmAtLat($dLatitude) Get the number of degrees longitude per kilometer at the given latitude.
getKmPerLat() Get the number of kilometers per degree latitude (average of 111.0 kilometers per degree)
getLatPerKm() Get the number of degrees latitude per kilometer (average of 1/111 degrees per kilometer)

Helper Function:
ConvKilometersToMiles($dValue) Convert a distance from kilometers to miles (km / 1.609344 = miles).

Examples

Here are some example uses for this class:
      include_once("GeoCalc.class.php");

      $oGC = new GeoCalc();

      // Great Circle Distance
      $dDist = $oGC->GCDistance(38.9333,-94.3253,38.9314,-94.4876);

      // Great Circle Azimuth
      $dDist =  $oGC->GCAzimuth(38.9333,-94.3253,38.9314,-94.4876);

      // Approximate Ellipsoid Distance
      $dDist = $oGC->ApproxDistance(38.9333,-94.3253,38.9314,-94.4876);

      // Accurate Ellipsoid Distance
      $dDist = $oGC->EllipsoidDistance(38.9333,-94.3253,38.9314,-94.4876);

      // Convert distance from kilometers to miles
      $dDistMiles = ConvKilometersToMiles($dDist);

      // Advanced Calculation:
        // The following will search for ZIP codes
        // within a radius (roughly calculated)

        // Define the center of the search bounds...
        $dLongitude = -94.44590241;
        $dLatitude = 38.7996;

        // Define the maximum search distance
        $dRadius = 100.00;  // in kilometers

        // Calculate the boundary distance in degrees longitude / latitude
        $dAddLat = $oGC->getLatPerKm() * $dRadius;
        $dAddLon = $oGC->getLonPerKmAtLat($dLatitude) * $dRadius;

        // Calculate the boundaries
        $dNorthBounds = $dLatitude + $dAddLat;
        $dSouthBounds = $dLatitude - $dAddLat;
        $dWestBounds = $dLongitude - $dAddLon;
        $dEastBounds = $dLongitude + $dAddLon;

        print "Center Longitude: $dLongitude\n";
        print "Center Latitude: $dLatitude\n";
        print "Radius: $dRadius kilometers\n";

        print "North Bounds: $dNorthBounds\n";
        print "South Bounds: $dSouthBounds\n";
        print "East Bounds: $dEastBounds\n";
        print "West Bounds: $dWestBounds\n";

        // Sample SQL query statement based on above boundaries:
        $strQuery = "SELECT * FROM PostalCodes " .
                    "WHERE Latitude > $dSouthBounds " .
                    "AND Latitude < $dNorthBounds " .
                    "AND Longitude > $dWestBounds " .
                    "AND Longitude < $dEastBounds";


    

For Additional Performance

Using MySQL User Defined Functions (UDF), it is possible to speed up the execution of your distance calculation queries. The performance increase is achieved by relying on a precompiled, native library being linked into a running MySQL server.

Download it Now!

You can download the FREE GeoCalc MySQL UDF here:
Alternatively, these are both available through the UDF Registry.

Instructions

Instructions for compilation and use are included in the distribution files above.