<?php

class Gis {

	final public static function haversineDistanceBetweenTwoGpsCoordinates($lat1, $lon1, $lat2, $lon2, $unit="M") {
		if (($lat1 == $lat2) && ($lon1 == $lon2)) {
			return 0;
		}
		else {
			$theta = $lon1 - $lon2;
			$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
			$dist = acos($dist);
			$dist = rad2deg($dist);
			$miles = $dist * 60 * 1.1515;
			$unit = strtoupper($unit);

			if ($unit == "K") {
				return ($miles * 1.609344);
			} else if ($unit == "N") {
				return ($miles * 0.8684);
			} else {
				return $miles;
			}
		}
	}

	final public static function cosinesDistanceBetweenTwoGpsCoordinates($lat1, $lon1, $lat2, $lon2, $unit="M") {
		if (($lat1 == $lat2) && ($lon1 == $lon2)) {
			return 0;
		}
		$dist = acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon2 - $lon1))) * 6371;
		$unit = strtoupper($unit);
		if ($unit == "K") {
			return $dist;
		} else {
			return $dist/1.609344;
		}
	}

	final public static function getCityServicesAvailableForCoordinates($db_conn ,$lat, $lng, $providers=[]) {
		return 	self::getServicesAvailableForCoordinates($db_conn, self::GET_CITY_PROVIDERS_IN_RADIUS, $lat, $lng, $providers);
	}

	final public static function getCountryServicesAvailableForCoordinates($db_conn ,$lat, $lng, $providers=[]) {
		return 	self::getServicesAvailableForCoordinates($db_conn, self::GET_COUNTRY_PROVIDERS_IN_RADIUS, $lat, $lng, $providers);
	}

	final protected static function getServicesAvailableForCoordinates($db_conn, $q, $lat, $lng, $providers=[]) {

		$result = [];

		$params = [ $lng, $lat];

		if (count($providers)) {
			$params[]="{".implode(",", $providers). "}";
			$q = $q."AND transport_provider_id = ANY($3)";
		}
		$req_result = pg_query_params($db_conn, $q, $params);
		if (!$req_result) {
			return $result;
		}
		while ($row = pg_fetch_assoc($req_result)) {
			array_push($result, $row);
		}
		return $result;
	}

	const GET_CITY_PROVIDERS_IN_RADIUS = "
			SELECT cs.* FROM geofence_area_city gac
			LEFT JOIN city_services cs ON gac.id = cs.city_id
			WHERE
      	ST_DistanceSphere(location::geometry, ST_SetSRID(ST_MakePoint($1,$2),4326)) <= radius
	";

	const GET_COUNTRY_PROVIDERS_IN_RADIUS = "
			SELECT cs.* FROM geofence_area_country gac
			LEFT JOIN country_services cs ON gac.id = cs.country_id
			WHERE
      	ST_DistanceSphere(location::geometry, ST_SetSRID(ST_MakePoint($1,$2),4326)) <= radius
	";


}