Exemplo n.º 1
0
 /**
  * Instantiate a Utm onject from Lat/Long coordinates or a LatLong object.
  * Returns a new Utm object.
  */
 public static function fromLatLong($latitude, $longitude = null)
 {
     // Accept various inputs.
     if (!isset($longitude)) {
         // One parameter only supplied. If this is not already a LatLong object,
         // then convert it into one.
         if (!is_a($latitude, 'Academe\\Proj4Php\\Mgrs\\LatLongInterface')) {
             // If some form of array, then let LatLong work out how to interpret it.
             $latitude = new LatLong($latitude);
         }
         $lat = $latitude->getLatitude();
         $long = $latitude->getLongitude();
     } else {
         // Coordinates supplied as separate values.
         $lat = $latitude;
         $long = $longitude;
     }
     // TODO: validate lat and long ranges, assuming they have been set, and throw exception if necessary.
     // lat: -180 to +180; long: -90 to +90
     /*
     if (...) {
         // Exception here.
         throw new \InvalidArgumentException(
             'error...'
         );
     );
     */
     // Convert to radians.
     $lat_rad = deg2rad($lat);
     $long_rad = deg2rad($long);
     // Calculate the zone number.
     $zone_number = static::calcZoneNumber($lat, $long);
     // +3 puts origin in middle of zone
     $long_origin = ($zone_number - 1) * 6 - 180 + 3;
     $long_origin_rad = deg2rad($long_origin);
     $ecc_prime_squared = static::$ecc_squared / (1 - static::$ecc_squared);
     $N = static::$a / sqrt(1 - static::$ecc_squared * pow(sin($lat_rad), 2));
     $T = pow(tan($lat_rad), 2);
     $C = $ecc_prime_squared * pow(cos($lat_rad), 2);
     $A = cos($lat_rad) * ($long_rad - $long_origin_rad);
     $M = static::$a * ((1 - static::$ecc_squared / 4 - 3 * pow(static::$ecc_squared, 2) / 64 - 5 * pow(static::$ecc_squared, 3) / 256) * $lat_rad - (3 * static::$ecc_squared / 8 + 3 * pow(static::$ecc_squared, 2) / 32 + 45 * pow(static::$ecc_squared, 3) / 1024) * sin(2 * $lat_rad) + (15 * pow(static::$ecc_squared, 2) / 256 + 45 * pow(static::$ecc_squared, 3) / 1024) * sin(4 * $lat_rad) - 35 * pow(static::$ecc_squared, 3) / 3072 * sin(6 * $lat_rad));
     $utm_easting = static::$k0 * $N * ($A + (1 - $T + $C) * pow($A, 3) / 6.0 + (5 - 18 * pow($T, 3) + 72 * $C - 58 * $ecc_prime_squared) * pow($A, 5) / 120.0) + 500000.0;
     $utm_northing = static::$k0 * ($M + $N * tan($lat_rad) * ($A * $A / 2 + (5 - $T + 9 * $C + 4 * pow($C, 2)) * pow($A, 4) / 24.0 + (61 - 58 * pow($T, 3) + 600 * $C - 330 * $ecc_prime_squared) * pow($A, 6) / 720.0));
     if ($lat < 0.0) {
         // 10,000,000 meter offset for southern hemisphere
         $utm_northing += 10000000.0;
     }
     $northing = round($utm_northing);
     $easting = round($utm_easting);
     $zone_number = $zone_number;
     $zone_letter = static::calcLetterDesignator($lat);
     // Return a new object instatiation.
     return new static($northing, $easting, $zone_number, $zone_letter);
 }
Exemplo n.º 2
0
 public function testSetYValue()
 {
     $latLongObject = new LatLong($this->_xyz);
     $fluidReturn = $latLongObject->setLongitude($this->_angle);
     $longitudeValue = $latLongObject->getLongitude();
     $this->assertTrue(is_object($longitudeValue));
     $this->assertTrue(is_a($longitudeValue, 'Geodetic\\Angle'));
     $this->assertEquals(12345.6789, $longitudeValue->getValue());
     //    Test fluid return object
     $this->assertTrue(is_object($fluidReturn));
     //    ... of the correct type
     $this->assertTrue(is_a($fluidReturn, 'Geodetic\\LatLong'));
 }
Exemplo n.º 3
0
 /**
  * Get the midpoint for a great circle route between two Latitude/Longitude objects
  *
  * @param     LatLong    $endPoint    The destination point
  * @return    LatLong    The midpoint Lat/Long between this Lat/Long and the $endpoint Lat/Long
  * @throws    Exception
  */
 public function getMidpoint(LatLong $endPoint)
 {
     $deltaLongitude = $endPoint->getLongitude()->getValue(Angle::RADIANS) - $this->longitude->getValue(Angle::RADIANS);
     $xModified = cos($endPoint->getLatitude()->getValue(Angle::RADIANS)) * cos($deltaLongitude);
     $yModified = cos($endPoint->getLatitude()->getValue(Angle::RADIANS)) * sin($deltaLongitude);
     $midpointLatitude = atan2(sin($this->latitude->getValue(Angle::RADIANS)) + sin($endPoint->getLatitude()->getValue(Angle::RADIANS)), sqrt((cos($this->latitude->getValue(Angle::RADIANS)) + $xModified) * (cos($this->latitude->getValue(Angle::RADIANS)) + $xModified) + $yModified * $yModified));
     $midpointLongitude = $this->longitude->getValue(Angle::RADIANS) + atan2($yModified, cos($this->latitude->getValue(Angle::RADIANS)) + $xModified);
     return new LatLong(new LatLong\CoordinateValues(self::cleanLatitude($midpointLatitude), self::cleanLongitude($midpointLongitude), Angle::RADIANS));
 }
Exemplo n.º 4
0
 /**
  * Identify whether a specified Latitude/Longitude falls within the bounds of this region
  *
  * @param     LatLong    The Latitude/Longitude object that we wish to test
  * @return    boolean
  */
 public function isInRegion(LatLong $position)
 {
     $latitude = $position->getLatitude()->getValue();
     $longitude = $position->getLongitude()->getValue();
     $perimeterNodeCount = count($this->nodePoints);
     $jIndex = $perimeterNodeCount - 1;
     $oddNodes = false;
     for ($iIndex = 0; $iIndex < $perimeterNodeCount; ++$iIndex) {
         $iLatitude = $this->nodePoints[$iIndex]->getLatitude()->getValue();
         $jLatitude = $this->nodePoints[$jIndex]->getLatitude()->getValue();
         if ($iLatitude < $latitude && $jLatitude >= $latitude || $jLatitude < $latitude && $iLatitude >= $latitude) {
             $iLongitude = $this->nodePoints[$iIndex]->getLongitude()->getValue();
             $jLongitude = $this->nodePoints[$jIndex]->getLongitude()->getValue();
             if ($iLongitude + ($latitude - $iLatitude) / ($jLatitude - $iLatitude) * ($jLongitude - $iLongitude) < $longitude) {
                 $oddNodes = !$oddNodes;
             }
         }
         $jIndex = $iIndex;
     }
     return $oddNodes;
 }