Ejemplo n.º 1
0
	  /**
	* <p>Computes the bounding coordinates of all points on the surface
	* of a sphere that have a great circle distance to the point represented
	* by this GeoLocation instance that is less or equal to the distance
	* argument.</p>
	* <p>For more information about the formulae used in this method visit
	* <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates">
	* http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates</a>.</p>
	*
	* @param double $distance the distance from the point represented by this
	* GeoLocation instance. Must me measured in the same unit as the radius
	* argument.
	* @param string $unit_of_measurement
	* @throws \Exception
	* @internal param radius the radius of the sphere, e.g. the average radius for a
	* spherical approximation of the figure of the Earth is approximately
	* 6371.01 kilometers.
	* @return GeoLocation[] an array of two GeoLocation objects such that:<ul>
	* <li>The latitude of any point within the specified distance is greater
	* or equal to the latitude of the first array element and smaller or
	* equal to the latitude of the second array element.</li>
	* <li>If the longitude of the first array element is smaller or equal to
	* the longitude of the second element, then
	* the longitude of any point within the specified distance is greater
	* or equal to the longitude of the first array element and smaller or
	* equal to the longitude of the second array element.</li>
	* <li>If the longitude of the first array element is greater than the
	* longitude of the second element (this is the case if the 180th
	* meridian is within the distance), then
	* the longitude of any point within the specified distance is greater
	* or equal to the longitude of the first array element
	* <strong>or</strong> smaller or equal to the longitude of the second
	* array element.</li>
	* </ul>
	*/
	public function boundingCoordinates($distance, $unit_of_measurement) {
		$radius = $this->getEarthsRadius($unit_of_measurement);
		if ($radius < 0 || $distance < 0) throw new \Exception('Arguments must be greater than 0.');
		
		// angular distance in radians on a great circle
		$this->angular = $distance / $radius;
		
		$minLat = $this->radLat - $this->angular;
		$maxLat = $this->radLat + $this->angular;
		
		$minLon = 0;
		$maxLon = 0;
		if ($minLat > self::$MIN_LAT && $maxLat < self::$MAX_LAT) {
		$deltaLon = asin(sin($this->angular) /
		cos($this->radLat));
		$minLon = $this->radLon - $deltaLon;
		if ($minLon < self::$MIN_LON) $minLon += 2 * pi();
		$maxLon = $this->radLon + $deltaLon;
		if ($maxLon > self::$MAX_LON) $maxLon -= 2 * pi();
		} else {
		// a pole is within the distance
		$minLat = max($minLat, self::$MIN_LAT);
		$maxLat = min($maxLat, self::$MAX_LAT);
		$minLon = self::$MIN_LON;
		$maxLon = self::$MAX_LON;
		}
		
		return array(
		GeoLocation::fromRadians($minLat, $minLon),
		GeoLocation::fromRadians($maxLat, $maxLon)
		);
	}
Ejemplo n.º 2
0
 /**
  * <p>Computes the bounding coordinates of all points on the surface
  * of a sphere that have a great circle distance to the point represented
  * by this GeoLocation instance that is less or equal to the distance
  * argument.</p>
  * <p>For more information about the formulae used in this method visit
  * <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates">
  * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates</a>.</p>
  * @param distance the distance from the point represented by this
  * GeoLocation instance. Must me measured in the same unit as the radius
  * argument.
  * @param radius the radius of the sphere, e.g. the average radius for a
  * spherical approximation of the figure of the Earth is approximately
  * 6371.01 kilometers.
  * @return an array of two GeoLocation objects such that:<ul>
  * <li>The latitude of any point within the specified distance is greater
  * or equal to the latitude of the first array element and smaller or
  * equal to the latitude of the second array element.</li>
  * <li>If the longitude of the first array element is smaller or equal to
  * the longitude of the second element, then
  * the longitude of any point within the specified distance is greater
  * or equal to the longitude of the first array element and smaller or
  * equal to the longitude of the second array element.</li>
  * <li>If the longitude of the first array element is greater than the
  * longitude of the second element (this is the case if the 180th
  * meridian is within the distance), then
  * the longitude of any point within the specified distance is greater
  * or equal to the longitude of the first array element
  * <strong>or</strong> smaller or equal to the longitude of the second
  * array element.</li>
  * </ul>
  */
 public function boundingCoordinates($distance, $radius)
 {
     if ($radius < 0 || $distance < 0) {
         throw new Exception('Arguments must be greater than 0.');
     }
     // angular distance in radians on a great circle
     $radDist = $distance / $radius;
     $minLat = $this->radLat - $radDist;
     $maxLat = $this->radLat + $radDist;
     $minLon = 0;
     $maxLon = 0;
     if ($minLat > MIN_LAT && $maxLat < MAX_LAT) {
         $deltaLon = asin(sin($radDist) / cos($this->radLat));
         $minLon = $this->radLon - $deltaLon;
         if ($minLon < MIN_LON) {
             $minLon += 2 * pi();
         }
         $maxLon = $this->radLon + $deltaLon;
         if ($maxLon > MAX_LON) {
             $maxLon -= 2 * pi();
         }
     } else {
         // a pole is within the distance
         $minLat = max($minLat, MIN_LAT);
         $maxLat = min($maxLat, MAX_LAT);
         $minLon = MIN_LON;
         $maxLon = MAX_LON;
     }
     return array(GeoLocation::fromRadians($minLat, $minLon), GeoLocation::fromRadians($maxLat, $maxLon));
 }