<?php

const R = 6371; // km

function distance_between_points_rad($lat1, $lng1, $lat2, $lng2){
    // latlng in radians
    $x = ($lng2-$lng1) * cos(($lat1+$lat2)/2);
    $y = ($lat2-$lat1);
    // return distance in km
    return sqrt($x*$x + $y*$y) * R;
}

function get_destination_lat_rad($lat1, $lng1, $d, $brng){
    return asin( sin($lat1)*cos($d/R) +
                    cos($lat1)*sin($d/R)*cos($brng) );
}

function get_destination_lng_rad($lat1, $lng1, $d, $brng){
    $lat2 = get_destination_lat_rad($lat1, $lng1, $d, $brng);
    return $lng1 + atan2(sin($brng)*sin($d/R)*cos($lat1),
                         cos($d/R)-sin($lat1)*sin($lat2));
}

function get_bounding_box_rad($lat, $lng, $range){
    // latlng in radians, $range in km
    $latmin = get_destination_lat_rad($lat, $lng, $range, 0);
    $latmax = get_destination_lat_rad($lat, $lng, $range, deg2rad(180));
    $lngmax = get_destination_lng_rad($lat, $lng, $range, deg2rad(90));
    $lngmin = get_destination_lng_rad($lat, $lng, $range, deg2rad(270));
    // return approx bounding latlng in radians
    return array($latmin, $latmax, $lngmin, $lngmax);
}

function distance_between_points_deg($lat1, $lng1, $lat2, $lng2){
    // latlng in degrees
    // return distance in km
    return distance_between_points_rad(
        deg2rad($lat1), deg2rad($lng1), deg2rad($lat2), deg2rad($lng2) );
}

function get_bounding_box_deg($lat, $lng, $range){
    // latlng in degrees, $range in km
    return array_map(rad2deg,
        get_bounding_box_rad(deg2rad($lat), deg2rad($lng), $range));
}

// tests
// distance from berlin (52.5200 N, 13.4050 E) to vienna (48.2082 N, 16.3738 E)
echo "Berlin to Vienna " . 
    distance_between_points_deg(52.5200, 13.4050, 48.2082, 16.3738) . " km \n";
var_dump(get_bounding_box_deg(52.5200, 13.4050, 0.5));