phpcoord - osgb to lat/lng conversion, from http://www.jstott.me.uk/phpcoord/

This commit is contained in:
Jon Atkins 2014-06-06 21:17:00 +01:00
parent 16f1ce1fc6
commit 63633da499
3 changed files with 1039 additions and 0 deletions

View File

@ -0,0 +1,773 @@
<?php
//--------------------------------------------------------------------------
// PHPcoord
// phpcoord.php
//
// (c) 2005 Jonathan Stott
//
// Created on 11-Aug-2005
//
// 2.3 - 24 Aug 2006
// - Changed OSRef->toSixFigureString() so that the eastings and northings
// are rounded rather than floored.
// 2.2 - 11 Feb 2006
// - Used different algorithm for calculating distance between latitudes
// and longitudes - fixes a number of problems with distance calculations
// 2.1 - 22 Dec 2005
// - Added getOSRefFromSixFigureReference function
// 2.0 - 21 Dec 2005
// - Completely different object design - conversion functions now through
// objects rather than static functions
// - Updated comments and documentation
// 1.1 - 11 Sep 2005
// - Added OSGB36/WGS84 data conversions
// 1.0 - 11 Aug 2005
// - Initial version
//--------------------------------------------------------------------------
// ================================================================== LatLng
class LatLng {
var $lat;
var $lng;
/**
* Create a new LatLng object from the given latitude and longitude
*
* @param lat latitude
* @param lng longitude
*/
function LatLng($lat, $lng) {
$this->lat = $lat;
$this->lng = $lng;
}
/**
* Return a string representation of this LatLng object
*
* @return a string representation of this LatLng object
*/
function toString() {
return "(" . $this->lat . ", " . $this->lng . ")";
}
/**
* Calculate the surface distance between this LatLng object and the one
* passed in as a parameter.
*
* @param to a LatLng object to measure the surface distance to
* @return the surface distance
*/
function distance($to) {
$er = 6366.707;
$latFrom = deg2rad($this->lat);
$latTo = deg2rad($to->lat);
$lngFrom = deg2rad($this->lng);
$lngTo = deg2rad($to->lng);
$x1 = $er * cos($lngFrom) * sin($latFrom);
$y1 = $er * sin($lngFrom) * sin($latFrom);
$z1 = $er * cos($latFrom);
$x2 = $er * cos($lngTo) * sin($latTo);
$y2 = $er * sin($lngTo) * sin($latTo);
$z2 = $er * cos($latTo);
$d = acos(sin($latFrom)*sin($latTo) + cos($latFrom)*cos($latTo)*cos($lngTo-$lngFrom)) * $er;
return $d;
}
/**
* Convert this LatLng object from OSGB36 datum to WGS84 datum.
*/
function OSGB36ToWGS84() {
$airy1830 = new RefEll(6377563.396, 6356256.909);
$a = $airy1830->maj;
$b = $airy1830->min;
$eSquared = $airy1830->ecc;
$phi = deg2rad($this->lat);
$lambda = deg2rad($this->lng);
$v = $a / (sqrt(1 - $eSquared * sinSquared($phi)));
$H = 0; // height
$x = ($v + $H) * cos($phi) * cos($lambda);
$y = ($v + $H) * cos($phi) * sin($lambda);
$z = ((1 - $eSquared) * $v + $H) * sin($phi);
$tx = 446.448;
$ty = -124.157;
$tz = 542.060;
$s = -0.0000204894;
$rx = deg2rad( 0.00004172222);
$ry = deg2rad( 0.00006861111);
$rz = deg2rad( 0.00023391666);
$xB = $tx + ($x * (1 + $s)) + (-$rx * $y) + ($ry * $z);
$yB = $ty + ($rz * $x) + ($y * (1 + $s)) + (-$rx * $z);
$zB = $tz + (-$ry * $x) + ($rx * $y) + ($z * (1 + $s));
$wgs84 = new RefEll(6378137.000, 6356752.3141);
$a = $wgs84->maj;
$b = $wgs84->min;
$eSquared = $wgs84->ecc;
$lambdaB = rad2deg(atan($yB / $xB));
$p = sqrt(($xB * $xB) + ($yB * $yB));
$phiN = atan($zB / ($p * (1 - $eSquared)));
for ($i = 1; $i < 10; $i++) {
$v = $a / (sqrt(1 - $eSquared * sinSquared($phiN)));
$phiN1 = atan(($zB + ($eSquared * $v * sin($phiN))) / $p);
$phiN = $phiN1;
}
$phiB = rad2deg($phiN);
$this->lat = $phiB;
$this->lng = $lambdaB;
}
/**
* Convert this LatLng object from WGS84 datum to OSGB36 datum.
*/
function WGS84ToOSGB36() {
$wgs84 = new RefEll(6378137.000, 6356752.3141);
$a = $wgs84->maj;
$b = $wgs84->min;
$eSquared = $wgs84->ecc;
$phi = deg2rad($this->lat);
$lambda = deg2rad($this->lng);
$v = $a / (sqrt(1 - $eSquared * sinSquared($phi)));
$H = 0; // height
$x = ($v + $H) * cos($phi) * cos($lambda);
$y = ($v + $H) * cos($phi) * sin($lambda);
$z = ((1 - $eSquared) * $v + $H) * sin($phi);
$tx = -446.448;
$ty = 124.157;
$tz = -542.060;
$s = 0.0000204894;
$rx = deg2rad(-0.00004172222);
$ry = deg2rad(-0.00006861111);
$rz = deg2rad(-0.00023391666);
$xB = $tx + ($x * (1 + $s)) + (-$rx * $y) + ($ry * $z);
$yB = $ty + ($rz * $x) + ($y * (1 + $s)) + (-$rx * $z);
$zB = $tz + (-$ry * $x) + ($rx * $y) + ($z * (1 + $s));
$airy1830 = new RefEll(6377563.396, 6356256.909);
$a = $airy1830->maj;
$b = $airy1830->min;
$eSquared = $airy1830->ecc;
$lambdaB = rad2deg(atan($yB / $xB));
$p = sqrt(($xB * $xB) + ($yB * $yB));
$phiN = atan($zB / ($p * (1 - $eSquared)));
for ($i = 1; $i < 10; $i++) {
$v = $a / (sqrt(1 - $eSquared * sinSquared($phiN)));
$phiN1 = atan(($zB + ($eSquared * $v * sin($phiN))) / $p);
$phiN = $phiN1;
}
$phiB = rad2deg($phiN);
$this->lat = $phiB;
$this->lng = $lambdaB;
}
/**
* Convert this LatLng object into an OSGB grid reference. Note that this
* function does not take into account the bounds of the OSGB grid -
* beyond the bounds of the OSGB grid, the resulting OSRef object has no
* meaning
*
* @return the converted OSGB grid reference
*/
function toOSRef() {
$airy1830 = new RefEll(6377563.396, 6356256.909);
$OSGB_F0 = 0.9996012717;
$N0 = -100000.0;
$E0 = 400000.0;
$phi0 = deg2rad(49.0);
$lambda0 = deg2rad(-2.0);
$a = $airy1830->maj;
$b = $airy1830->min;
$eSquared = $airy1830->ecc;
$phi = deg2rad($this->lat);
$lambda = deg2rad($this->lng);
$E = 0.0;
$N = 0.0;
$n = ($a - $b) / ($a + $b);
$v = $a * $OSGB_F0 * pow(1.0 - $eSquared * sinSquared($phi), -0.5);
$rho =
$a * $OSGB_F0 * (1.0 - $eSquared) * pow(1.0 - $eSquared * sinSquared($phi), -1.5);
$etaSquared = ($v / $rho) - 1.0;
$M =
($b * $OSGB_F0)
* (((1 + $n + ((5.0 / 4.0) * $n * $n) + ((5.0 / 4.0) * $n * $n * $n))
* ($phi - $phi0))
- (((3 * $n) + (3 * $n * $n) + ((21.0 / 8.0) * $n * $n * $n))
* sin($phi - $phi0)
* cos($phi + $phi0))
+ ((((15.0 / 8.0) * $n * $n) + ((15.0 / 8.0) * $n * $n * $n))
* sin(2.0 * ($phi - $phi0))
* cos(2.0 * ($phi + $phi0)))
- (((35.0 / 24.0) * $n * $n * $n)
* sin(3.0 * ($phi - $phi0))
* cos(3.0 * ($phi + $phi0))));
$I = $M + $N0;
$II = ($v / 2.0) * sin($phi) * cos($phi);
$III =
($v / 24.0)
* sin($phi)
* pow(cos($phi), 3.0)
* (5.0 - tanSquared($phi) + (9.0 * $etaSquared));
$IIIA =
($v / 720.0)
* sin($phi)
* pow(cos($phi), 5.0)
* (61.0 - (58.0 * tanSquared($phi)) + pow(tan($phi), 4.0));
$IV = $v * cos($phi);
$V = ($v / 6.0) * pow(cos($phi), 3.0) * (($v / $rho) - tanSquared($phi));
$VI =
($v / 120.0)
* pow(cos($phi), 5.0)
* (5.0
- (18.0 * tanSquared($phi))
+ (pow(tan($phi), 4.0))
+ (14 * $etaSquared)
- (58 * tanSquared($phi) * $etaSquared));
$N =
$I
+ ($II * pow($lambda - $lambda0, 2.0))
+ ($III * pow($lambda - $lambda0, 4.0))
+ ($IIIA * pow($lambda - $lambda0, 6.0));
$E =
$E0
+ ($IV * ($lambda - $lambda0))
+ ($V * pow($lambda - $lambda0, 3.0))
+ ($VI * pow($lambda - $lambda0, 5.0));
return new OSRef($E, $N);
}
/**
* Convert a latitude and longitude to an UTM reference
*
* @return the converted UTM reference
*/
function toUTMRef() {
$wgs84 = new RefEll(6378137, 6356752.314);
$UTM_F0 = 0.9996;
$a = $wgs84->maj;
$eSquared = $wgs84->ecc;
$longitude = $this->lng;
$latitude = $this->lat;
$latitudeRad = $latitude * (pi() / 180.0);
$longitudeRad = $longitude * (pi() / 180.0);
$longitudeZone = (int) (($longitude + 180.0) / 6.0) + 1;
// Special zone for Norway
if ($latitude >= 56.0
&& $latitude < 64.0
&& $longitude >= 3.0
&& $longitude < 12.0) {
$longitudeZone = 32;
}
// Special zones for Svalbard
if ($latitude >= 72.0 && $latitude < 84.0) {
if ($longitude >= 0.0 && $longitude < 9.0) {
$longitudeZone = 31;
} else if ($longitude >= 9.0 && $longitude < 21.0) {
$longitudeZone = 33;
} else if ($longitude >= 21.0 && $longitude < 33.0) {
$longitudeZone = 35;
} else if ($longitude >= 33.0 && $longitude < 42.0) {
$longitudeZone = 37;
}
}
$longitudeOrigin = ($longitudeZone - 1) * 6 - 180 + 3;
$longitudeOriginRad = $longitudeOrigin * (pi() / 180.0);
$UTMZone = getUTMLatitudeZoneLetter($latitude);
$ePrimeSquared = ($eSquared) / (1 - $eSquared);
$n = $a / sqrt(1 - $eSquared * sin($latitudeRad) * sin($latitudeRad));
$t = tan($latitudeRad) * tan($latitudeRad);
$c = $ePrimeSquared * cos($latitudeRad) * cos($latitudeRad);
$A = cos($latitudeRad) * ($longitudeRad - $longitudeOriginRad);
$M =
$a
* ((1
- $eSquared / 4
- 3 * $eSquared * $eSquared / 64
- 5 * $eSquared * $eSquared * $eSquared / 256)
* $latitudeRad
- (3 * $eSquared / 8
+ 3 * $eSquared * $eSquared / 32
+ 45 * $eSquared * $eSquared * $eSquared / 1024)
* sin(2 * $latitudeRad)
+ (15 * $eSquared * $eSquared / 256
+ 45 * $eSquared * $eSquared * $eSquared / 1024)
* sin(4 * $latitudeRad)
- (35 * $eSquared * $eSquared * $eSquared / 3072)
* sin(6 * $latitudeRad));
$UTMEasting =
(double) ($UTM_F0
* $n
* ($A
+ (1 - $t + $c) * pow($A, 3.0) / 6
+ (5 - 18 * $t + $t * $t + 72 * $c - 58 * $ePrimeSquared)
* pow($A, 5.0)
/ 120)
+ 500000.0);
$UTMNorthing =
(double) ($UTM_F0
* ($M
+ $n
* tan($latitudeRad)
* ($A * $A / 2
+ (5 - $t + (9 * $c) + (4 * $c * $c)) * pow($A, 4.0) / 24
+ (61 - (58 * $t) + ($t * $t) + (600 * $c) - (330 * $ePrimeSquared))
* pow($A, 6.0)
/ 720)));
// Adjust for the southern hemisphere
if ($latitude < 0) {
$UTMNorthing += 10000000.0;
}
return new UTMRef($UTMEasting, $UTMNorthing, $UTMZone, $longitudeZone);
}
}
// =================================================================== OSRef
// References given with OSRef are accurate to 1m.
class OSRef {
var $easting;
var $northing;
/**
* Create a new OSRef object representing an OSGB grid reference. Note
* that the parameters for this constructor require eastings and
* northings with 1m accuracy and need to be absolute with respect to
* the whole of the British Grid. For example, to create an OSRef
* object from the six-figure grid reference TG514131, the easting would
* be 651400 and the northing would be 313100.
*
* Grid references with accuracy greater than 1m can be represented
* using floating point values for the easting and northing. For example,
* a value representing an easting or northing accurate to 1mm would be
* given as 651400.0001.
*
* @param easting the easting of the reference (with 1m accuracy)
* @param northing the northing of the reference (with 1m accuracy)
*/
function OSRef($easting, $northing) {
$this->easting = $easting;
$this->northing = $northing;
}
/**
* Convert this grid reference into a string showing the exact values
* of the easting and northing.
*
* @return
*/
function toString() {
return "(" . $this->easting . ", " . $this->northing . ")";
}
/**
* Convert this grid reference into a string using a standard six-figure
* grid reference including the two-character designation for the 100km
* square. e.g. TG514131.
*
* @return
*/
function toSixFigureString() {
$hundredkmE = floor($this->easting / 100000);
$hundredkmN = floor($this->northing / 100000);
$firstLetter = "";
if ($hundredkmN < 5) {
if ($hundredkmE < 5) {
$firstLetter = "S";
} else {
$firstLetter = "T";
}
} else if ($hundredkmN < 10) {
if ($hundredkmE < 5) {
$firstLetter = "N";
} else {
$firstLetter = "O";
}
} else {
$firstLetter = "H";
}
$secondLetter = "";
$index = 65 + ((4 - ($hundredkmN % 5)) * 5) + ($hundredkmE % 5);
$ti = $index;
if ($index >= 73) $index++;
$secondLetter = chr($index);
$e = round(($this->easting - (100000 * $hundredkmE)) / 100);
$n = round(($this->northing - (100000 * $hundredkmN)) / 100);
return sprintf("%s%s%03d%03d", $firstLetter, $secondLetter, $e, $n);
}
/**
* Convert this grid reference into a latitude and longitude
*
* @return
*/
function toLatLng() {
$airy1830 = new RefEll(6377563.396, 6356256.909);
$OSGB_F0 = 0.9996012717;
$N0 = -100000.0;
$E0 = 400000.0;
$phi0 = deg2rad(49.0);
$lambda0 = deg2rad(-2.0);
$a = $airy1830->maj;
$b = $airy1830->min;
$eSquared = $airy1830->ecc;
$phi = 0.0;
$lambda = 0.0;
$E = $this->easting;
$N = $this->northing;
$n = ($a - $b) / ($a + $b);
$M = 0.0;
$phiPrime = (($N - $N0) / ($a * $OSGB_F0)) + $phi0;
do {
$M =
($b * $OSGB_F0)
* (((1 + $n + ((5.0 / 4.0) * $n * $n) + ((5.0 / 4.0) * $n * $n * $n))
* ($phiPrime - $phi0))
- (((3 * $n) + (3 * $n * $n) + ((21.0 / 8.0) * $n * $n * $n))
* sin($phiPrime - $phi0)
* cos($phiPrime + $phi0))
+ ((((15.0 / 8.0) * $n * $n) + ((15.0 / 8.0) * $n * $n * $n))
* sin(2.0 * ($phiPrime - $phi0))
* cos(2.0 * ($phiPrime + $phi0)))
- (((35.0 / 24.0) * $n * $n * $n)
* sin(3.0 * ($phiPrime - $phi0))
* cos(3.0 * ($phiPrime + $phi0))));
$phiPrime += ($N - $N0 - $M) / ($a * $OSGB_F0);
} while (($N - $N0 - $M) >= 0.001);
$v = $a * $OSGB_F0 * pow(1.0 - $eSquared * sinSquared($phiPrime), -0.5);
$rho =
$a
* $OSGB_F0
* (1.0 - $eSquared)
* pow(1.0 - $eSquared * sinSquared($phiPrime), -1.5);
$etaSquared = ($v / $rho) - 1.0;
$VII = tan($phiPrime) / (2 * $rho * $v);
$VIII =
(tan($phiPrime) / (24.0 * $rho * pow($v, 3.0)))
* (5.0
+ (3.0 * tanSquared($phiPrime))
+ $etaSquared
- (9.0 * tanSquared($phiPrime) * $etaSquared));
$IX =
(tan($phiPrime) / (720.0 * $rho * pow($v, 5.0)))
* (61.0
+ (90.0 * tanSquared($phiPrime))
+ (45.0 * tanSquared($phiPrime) * tanSquared($phiPrime)));
$X = sec($phiPrime) / $v;
$XI =
(sec($phiPrime) / (6.0 * $v * $v * $v))
* (($v / $rho) + (2 * tanSquared($phiPrime)));
$XII =
(sec($phiPrime) / (120.0 * pow($v, 5.0)))
* (5.0
+ (28.0 * tanSquared($phiPrime))
+ (24.0 * tanSquared($phiPrime) * tanSquared($phiPrime)));
$XIIA =
(sec($phiPrime) / (5040.0 * pow($v, 7.0)))
* (61.0
+ (662.0 * tanSquared($phiPrime))
+ (1320.0 * tanSquared($phiPrime) * tanSquared($phiPrime))
+ (720.0
* tanSquared($phiPrime)
* tanSquared($phiPrime)
* tanSquared($phiPrime)));
$phi =
$phiPrime
- ($VII * pow($E - $E0, 2.0))
+ ($VIII * pow($E - $E0, 4.0))
- ($IX * pow($E - $E0, 6.0));
$lambda =
$lambda0
+ ($X * ($E - $E0))
- ($XI * pow($E - $E0, 3.0))
+ ($XII * pow($E - $E0, 5.0))
- ($XIIA * pow($E - $E0, 7.0));
return new LatLng(rad2deg($phi), rad2deg($lambda));
}
}
// ================================================================== UTMRef
class UTMRef {
var $easting;
var $northing;
var $latZone;
var $lngZone;
/**
* Create a new object representing a UTM reference.
*
* @param easting
* @param northing
* @param latZone
* @param lngZone
*/
function UTMRef($easting, $northing, $latZone, $lngZone) {
$this->easting = $easting;
$this->northing = $northing;
$this->latZone = $latZone;
$this->lngZone = $lngZone;
}
/**
* Return a string representation of this UTM reference
*
* @return
*/
function toString() {
return $this->lngZone . $this->latZone . " " .
$this->easting . " " . $this->northing;
}
/**
* Convert this UTM reference to a latitude and longitude
*
* @return the converted latitude and longitude
*/
function toLatLng() {
$wgs84 = new RefEll(6378137, 6356752.314);
$UTM_F0 = 0.9996;
$a = $wgs84->maj;
$eSquared = $wgs84->ecc;
$ePrimeSquared = $eSquared / (1.0 - $eSquared);
$e1 = (1 - sqrt(1 - $eSquared)) / (1 + sqrt(1 - $eSquared));
$x = $this->easting - 500000.0;;
$y = $this->northing;
$zoneNumber = $this->lngZone;
$zoneLetter = $this->latZone;
$longitudeOrigin = ($zoneNumber - 1.0) * 6.0 - 180.0 + 3.0;
// Correct y for southern hemisphere
if ((ord($zoneLetter) - ord("N")) < 0) {
$y -= 10000000.0;
}
$m = $y / $UTM_F0;
$mu =
$m
/ ($a
* (1.0
- $eSquared / 4.0
- 3.0 * $eSquared * $eSquared / 64.0
- 5.0
* pow($eSquared, 3.0)
/ 256.0));
$phi1Rad =
$mu
+ (3.0 * $e1 / 2.0 - 27.0 * pow($e1, 3.0) / 32.0) * sin(2.0 * $mu)
+ (21.0 * $e1 * $e1 / 16.0 - 55.0 * pow($e1, 4.0) / 32.0)
* sin(4.0 * $mu)
+ (151.0 * pow($e1, 3.0) / 96.0) * sin(6.0 * $mu);
$n =
$a
/ sqrt(1.0 - $eSquared * sin($phi1Rad) * sin($phi1Rad));
$t = tan($phi1Rad) * tan($phi1Rad);
$c = $ePrimeSquared * cos($phi1Rad) * cos($phi1Rad);
$r =
$a
* (1.0 - $eSquared)
/ pow(
1.0 - $eSquared * sin($phi1Rad) * sin($phi1Rad),
1.5);
$d = $x / ($n * $UTM_F0);
$latitude = (
$phi1Rad
- ($n * tan($phi1Rad) / $r)
* ($d * $d / 2.0
- (5.0
+ (3.0 * $t)
+ (10.0 * $c)
- (4.0 * $c * $c)
- (9.0 * $ePrimeSquared))
* pow($d, 4.0)
/ 24.0
+ (61.0
+ (90.0 * $t)
+ (298.0 * $c)
+ (45.0 * $t * $t)
- (252.0 * $ePrimeSquared)
- (3.0 * $c * $c))
* pow($d, 6.0)
/ 720.0)) * (180.0 / pi());
$longitude = $longitudeOrigin + (
($d
- (1.0 + 2.0 * $t + $c) * pow($d, 3.0) / 6.0
+ (5.0
- (2.0 * $c)
+ (28.0 * $t)
- (3.0 * $c * $c)
+ (8.0 * $ePrimeSquared)
+ (24.0 * $t * $t))
* pow($d, 5.0)
/ 120.0)
/ cos($phi1Rad)) * (180.0 / pi());
return new LatLng($latitude, $longitude);
}
}
// ================================================================== RefEll
class RefEll {
var $maj;
var $min;
var $ecc;
/**
* Create a new RefEll object to represent a reference ellipsoid
*
* @param maj the major axis
* @param min the minor axis
*/
function RefEll($maj, $min) {
$this->maj = $maj;
$this->min = $min;
$this->ecc = (($maj * $maj) - ($min * $min)) / ($maj * $maj);
}
}
// ================================================== Mathematical Functions
function sinSquared($x) {
return sin($x) * sin($x);
}
function cosSquared($x) {
return cos($x) * cos($x);
}
function tanSquared($x) {
return tan($x) * tan($x);
}
function sec($x) {
return 1.0 / cos($x);
}
/**
* Take a string formatted as a six-figure OS grid reference (e.g.
* "TG514131") and return a reference to an OSRef object that represents
* that grid reference. The first character must be H, N, S, O or T.
* The second character can be any uppercase character from A through Z
* excluding I.
*
* @param ref
* @return
* @since 2.1
*/
function getOSRefFromSixFigureReference($ref) {
$char1 = substr($ref, 0, 1);
$char2 = substr($ref, 1, 1);
$east = substr($ref, 2, 3) * 100;
$north = substr($ref, 5, 3) * 100;
if ($char1 == 'H') {
$north += 1000000;
} else if ($char1 == 'N') {
$north += 500000;
} else if ($char1 == 'O') {
$north += 500000;
$east += 500000;
} else if ($char1 == 'T') {
$east += 500000;
}
$char2ord = ord($char2);
if ($char2ord > 73) $char2ord--; // Adjust for no I
$nx = (($char2ord - 65) % 5) * 100000;
$ny = (4 - floor(($char2ord - 65) / 5)) * 100000;
return new OSRef($east + $nx, $north + $ny);
}
/**
* Work out the UTM latitude zone from the latitude
*
* @param latitude
* @return
*/
function getUTMLatitudeZoneLetter($latitude) {
if ((84 >= $latitude) && ($latitude >= 72)) return "X";
else if (( 72 > $latitude) && ($latitude >= 64)) return "W";
else if (( 64 > $latitude) && ($latitude >= 56)) return "V";
else if (( 56 > $latitude) && ($latitude >= 48)) return "U";
else if (( 48 > $latitude) && ($latitude >= 40)) return "T";
else if (( 40 > $latitude) && ($latitude >= 32)) return "S";
else if (( 32 > $latitude) && ($latitude >= 24)) return "R";
else if (( 24 > $latitude) && ($latitude >= 16)) return "Q";
else if (( 16 > $latitude) && ($latitude >= 8)) return "P";
else if (( 8 > $latitude) && ($latitude >= 0)) return "N";
else if (( 0 > $latitude) && ($latitude >= -8)) return "M";
else if (( -8 > $latitude) && ($latitude >= -16)) return "L";
else if ((-16 > $latitude) && ($latitude >= -24)) return "K";
else if ((-24 > $latitude) && ($latitude >= -32)) return "J";
else if ((-32 > $latitude) && ($latitude >= -40)) return "H";
else if ((-40 > $latitude) && ($latitude >= -48)) return "G";
else if ((-48 > $latitude) && ($latitude >= -56)) return "F";
else if ((-56 > $latitude) && ($latitude >= -64)) return "E";
else if ((-64 > $latitude) && ($latitude >= -72)) return "D";
else if ((-72 > $latitude) && ($latitude >= -80)) return "C";
else return 'Z';
}
?>

View File

@ -0,0 +1,60 @@
--------------------------------------------------------------------------
PHPcoord
readme.txt
(c) 2005 Jonathan Stott
Created on 11-Aug-2005
2.3 - 24 Aug 2006
- Changed OSRef->toSixFigureString() so that the eastings and northings
are rounded rather than floored.
2.2 - 11 Feb 2006
- Used different algorithm for calculating distance between latitudes
and longitudes - fixes a number of problems with distance calculations
2.1 - 22 Dec 2005
- Added getOSRefFromSixFigureReference function
2.0 - 21 Dec 2005
- Completely different object design - conversion functions now through
objects rather than static functions
- Updated comments and documentation
1.1 - 11 Sep 2005
- Added WGS84/OSGB36 conversions
1.0 - 11 Aug 2005
- Initial version
--------------------------------------------------------------------------
PHPcoord is a PHP script that provides functions for handling various
co-ordinate systems and converting between them. Currently, OSGB (Ordnance
Survey of Great Britain) grid references, UTM (Universal Transverse
Mercator) references and latitude/longitude are supported. A function is
also provided to find the surface distance between two points of latitude
and longitude.
When using the OSGB conversions, the majority of applications use the
WGS84 datum rather than the OSGB36 datum. Conversions between the two
data were added in v1.1 - the conversions should be accurate to within
5m or so. If accuracy is not important (i.e. to within 200m or so),
then it isn't necessary to perform the conversions.
Examples of how to use the functions provided in phpcoord.php can be
found in the test.php script.
See http://www.jstott.me.uk/phpcoord/ for latest releases and information.
DISCLAIMER
Accuracy of the co-ordinate conversions contained within the PHPcoord
package is not guaranteed. Use of the conversions is entirely at your
own risk and I cannot be held responsible for any consequences of
errors created by the conversions. I do not recommend using the package
for mission-critical applications.
LICENSING
This software product is available under the GNU General Public License
(GPL). Terms of the GPL can be read at http://www.jstott.me.uk/gpl/.
Any commercial use requires the purchase of a license - contact me at
phpcoord@jstott.me.uk for details.

View File

@ -0,0 +1,206 @@
<?php
//--------------------------------------------------------------------------
// PHPcoord
// text.php
//
// (c) 2005 Jonathan Stott
//
// Created on 11-Aug-2005
//
// 2.3 - 24 Aug 2006
// - Changed OSRef->toSixFigureString() so that the eastings and northings
// are rounded rather than floored.
// 2.2 - 11 Feb 2006
// - Used different algorithm for calculating distance between latitudes
// and longitudes - fixes a number of problems with distance calculations
// 2.1 - 22 Dec 2005
// - Added getOSRefFromSixFigureReference function
// 2.0 - 21 Dec 2005
// - Completely different object design - conversion functions now through
// objects rather than static functions
// - Updated comments and documentation
// 1.1 - 11 Sep 2005
// - Added OSGB36/WGS84 data conversions
// 1.0 - 11 Aug 2005
// - Initial version
//--------------------------------------------------------------------------
require_once("phpcoord-2.3.php");
?>
<html>
<head>
<title>phpcoord Test Script</title>
</head>
<body>
<h1>phpcoord Test Script</h1>
<h2>Calculate Surface Distance between two Latitudes/Longitudes</h2>
<p>
The LatLngDistance function takes two latitudes/longitudes and calculates
the surface distance between the two in kilometres:
</p>
<p>
<pre>$lld1 = new LatLng(40.718119, -73.995667); // New York
echo "New York Lat/Long: " . $lld1->toString() . "&lt;br /&gt;";
$lld2 = new LatLng(51.499981, -0.125313); // London
$d = $lld1->distance($lld2);
echo "Surface Distance between New York and London: " . $d . "km";</pre>
<?php
$lld1 = new LatLng(40.718119, -73.995667); // New York
echo "New York Lat/Long: " . $lld1->toString() . "<br />";
$lld2 = new LatLng(51.499981, -0.125313); // London
echo "London Lat/Long: " . $lld2->toString() . "<br />";
$d = $lld1->distance($lld2);
echo "Surface Distance between New York and London: " . $d . "km";
?>
</p>
<h2>Convert OS Grid Reference to Latitude/Longitude</h2>
<p>
Note that the OSGB-Latitude/Longitude conversions use the OSGB36 datum by default. The
majority of applications use the WGS84 datum, for which the appropriate conversions
need to be added. See the examples below to see the difference between the two data.
</p>
<p>
Using OSGB36 (convert an OSGB grid reference to a latitude and longitude using the OSGB36 datum):
<pre>$os1 = new OSRef(651409.903, 313177.270);
echo "OS Grid Reference: " . $os1->toString() . " - " . $os1->toSixFigureString() . "&lt;br /&gt;";
$ll1 = $os1->toLatLng();
echo "Converted to Lat/Long: " . $ll1->toString();</pre>
<?php
$os1 = new OSRef(651409.903, 313177.270);
echo "OS Grid Reference: " . $os1->toString() . " - " . $os1->toSixFigureString() . "<br />";
$ll1 = $os1->toLatLng();
echo "Converted to Lat/Long: " . $ll1->toString();
?>
</p>
<p>
Using WGS84 (convert an OSGB grid reference to a latitude and longitude using the WGS84 datum):
<pre>$os1w = new OSRef(651409.903, 313177.270);
echo "OS Grid Reference: " . $os1w->toString() . " - " . $os1w->toSixFigureString() . "&lt;br /&gt;";
$l1w = $os1w->toLatLng();
$l1w->OSGB36ToWGS84();
echo "Converted to Lat/Long: " . $ll1w->toString();</pre>
<?php
$os1w = new OSRef(651409.903, 313177.270);
echo "OS Grid Reference: " . $os1w->toString() . " - " . $os1w->toSixFigureString() . "<br />";
$ll1w = $os1w->toLatLng();
$ll1w->OSGB36ToWGS84();
echo "Converted to Lat/Long: " . $ll1w->toString();
?>
</p>
<h2>Convert Latitude/Longitude to OS Grid Reference</h2>
<p>
Note that the OSGB-Latitude/Longitude conversions use the OSGB36 datum by default. The
majority of applications use the WGS84 datum, for which the appropriate conversions
need to be added. See the examples below to see the difference between the two data.
</p>
<p>
Using OSGB36 (convert a latitude and longitude using the OSGB36 datum to an OSGB grid reference):
<pre>$ll2 = new LatLng(52.657570301933, 1.7179215806451);
echo "Latitude/Longitude: " . $ll2->toString() . "&lt;br /&gt;";
$os2 = $ll2->toOSRef();
echo "Converted to OS Grid Ref: " . $os2->toString() . " - " . $os2->toSixFigureString();</pre>
<?php
$ll2 = new LatLng(52.657570301933, 1.7179215806451);
echo "Latitude/Longitude: " . $ll2->toString() . "<br />";
$os2 = $ll2->toOSRef();
echo "Converted to OS Grid Ref: " . $os2->toString() . " - " . $os2->toSixFigureString();
?>
</p>
<p>
Using WGS84 (convert a latitude and longitude using the WGS84 datum to an OSGB grid reference):
<pre>$ll2w = new LatLng(52.657570301933, 1.7179215806451);
echo "Latitude/Longitude: " . $ll2->toString() . "&lt;br /&gt;";
$ll2w->WGS84ToOSGB36();
$os2w = $ll2w->toOSRef();
echo "Converted to OS Grid Ref: " . $os2w->toString() . " - " . $os2w->toSixFigureString();</pre>
<?php
$ll2w = new LatLng(52.657570301933, 1.7179215806451);
echo "Latitude/Longitude: " . $ll2->toString() . "<br />";
$ll2w->WGS84ToOSGB36();
$os2w = $ll2w->toOSRef();
echo "Converted to OS Grid Ref: " . $os2w->toString() . " - " . $os2w->toSixFigureString();
?>
</p>
<h2>Convert Six-Figure OS Grid Reference String to an OSRef Object</h2>
<p>
To convert a string representing a six-figure OSGB grid reference:
<pre>$os6 = "TG514131";
echo "Six figure string: " . $os6 . "&lt;br /&gt;";
$os6x = getOSRefFromSixFigureReference($os6);
echo "Converted to OS Grid Ref: " . $os6x->toString() . " - " . $os6x->toSixFigureString();</pre>
<?php
$os6 = "TG514131";
echo "Six figure string: " . $os6 . "<br />";
$os6x = getOSRefFromSixFigureReference($os6);
echo "Converted to OS Grid Ref: " . $os6x->toString() . " - " . $os6x->toSixFigureString();
?>
</p>
<h2>Convert UTM Reference to Latitude/Longitude</h2>
<p>
<pre>$utm1 = new UTMRef(456463.99, 3335334.05, "E", 12);
echo "UTM Reference: " . $utm1->toString() . "&lt;br /&gt;";
$ll3 = $utm1->toLatLng();
echo "Converted to Lat/Long: " . $ll3->toString();</pre>
<?php
$utm1 = new UTMRef(456463.99, 3335334.05, "E", 12);
echo "UTM Reference: " . $utm1->toString() . "<br />";
$ll3 = $utm1->toLatLng();
echo "Converted to Lat/Long: " . $ll3->toString();
?>
</p>
<h2>Convert Latitude/Longitude to UTM Reference</h2>
<p>
<pre>$ll4 = new LatLng(-60.1167, -111.7833);
echo "Latitude/Longitude: " . $ll4->toString() . "&lt;br /&gt;";
$utm2 = $ll4->toUTMRef();
echo "Converted to UTM Ref: " . $utm2->toString() ;</pre>
<?php
$ll4 = new LatLng(-60.1167, -111.7833);
echo "Latitude/Longitude: " . $ll4->toString() . "<br />";
$utm2 = $ll4->toUTMRef();
echo "Converted to UTM Ref: " . $utm2->toString() ;
?>
</p>
<p>
(c) 2005, Jonathan Stott
</p>
</body>
</html>