<?php
require_once(dirname(__FILE__).'/utils.class.php');

interface LatLon {
  public function get_lat();
  public function get_lon();
}

interface Collection {
  public static function get_all();
}

abstract class GeoPoint implements LatLon, Collection {
  /**  distance, by Vincenty formula
       see http://stackoverflow.com/a/10054282
   */
  public function distance($other_point) {
    $earthRadius = 6371;

	// convert from degrees to radians
	$latFrom = deg2rad($this->get_lat());
	$lonFrom = deg2rad($this->get_lon());
	$latTo = deg2rad($other_point->get_lat());
	$lonTo = deg2rad($other_point->get_lon());

	$lonDelta = $lonTo - $lonFrom;
	$a = pow(cos($latTo) * sin($lonDelta), 2) +
	  pow(cos($latFrom) * sin($latTo) -
      sin($latFrom) * cos($latTo) * cos($lonDelta), 2);
	$b = sin($latFrom) * sin($latTo) +
      cos($latFrom) * cos($latTo) * cos($lonDelta);

	$angle = atan2(sqrt($a), $b);
	return $angle * $earthRadius;
  }

  /** Gets only the points in a circle of $distance km arround $opint

     @param $target a LatLon
   */
  public static function near_points($target, $distance) {
    $near_points = array();
    foreach (static::get_all() as $point) {
      if ($point->distance($target) < $distance) {
        $near_points[] = $point;
      }
    }
    return $near_points;
  }
}
?>
