public static function fromCenterAndDistance(GeolocationInterface $center, Distance $distance) { $radLat = deg2rad($center->getLat()); $radLon = deg2rad($center->getLong()); // angular distance in radians on a great circle $radDist = $distance->getMeters() / GeolocationInterface::EARTH_RADIUS; $minLat = $radLat - $radDist; $maxLat = $radLat + $radDist; $deltaLon = asin(sin($radDist) / cos($radLat)); $minLon = $radLon - $deltaLon; //if (minLon < MIN_LON) {minLon += 2d * Math.PI;} $maxLon = $radLon + $deltaLon; //if (maxLon > MAX_LON) {maxLon -= 2d * Math.PI;} $min = new Geolocation(rad2deg($maxLat), rad2deg($minLon)); $max = new Geolocation(rad2deg($minLat), rad2deg($maxLon)); return new BoundingBox($min, $max); }
/** @return Distance */ public function distanceTo(GeolocationInterface $otherGeolocation) { if (!$this->latRadians) { $this->latRadians = deg2rad($this->lat); } if (!$this->longRadians) { $this->longRadians = deg2rad($this->long); } $latFrom = $this->latRadians; $lonFrom = $this->longRadians; $latTo = deg2rad($otherGeolocation->getLat()); $lonTo = deg2rad($otherGeolocation->getLong()); $latDelta = $latTo - $latFrom; $lonDelta = $lonTo - $lonFrom; $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) + cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2))); return new Distance($angle * GeolocationInterface::EARTH_RADIUS); }