summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorlsces <lester@lsces.co.uk>2025-08-24 15:35:09 +0100
committerlsces <lester@lsces.co.uk>2025-08-24 15:35:09 +0100
commitce4fa87baac56fe2478cfea56b539cba63887467 (patch)
tree6d5f6a74d4d80fcc11b12ce2fa86715e1bff9b88 /lib
parent69b08377a8a2d3791b21d96720657d93beda2af0 (diff)
downloadcontact-ce4fa87baac56fe2478cfea56b539cba63887467.tar.gz
contact-ce4fa87baac56fe2478cfea56b539cba63887467.tar.bz2
contact-ce4fa87baac56fe2478cfea56b539cba63887467.zip
Just a crude merging of the PHP7 code base with the PHP8.4 version
Diffstat (limited to 'lib')
-rwxr-xr-xlib/phpcoord-2.3.php1335
-rwxr-xr-xlib/test-2.3.php197
2 files changed, 867 insertions, 665 deletions
diff --git a/lib/phpcoord-2.3.php b/lib/phpcoord-2.3.php
index 494d62d..ae5b4d6 100755
--- a/lib/phpcoord-2.3.php
+++ b/lib/phpcoord-2.3.php
@@ -1,7 +1,13 @@
<?php
- //-------------------------------------------------------------------------- // PHPcoord
- // phpcoord.php // // (c) 2005 Jonathan Stott // // Created on 11-Aug-2005 //
+ //--------------------------------------------------------------------------
+ // 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.
@@ -13,749 +19,748 @@
// 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
+ // - Updated comments and documentation
+ // 1.1 - 11 Sep 2005
// - Added OSGB36/WGS84 data conversions
- // 1.0 - 11 Aug 2005 // - Initial version //--------------------------------------------------------------------------
+ // 1.0 - 11 Aug 2005
+ // - Initial version
+ //--------------------------------------------------------------------------
// ================================================================== LatLng
- class LatLng {
+class LatLng {
- var $lat;
- var $lng;
+ public $lat;
+ public $lng;
- /**
- * Create a new LatLng object from the given latitude and longitude
- *
- * @param lat latitude
- * @param lng longitude
- */
- function __construct($lat, $lng) {
- $this->lat = $lat;
- $this->lng = $lng;
- }
+ /**
+ * Create a new LatLng object from the given latitude and longitude
+ *
+ * @param float|integer lat latitude
+ * @param float|integer lng longitude
+ */
+ public function __construct($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;
+ /**
+ * Return a string representation of this LatLng object
+ *
+ * @return string representation of this LatLng object
+ */
+ public function toString() {
+ return "({$this->lat}, {$this->lng})";
+ }
- $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);
+ /**
+ * Calculate the surface distance between this LatLng object and the one
+ * passed in as a parameter.
+ *
+ * @param array $to a LatLng object to measure the surface distance to
+ * @return float|integer the surface distance
+ */
+ public function distance($to) {
+ $er = 6366.707;
- $x2 = $er * cos($lngTo) * sin($latTo);
- $y2 = $er * sin($lngTo) * sin($latTo);
- $z2 = $er * cos($latTo);
+ $latFrom = deg2rad($this->lat);
+ $latTo = deg2rad($to['lat']);
+ $lngFrom = deg2rad($this->lng);
+ $lngTo = deg2rad($to['lng']);
- $d = acos(sin($latFrom)*sin($latTo) + cos($latFrom)*cos($latTo)*cos($lngTo-$lngFrom)) * $er;
-
- return $d;
- }
+ $x1 = $er * cos($lngFrom) * sin($latFrom);
+ $y1 = $er * sin($lngFrom) * sin($latFrom);
+ $z1 = $er * cos($latFrom);
-
- /**
- * 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);
+ $x2 = $er * cos($lngTo) * sin($latTo);
+ $y2 = $er * sin($lngTo) * sin($latTo);
+ $z2 = $er * cos($latTo);
- $tx = 446.448;
- $ty = -124.157;
- $tz = 542.060;
- $s = -0.0000204894;
- $rx = deg2rad( 0.00004172222);
- $ry = deg2rad( 0.00006861111);
- $rz = deg2rad( 0.00023391666);
+ $d = acos(sin($latFrom)*sin($latTo) + cos($latFrom)*cos($latTo)*cos($lngTo-$lngFrom)) * $er;
+
+ return $d;
+ }
- $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;
+ /**
+ * Convert this LatLng object from OSGB36 datum to WGS84 datum.
+ */
+ public 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);
- $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;
- }
+ $tx = 446.448;
+ $ty = -124.157;
+ $tz = 542.060;
+ $s = -0.0000204894;
+ $rx = deg2rad( 0.00004172222);
+ $ry = deg2rad( 0.00006861111);
+ $rz = deg2rad( 0.00023391666);
- $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);
+ $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 );
- $tx = -446.448;
- $ty = 124.157;
- $tz = -542.060;
- $s = 0.0000204894;
- $rx = deg2rad(-0.00004172222);
- $ry = deg2rad(-0.00006861111);
- $rz = deg2rad(-0.00023391666);
+ $wgs84 = new RefEll(6378137.000, 6356752.3141);
+ $a = $wgs84->maj;
+ $b = $wgs84->min;
+ $eSquared = $wgs84->ecc;
- $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));
+ $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;
+ }
- $airy1830 = new RefEll(6377563.396, 6356256.909);
- $a = $airy1830->maj;
- $b = $airy1830->min;
- $eSquared = $airy1830->ecc;
+ $phiB = rad2deg($phiN);
+
+ $this->lat = $phiB;
+ $this->lng = $lambdaB;
+ }
- $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));
+ /**
+ * 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);
- 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;
+ $tx = -446.448;
+ $ty = 124.157;
+ $tz = -542.060;
+ $s = 0.0000204894;
+ $rx = deg2rad(-0.00004172222);
+ $ry = deg2rad(-0.00006861111);
+ $rz = deg2rad(-0.00023391666);
- $latitudeRad = $latitude * (pi() / 180.0);
- $longitudeRad = $longitude * (pi() / 180.0);
- $longitudeZone = (int) (($longitude + 180.0) / 6.0) + 1;
+ $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 );
- // Special zone for Norway
- if ($latitude >= 56.0
- && $latitude < 64.0
- && $longitude >= 3.0
- && $longitude < 12.0) {
- $longitudeZone = 32;
- }
+ $airy1830 = new RefEll(6377563.396, 6356256.909);
+ $a = $airy1830->maj;
+ $b = $airy1830->min;
+ $eSquared = $airy1830->ecc;
- // 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;
- }
- }
+ $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;
+ }
- $longitudeOrigin = ($longitudeZone - 1) * 6 - 180 + 3;
- $longitudeOriginRad = $longitudeOrigin * (pi() / 180.0);
+ $phiB = rad2deg($phiN);
+
+ $this->lat = $phiB;
+ $this->lng = $lambdaB;
+ }
- $UTMZone = getUTMLatitudeZoneLetter($latitude);
+ /**
+ * 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 string the converted OSGB grid reference
+ */
+ public 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);
- $ePrimeSquared = ($eSquared) / (1 - $eSquared);
+ $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 );
- $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);
+ $osref = new OSRef($E, $N);
+ return $osref->toString();
+ }
- $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);
+ /**
+ * Convert a latitude and longitude to an UTM reference
+ *
+ * @return string the converted UTM reference
+ */
+ public function toUTMRef() {
+ $wgs84 = new RefEll(6378137, 6356752.314);
+ $UTM_F0 = 0.9996;
+ $a = $wgs84->maj;
+ $eSquared = $wgs84->ecc;
+ $longitude = $this->lng;
+ $latitude = $this->lat;
- $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)));
+ $latitudeRad = $latitude * (pi() / 180.0);
+ $longitudeRad = $longitude * (pi() / 180.0);
+ $longitudeZone = (int) (($longitude + 180.0) / 6.0) + 1;
- // Adjust for the southern hemisphere if ($latitude < 0) {
- $UTMNorthing += 10000000.0;
- }
+ // Special zone for Norway
+ if ($latitude >= 56.0
+ && $latitude < 64.0
+ && $longitude >= 3.0
+ && $longitude < 12.0) {
+ $longitudeZone = 32;
+ }
- return new UTMRef($UTMEasting, $UTMNorthing, $UTMZone, $longitudeZone);
- }
- }
+ // 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);
- // =================================================================== OSRef
+ $UTMZone = getUTMLatitudeZoneLetter($latitude);
- // References given with OSRef are accurate to 1m.
- class OSRef {
+ $ePrimeSquared = $eSquared / (1 - $eSquared);
- var $easting;
- var $northing;
+ $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));
- /**
- * 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 __construct($easting, $northing) {
- $this->easting = $easting;
- $this->northing = $northing;
- }
+ $UTMEasting =
+ (float) ($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 =
+ (float) ($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)));
- /**
- * Convert this grid reference into a string showing the exact values
- * of the easting and northing.
- *
- * @return
- */
- function toString() {
- return "(" . $this->easting . ", " . $this->northing . ")";
- }
+ // Adjust for the southern hemisphere
+ if ($latitude < 0) {
+ $UTMNorthing += 10000000.0;
+ }
+ $utmref = new UTMRef($UTMEasting, $UTMNorthing, $UTMZone, $longitudeZone);
+ return $utmref->toString();
+ }
+}
- /**
- * 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);
+// =================================================================== OSRef
- $e = round(($this->easting - (100000 * $hundredkmE)) / 100);
- $n = round(($this->northing - (100000 * $hundredkmN)) / 100);
+// References given with OSRef are accurate to 1m.
+class OSRef {
- return sprintf("%s%s%03d%03d", $firstLetter, $secondLetter, $e, $n);
- }
+ public $easting;
+ public $northing;
- /**
- * Convert this grid reference into a latitude and longitude
- *
- * @return
- */
- function toLatLng() {
- $airy1830 = new RefEll(6377563.396, 6356256.909);
- $OSGB_F0 = 0.9996012717;
- $N0 = -100050.0;
- $E0 = 400110.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));
- }
- }
+ /**
+ * 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 float|integer easting the easting of the reference (with 1m accuracy)
+ * @param float|integer northing the northing of the reference (with 1m accuracy)
+ */
+ public function __construct($easting, $northing) {
+ $this->easting = $easting;
+ $this->northing = $northing;
+ }
- // ================================================================== UTMRef
+ /**
+ * Convert this grid reference into a string showing the exact values
+ * of the easting and northing.
+ *
+ * @return
+ */
+ public function toString() {
+ return "({$this->easting}, {$this->northing})";
+ }
- class UTMRef {
- var $easting;
- var $northing;
- var $latZone;
- var $lngZone;
+ /**
+ * 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
+ */
+ public function toSixFigureString() {
+ $hundredkmE = floor($this->easting / 100000);
+ $hundredkmN = floor($this->northing / 100000);
+ $firstLetter = "";
+ $firstLetter = $hundredkmN < 5
+ ? ( $hundredkmE < 5 ? "S" : "T" )
+ : ( $hundredkmN < 10 ? ( $hundredkmE < 5 ? "N" : "O" ) : "H" );
+ $secondLetter = "";
+ $index = 65 + ( 4 - ( $hundredkmN % 5 ) ) * 5 + ($hundredkmE % 5);
+ $ti = $index;
+ if ($index >= 73) $index++;
+ $secondLetter = chr($index);
- /**
- * Create a new object representing a UTM reference.
- *
- * @param easting
- * @param northing
- * @param latZone
- * @param lngZone
- */
- function __construct($easting, $northing, $latZone, $lngZone) {
- $this->easting = $easting;
- $this->northing = $northing;
- $this->latZone = $latZone;
- $this->lngZone = $lngZone;
- }
+ $e = round(($this->easting - 100000 * $hundredkmE) / 100);
+ $n = round(($this->northing - 100000 * $hundredkmN) / 100);
+ return sprintf("%s%s%03d%03d", $firstLetter, $secondLetter, $e, $n);
+ }
- /**
- * 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;
+ /**
+ * Convert this grid reference into a latitude and longitude
+ *
+ * @return
+ */
+ public function toLatLng() {
+ $airy1830 = new RefEll(6377563.396, 6356256.909);
+ $OSGB_F0 = 0.9996012717;
+ $N0 = -100050.0;
+ $E0 = 400110.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 );
- // Correct y for southern hemisphere if ((ord($zoneLetter) - ord("N")) < 0) {
- $y -= 10000000.0;
- }
+ return new LatLng(rad2deg($phi), rad2deg($lambda));
+ }
+}
- $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);
+// ================================================================== UTMRef
- $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);
+class UTMRef {
- $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());
+ public $easting;
+ public $northing;
+ public $latZone;
+ public $lngZone;
- $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);
- }
- }
+ /**
+ * Create a new object representing a UTM reference.
+ *
+ * @param float|integer easting
+ * @param float|integer northing
+ * @param float|integer latZone
+ * @param float|integer lngZone
+ */
+ public function __construct($easting, $northing, $latZone, $lngZone) {
+ $this->easting = $easting;
+ $this->northing = $northing;
+ $this->latZone = $latZone;
+ $this->lngZone = $lngZone;
+ }
- // ================================================================== RefEll
+ /**
+ * Return a string representation of this UTM reference
+ *
+ * @return string
+ */
+ public function toString() {
+ return "{$this->lngZone}{$this->latZone} {$this->easting} {$this->northing}";
+ }
- class RefEll {
- var $maj;
- var $min;
- var $ecc;
+ /**
+ * Convert this UTM reference to a latitude and longitude
+ *
+ * @return string the converted latitude and longitude
+ */
+ public 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;
- /**
- * Create a new RefEll object to represent a reference ellipsoid
- *
- * @param maj the major axis
- * @param min the minor axis
- */
- function __construct($maj, $min) {
- $this->maj = $maj;
- $this->min = $min;
- $this->ecc = (($maj * $maj) - ($min * $min)) / ($maj * $maj);
- }
- }
+ // 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());
+
+ $latlog = new LatLng($latitude, $longitude);
+ return $latlog->toString();
+ }
+}
+
+
+// ================================================================== RefEll
+
+ class RefEll {
+
+ public $maj;
+ public $min;
+ public $ecc;
+
+
+ /**
+ * Create a new RefEll object to represent a reference ellipsoid
+ *
+ * @param float|integer maj the major axis
+ * @param float|integer min the minor axis
+ */
+ public function __construct($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 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);
+}
- function cosSquared($x) {
- return cos($x) * cos($x);
- }
- function tanSquared($x) {
- return tan($x) * tan($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 string $ref
+* @return string
+* @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;
+ switch ($char1) {
+ case 'H':
+ $north += 1000000;
+ break;
+ case 'N':
+ $north += 500000;
+ break;
+ case 'O':
+ $north += 500000;
+ $east += 500000;
+ break;
+ case 'T':
+ $east += 500000;
+ break;
+ }
+ $char2ord = ord($char2);
+ if ($char2ord > 73) $char2ord--; // Adjust for no I
+ $nx = (($char2ord - 65) % 5) * 100000;
+ $ny = (4 - floor(($char2ord - 65) / 5)) * 100000;
+ $osref = new OSRef($east + $nx, $north + $ny);
+ return $osref->toString();
+}
- 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';
- }
-?> \ No newline at end of file
+/**
+* Work out the UTM latitude zone from the latitude
+*
+* @param float|integer 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';
+}
diff --git a/lib/test-2.3.php b/lib/test-2.3.php
new file mode 100755
index 0000000..c9edc8b
--- /dev/null
+++ b/lib/test-2.3.php
@@ -0,0 +1,197 @@
+<?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> \ No newline at end of file