Skip to content

Instantly share code, notes, and snippets.

@acidjazz
Created September 26, 2019 21:48
Show Gist options
  • Save acidjazz/9554c6c27eeccde9b8bc8a35ea972246 to your computer and use it in GitHub Desktop.
Save acidjazz/9554c6c27eeccde9b8bc8a35ea972246 to your computer and use it in GitHub Desktop.
<?php
namespace App\Services;
use GuzzleHttp\Client;
/**
* Geographical Coordinate Services
*
* @package LocationService
* @author kevin olson <acidjazz@gmail.com>
* @version 0.1
* @copyright (C) 2019 kevin olson <acidjazz@gmail.com>
* @license APACHE
*/
class LocationService {
public static function getTimezone($lat, $lng)
{
$client = new Client(['base_uri' => 'https://maps.googleapis.com/']);
$result = $client->get(
'/maps/api/timezone/json', [
'query' => [
'location' => $lat.','.$lng,
'timestamp' => time(),
'key' => config('services.google.api_key'),
]])->getBody()->getContents();
return json_decode($result, true);
}
public static function randomCoords($middle, $distance) {
$floats = static::generate_random_point([
$middle['lat'], $middle['lng'] ], $distance);
return ['lng' => $floats[1], 'lat' => $floats[0]];
}
/**
* Return a random point within a radius of miles
*
* Given a $centre (latitude, longitude) co-ordinates and a
* distance $radius (miles), returns a random point (latitude,longtitude)
* which is within $radius miles of $centre.
*
* @param Array $centre Numeric array of floats. First element is
* latitude, second is longitude.
* @param Float $radius The radius (in miles).
* @return Array Numeric array of floats (lat/lng). First
* element is latitude, second is longitude.
*/
private static function generate_random_point( $centre, $radius ){
$radius_earth = 3959; //miles
// pick random distance within $distance;
$distance = lcg_value() * $radius;
// convert degrees to radians.
$centre_rads = array_map('deg2rad', $centre);
// first suppose our point is the north pole.
// find a random point $distance miles away
$lat_rads = (pi() / 2) - $distance / $radius_earth;
$lng_rads = lcg_value() * 2 * pi();
// ($lat_rads,$lng_rads) is a point on the circle which is
// $distance miles from the north pole. Convert to Cartesian
$x1 = cos($lat_rads) * sin($lng_rads);
$y1 = cos($lat_rads) * cos($lng_rads);
$z1 = sin($lat_rads);
// rotate that sphere so that the north pole is now at $centre.
// rotate in x axis by $rot = (pi()/2) - $centre_rads[0];
$rot = (pi() / 2) - $centre_rads[0];
$x2 = $x1;
$y2 = $y1 * cos($rot) + $z1 * sin($rot);
$z2 = -$y1 * sin($rot) + $z1 * cos($rot);
// rotate in z axis by $rot = $centre_rads[1]
$rot = $centre_rads[1];
$x3 = $x2 * cos($rot) + $y2 * sin($rot);
$y3 = -$x2 * sin($rot) + $y2 * cos($rot);
$z3 = $z2;
// finally convert this point to polar co-ords
$lng_rads = atan2($x3, $y3);
$lat_rads = asin($z3);
return array_map('rad2deg', [$lat_rads, $lng_rads]);
}
/**
* Return a rectangle with its center
*
* Given x,y of two coordinates, calculate the
* center of the shape and its other two coordinates
*
* @param Float $x1 - x1
* @param Float $y1 - y1
* @param Float $x2 - x2
* @param Float $y2 - y2
*
* @return Array Numeric Array of x,y of all 4 coordinates and its centner
*/
public static function rectangle($x1, $y1, $x2, $y2)
{
/*
x1 = ? ; y1 = ? ; // First diagonal point
x2 = ? ; y2 = ? ; // Second diagonal point
xc = (x1 + x2)/2 ; yc = (y1 + y2)/2 ; // Center point
xd = (x1 - x2)/2 ; yd = (y1 - y2)/2 ; // Half-diagonal
x3 = xc - yd ; y3 = yc + xd; // Third corner
x4 = xc + yd ; y4 = yc - xd; // Fourth corner
*/
$x_c = ($x1 + $x2)/2;
$y_c = ($y1 + $y2)/2;
$x_d = ($x1 - $x2) / 2;
$y_d = ($y1 - $y2) / 2;
$x3 = $x_c - $y_d;
$y3 = $y_c + $x_d;
$x4 = $x_c + $y_d;
$y4 = $y_c - $x_d;
return [[$x1, $y1], [$x2, $y2], [$x3, $y3], [$x4, $y4], [$x_c, $y_c], ];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment