/** * Convert a latitude and longitude to easting and northing using a Transverse Mercator projection * Formula for transformation is taken from OS document * "A Guide to Coordinate Systems in Great Britain" * * @param float $scale scale factor on central meridian * @param float $originEasting easting of true origin * @param float $originNorthing northing of true origin * @param float $originLat latitude of true origin * @param float $originLong longitude of true origin * @return array */ public function toTransverseMercatorEastingNorthing($scale, $originEasting, $originNorthing, $originLat, $originLong) { $originLat = deg2rad($originLat); $originLong = deg2rad($originLong); $lat = deg2rad($this->lat); $sinLat = sin($lat); $cosLat = cos($lat); $tanLat = tan($lat); $tanLatSq = pow($tanLat, 2); $long = deg2rad($this->lng); $n = ($this->refEll->getMaj() - $this->refEll->getMin()) / ($this->refEll->getMaj() + $this->refEll->getMin()); $nSq = pow($n, 2); $nCu = pow($n, 3); $v = $this->refEll->getMaj() * $scale * pow(1 - $this->refEll->getEcc() * pow($sinLat, 2), -0.5); $p = $this->refEll->getMaj() * $scale * (1 - $this->refEll->getEcc()) * pow(1 - $this->refEll->getEcc() * pow($sinLat, 2), -1.5); $hSq = $v / $p - 1; $latPlusOrigin = $lat + $originLat; $latMinusOrigin = $lat - $originLat; $longMinusOrigin = $long - $originLong; $M = $this->refEll->getMin() * $scale * ((1 + $n + 1.25 * ($nSq + $nCu)) * $latMinusOrigin - (3 * ($n + $nSq) + 2.625 * $nCu) * sin($latMinusOrigin) * cos($latPlusOrigin) + 1.875 * ($nSq + $nCu) * sin(2 * $latMinusOrigin) * cos(2 * $latPlusOrigin) - 35 / 24 * $nCu * sin(3 * $latMinusOrigin) * cos(3 * $latPlusOrigin)); $I = $M + $originNorthing; $II = $v / 2 * $sinLat * $cosLat; $III = $v / 24 * $sinLat * pow($cosLat, 3) * (5 - $tanLatSq + 9 * $hSq); $IIIA = $v / 720 * $sinLat * pow($cosLat, 5) * (61 - 58 * $tanLatSq + pow($tanLatSq, 2)); $IV = $v * $cosLat; $V = $v / 6 * pow($cosLat, 3) * ($v / $p - $tanLatSq); $VI = $v / 120 * pow($cosLat, 5) * (5 - 18 * $tanLatSq + pow($tanLatSq, 2) + 14 * $hSq - 58 * $tanLatSq * $hSq); $E = $originEasting + $IV * $longMinusOrigin + $V * pow($longMinusOrigin, 3) + $VI * pow($longMinusOrigin, 5); $N = $I + $II * pow($longMinusOrigin, 2) + $III * pow($longMinusOrigin, 4) + $IIIA * pow($longMinusOrigin, 6); return array('E' => $E, 'N' => $N); }
/** * Convert these coordinates into a latitude, longitude * Formula for transformation is taken from OS document * "A Guide to Coordinate Systems in Great Britain" * * @return LatLng */ public function toLatitudeLongitude() { $lambda = rad2deg(atan2($this->y, $this->x)); $p = sqrt(pow($this->x, 2) + pow($this->y, 2)); $phi = atan($this->z / ($p * (1 - $this->refEll->getEcc()))); do { $phi1 = $phi; $v = $this->refEll->getMaj() / sqrt(1 - $this->refEll->getEcc() * pow(sin($phi), 2)); $phi = atan(($this->z + $this->refEll->getEcc() * $v * sin($phi)) / $p); } while (abs($phi - $phi1) >= 1.0E-5); $h = $p / cos($phi) - $v; $phi = rad2deg($phi); return new LatLng($phi, $lambda, $h, $this->refEll); }
public function testHelmertOSWorkedExample() { $tx = -446.448; $ty = 125.157; $tz = -542.0599999999999; $s = 2.04894E-5; $rx = -0.1502; $ry = -0.247; $rz = -0.8421; $c = new Cartesian(3909833.018, -147097.138, 5020322.478, RefEll::wgs84()); $c->transformDatum(RefEll::airy1830(), $tx, $ty, $tz, $s, $rx, $ry, $rz); self::assertEquals(3909460.068, round($c->getX(), 3)); self::assertEquals(-146987.302, round($c->getY(), 3)); self::assertEquals(5019888.07, round($c->getZ(), 3)); }
public function getReferenceEllipsoid() { return RefEll::WGS84(); }
/** * @param int $x * @param int $y * @param int $z */ public function __construct($x, $y, $z = 0) { parent::__construct($x, $y, $z, RefEll::airyModified()); }
public function testNoopTransformNewYork() { $LatLng = new LatLng(40.7127, -74.0059, RefEll::GRS80()); $LatLngTrans = clone $LatLng; $LatLngTrans->transformDatum(RefEll::GRS80(), RefEll::GRS80(), 0, 0, 0, 0, 0, 0, 0); $this->assertEquals($LatLng->lat, $LatLngTrans->lat, 'Latitude transform failed'); $this->assertEquals($LatLng->lng, $LatLngTrans->lng, 'Longitude transform failed'); }
/** * @param int $x * @param int $y * @param int $z */ public function __construct($x, $y, $z = 0) { parent::__construct($x, $y, $z, RefEll::grs80()); }
/** * Convert a WGS84 latitude and longitude to an UTM reference * * Reference values for transformation are taken from OS document * "A Guide to Coordinate Systems in Great Britain" * @return UTMRef */ public function toUTMRef() { if ($this->refEll != RefEll::WGS84()) { trigger_error('Current co-ordinates are in a non-WGS84 datum', E_USER_WARNING); } $longitudeZone = (int) (($this->lng + 180) / 6) + 1; // Special zone for Norway if ($this->lat >= 56 && $this->lat < 64 && $this->lng >= 3 && $this->lng < 12) { $longitudeZone = 32; } // Special zones for Svalbard if ($this->lat >= 72 && $this->lat < 84) { if ($this->lng >= 0 && $this->lng < 9) { $longitudeZone = 31; } else { if ($this->lng >= 9 && $this->lng < 21) { $longitudeZone = 33; } else { if ($this->lng >= 21 && $this->lng < 33) { $longitudeZone = 35; } else { if ($this->lng >= 33 && $this->lng < 42) { $longitudeZone = 37; } } } } } $UTMZone = $this->getUTMLatitudeZoneLetter($this->lat); $UTM = new UTMRef(0, 0, $UTMZone, $longitudeZone); //dummy to get reference data $scale = $UTM->getScaleFactor(); $N0 = $UTM->getOriginNorthing(); $E0 = $UTM->getOriginEasting(); $phi0 = $UTM->getOriginLatitude(); $lambda0 = $UTM->getOriginLongitude(); $coords = $this->toTransverseMercatorEastingNorthing($scale, $E0, $N0, $phi0, $lambda0); if ($this->lat < 0) { $coords['N'] += 10000000; } return new UTMRef($coords['E'], $coords['N'], $UTMZone, $longitudeZone); }
public function getReferenceEllipsoid() { return RefEll::Airy1830(); }
/** * Create a new object representing a OSGB reference. * * @param int $x * @param int $y * @param int $z */ public function __construct($x, $y, $z = 0) { parent::__construct($x, $y, $z, RefEll::airy1830()); }