/** * Find a location a distance and bearing from this one * * @param Number $distance distance to other point * @param Number $bearing initial bearing to other point * @param String $unit The unit the distance is in * * @return Point */ public function getRelativePoint($distance, $bearing, $unit = 'km') { $rad = Location::getEllipsoid()->radius($unit); $lat1 = $this->latitudeToRad(); $lon1 = $this->longitudeToRad(); $bearing = deg2rad($bearing); $lat2 = sin($lat1) * cos($distance / $rad) + cos($lat1) * sin($distance / $rad) * cos($bearing); $lat2 = asin($lat2); $lon2y = sin($bearing) * sin($distance / $rad) * cos($lat1); $lon2x = cos($distance / $rad) - sin($lat1) * sin($lat2); $lon2 = $lon1 + atan2($lon2y, $lon2x); return new self(rad2deg($lat2), rad2deg($lon2)); }
/** * @param Point $point the centre of the bounding box * @param number $radius minimum radius from $point * @param string $unit unit of the radius (default is kilometres) * * @return Polygon the BBox */ public static function getBBoxByRadius(Point $point, $radius, $unit = 'km') { $north = $point->getRelativePoint($radius, 0, $unit); $south = $point->getRelativePoint($radius, 180, $unit); $limits['n'] = $north->getLatitude(); $limits['s'] = $south->getLatitude(); $radDist = $radius / Location::getEllipsoid()->radius($unit); // $minLat = deg2rad( $limits['s'] ); // $maxLat = deg2rad( $limits['n'] ); $radLon = $point->longitudeToRad(); //if ($minLat > deg2rad(-90) && $maxLat < deg2rad(90)) { $deltaLon = asin(sin($radDist) / cos($point->latitudeToRad())); $minLon = $radLon - $deltaLon; if ($minLon < deg2rad(-180)) { $minLon += 2 * pi(); } $maxLon = $radLon + $deltaLon; if ($maxLon > deg2rad(180)) { $maxLon -= 2 * pi(); } //} $limits['w'] = rad2deg($minLon); $limits['e'] = rad2deg($maxLon); $nw = new Point($limits['n'], $limits['w']); $ne = new Point($limits['n'], $limits['e']); $sw = new Point($limits['s'], $limits['w']); $se = new Point($limits['s'], $limits['e']); $polygon = new Polygon([[$nw, $ne, $se, $sw]]); return $polygon; }