/** * Exact distance with Haversine formula * * @param LatLng $coord * * @return float * @see http://www.movable-type.co.uk/scripts/latlong.html */ public function exactDistanceFrom(LatLng $coord) { $lat1 = deg2rad($this->getLat()); $lat2 = deg2rad($coord->getLat()); $lon1 = deg2rad($this->getLng()); $lon2 = deg2rad($coord->getLng()); $dLatHalf = ($lat2 - $lat1) / 2; $dLonHalf = ($lon2 - $lon1) / 2; $a = pow(sin($dLatHalf), 2) + cos($lat1) * cos($lat2) * pow(sin($dLonHalf), 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); return $c * UnitsType::EARTH_RADIUS; }
/** * Calculate the bounds corresponding to a specific center and zoom level for a give map size in pixels * @param LatLng $center * @param integer $zoom * @param integer $width * @param integer $height * @return LatLngBounds */ public static function getBoundsFromCenterAndZoom(LatLng $center, $zoom, $width, $height = null) { if (is_null($height)) { $height = $width; } $centerLat = $center->getLat(); $centerLng = $center->getLng(); $pix = LatLng::latToPixels($centerLat, $zoom); $neLat = LatLng::pixelsToLat($pix - round(($height - 1) / 2), $zoom); $swLat = LatLng::pixelsToLat($pix + round(($height - 1) / 2), $zoom); $pix = LatLng::lngToPixels($centerLng, $zoom); $swLng = LatLng::pixelsToLng($pix - round(($width - 1) / 2), $zoom); $neLng = LatLng::pixelsToLng($pix + round(($width - 1) / 2), $zoom); return new self(['southWest' => new LatLng(['lat' => $swLat, 'lng' => $swLng]), 'northEast' => new LatLng(['lat' => $neLat, 'lng' => $neLng])]); }
/** * Returns the center coordinates of an array of Markers * * @param Marker[] $markers * * @return LatLng|null * @throws \yii\base\InvalidParamException */ public static function getCenterOfMarkers($markers) { $coords = []; foreach ($markers as $marker) { if (!$marker instanceof Marker) { throw new InvalidParamException('$markers must be an array of "' . self::className() . '" objects'); } $coords[] = $marker->position; } return LatLng::getCenterOfCoordinates($coords); }