<?php
class Coordinate
{
/** @var float $latitudeRadians */
protected $latitudeRadians;
/** @var float $longitudeRadians */
protected $longitudeRadians;
/**
* Constructor.
*
* @param float $latitudeRadians
* @param float $latitudeRadians
*/
public function __construct(
float $latitudeRadians,
float $longitudeRadians
) {
$this->latitudeRadians = $latitudeRadians;
$this->longitudeRadians = $longitudeRadians;
}
/**
* Create a Coordinate object from latitude and longitude given in degrees.
*
* @param float $latitudeDegrees
* @param float $longitudeDegrees
*
* @return static
*/
public static function fromDegrees(float $latitudeDegrees, float $longitudeDegrees)
{
return new static(
$latitudeDegrees * M_PI / 180,
$longitudeDegrees * M_PI / 180
);
}
/**
* Get the coordinate's latitude, measured in degrees.
*
* @return float
*/
public function latitudeDegrees() : float
{
return $this->latitudeRadians * 180 / M_PI;
}
/**
* Get the coordinate's latitude, measured in radians.
*
* @return float
*/
public function latitudeRadians() : float
{
return $this->latitudeRadians;
}
/**
* Get the coordinate's longitude, measured in degrees.
*
* @return float
*/
public function longitudeDegrees() : float
{
return $this->longitudeRadians * 180 / M_PI;
}
/**
* Get the coordinate's longitude, measured in radians.
*
* @return float
*/
public function longitudeRadians() : float
{
return $this->longitudeRadians;
}
/**
* Is this coordinate equivalent to another?
*
* @param static $other
*
* @return bool
*/
public function equals(self $other) : bool
{
return $this->latitudeRadians() === $other->latitudeRadians()
&& $this->longitudeRadians() === $other->longitudeRadians()
;
}
/**
* Calculate the distance between this and another coordinate, in kilometers.
*
* @param static $other
*
* @return float
*/
public function distanceKilometers(self $other) : float
{
// Haversine formula for great-circle distance.
$earthRadiusKilometers = 6371;
$deltaLatitudeRadians = $this->latitudeRadians() - $other->latitudeRadians();
$deltaLongitudeRadians = $this->longitudeRadians() - $other->longitudeRadians();
$a = sin($deltaLatitudeRadians / 2) ** 2
+ cos($this->latitudeRadians())
* cos($other->latitudeRadians())
* sin($deltaLongitudeRadians / 2) ** 2
;
$c = 2 * asin(sqrt($a));
return $c * $earthRadiusKilometers;
}
}
$latitudeWorkDegrees = 40.981123;
$longitudeWorkDegrees = -74.121752;
$latitudeHomeDegrees = 41.184084;
$longitudeHomeDegrees = -74.555852;
$latitudeWorkRadians = deg2rad($latitudeWorkDegrees);
$longitudeWorkRadians = deg2rad($longitudeWorkDegrees);
$latitudeHomeRadians = deg2rad($latitudeHomeDegrees);
$longitudeHomeRadians = deg2rad($longitudeHomeDegrees);
$coordinateWork = new Coordinate($latitudeWorkRadians, $longitudeWorkRadians);
$coordinateHome = new Coordinate($latitudeHomeRadians, $longitudeHomeRadians);
$distance = $coordinateWork->distanceKilometers($coordinateHome);
echo $distance;
preferences:
74.38 ms | 402 KiB | 5 Q