我在计算边界坐标和计算地球上两点之间的距离方面有很大的资源this。
当我伤害这个时,我开始建立自己的CI库。我很乐意根据自己的需要调整它,但我对如何操作感到很遗憾。
边界坐标有例子:
$edison = GeoLocation::fromDegrees(40.5187154, -74.4120953);
$coordinates = $edison->boundingCoordinates(3, 'miles');
问题是 - 如果我使用这个类作为我的库,我该如何实际调用它?
$edison = $this->Geolibrary->GeoLocation::fromDegrees(40.5187154, -74.4120953);
或者我应该如何正确地更改代码以将其用作库?
更新
图书馆代码:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class GeoLocation {
private $radLat; // latitude in radians
private $radLon; // longitude in radians
private $degLat; // latitude in degrees
private $degLon; // longitude in degrees
private $angular; // angular radius
const EARTHS_RADIUS_KM = 6371.01;
const EARTHS_RADIUS_MI = 3958.762079;
protected static $MIN_LAT; // -PI/2
protected static $MAX_LAT; // PI/2
protected static $MIN_LON; // -PI
protected static $MAX_LON; // PI
public function __construct() {
self::$MIN_LAT = deg2rad(-90); // -PI/2
self::$MAX_LAT = deg2rad(90); // PI/2
self::$MIN_LON = deg2rad(-180); // -PI
self::$MAX_LON = deg2rad(180); // PI
}
public function createLocation($latitude, $longitude, $from)
{
// I want to create an instance here ???
}
/**
* @param double $latitude the latitude, in degrees.
* @param double $longitude the longitude, in degrees.
* @return GeoLocation
*/
private static function fromDegrees($latitude, $longitude) {
$location = new GeoLocation();
$location->radLat = deg2rad($latitude);
$location->radLon = deg2rad($longitude);
$location->degLat = $latitude;
$location->degLon = $longitude;
$location->checkBounds();
return $location;
}
/**
* @param double $latitude the latitude, in radians.
* @param double $longitude the longitude, in radians.
* @return GeoLocation
*/
private static function fromRadians($latitude, $longitude) {
$location = new GeoLocation();
$location->radLat = $latitude;
$location->radLon = $longitude;
$location->degLat = rad2deg($latitude);
$location->degLon = rad2deg($longitude);
$location->checkBounds();
return $location;
}
protected function checkBounds() {
if ($this->radLat < self::$MIN_LAT || $this->radLat > self::$MAX_LAT ||
$this->radLon < self::$MIN_LON || $this->radLon > self::$MAX_LON)
throw new \Exception("Invalid Argument");
}
/**
* Computes the great circle distance between this GeoLocation instance
* and the location argument.
* @param GeoLocation $location
* @param string $unit_of_measurement
* @internal param float $radius the radius of the sphere, e.g. the average radius for a
* spherical approximation of the figure of the Earth is approximately
* 6371.01 kilometers.
* @return double the distance, measured in the same unit as the radius
* argument.
*/
public function distanceTo(GeoLocation $location, $unit_of_measurement) {
$radius = $this->getEarthsRadius($unit_of_measurement);
return acos(sin($this->radLat) * sin($location->radLat) +
cos($this->radLat) * cos($location->radLat) *
cos($this->radLon - $location->radLon)) * $radius;
}
/**
* @return double the latitude, in degrees.
*/
public function getLatitudeInDegrees() {
return $this->degLat;
}
/**
* @return double the longitude, in degrees.
*/
public function getLongitudeInDegrees() {
return $this->degLon;
}
/**
* @return double the latitude, in radians.
*/
public function getLatitudeInRadians() {
return $this->radLat;
}
/**
* @return double the longitude, in radians.
*/
public function getLongitudeInRadians() {
return $this->radLon;
}
/**
* @return double angular radius.
*/
public function getAngular() {
return $this->angular;
}
public function __toString() {
return "(" . $this->degLat . ", " . $this->degLon . ") = (" .
$this->radLat . " rad, " . $this->radLon . " rad";
}
/**
* <p>Computes the bounding coordinates of all points on the surface
* of a sphere that have a great circle distance to the point represented
* by this GeoLocation instance that is less or equal to the distance
* argument.</p>
* <p>For more information about the formulae used in this method visit
* <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates">
* http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates</a>.</p>
*
* @param double $distance the distance from the point represented by this
* GeoLocation instance. Must me measured in the same unit as the radius
* argument.
* @param string $unit_of_measurement
* @throws \Exception
* @internal param radius the radius of the sphere, e.g. the average radius for a
* spherical approximation of the figure of the Earth is approximately
* 6371.01 kilometers.
* @return GeoLocation[] an array of two GeoLocation objects such that:<ul>
* <li>The latitude of any point within the specified distance is greater
* or equal to the latitude of the first array element and smaller or
* equal to the latitude of the second array element.</li>
* <li>If the longitude of the first array element is smaller or equal to
* the longitude of the second element, then
* the longitude of any point within the specified distance is greater
* or equal to the longitude of the first array element and smaller or
* equal to the longitude of the second array element.</li>
* <li>If the longitude of the first array element is greater than the
* longitude of the second element (this is the case if the 180th
* meridian is within the distance), then
* the longitude of any point within the specified distance is greater
* or equal to the longitude of the first array element
* <strong>or</strong> smaller or equal to the longitude of the second
* array element.</li>
* </ul>
*/
public function boundingCoordinates($distance, $unit_of_measurement) {
$radius = $this->getEarthsRadius($unit_of_measurement);
if ($radius < 0 || $distance < 0) throw new \Exception('Arguments must be greater than 0.');
// angular distance in radians on a great circle
$this->angular = $distance / $radius;
$minLat = $this->radLat - $this->angular;
$maxLat = $this->radLat + $this->angular;
$minLon = 0;
$maxLon = 0;
if ($minLat > self::$MIN_LAT && $maxLat < self::$MAX_LAT) {
$deltaLon = asin(sin($this->angular) /
cos($this->radLat));
$minLon = $this->radLon - $deltaLon;
if ($minLon < self::$MIN_LON) $minLon += 2 * pi();
$maxLon = $this->radLon + $deltaLon;
if ($maxLon > self::$MAX_LON) $maxLon -= 2 * pi();
} else {
// a pole is within the distance
$minLat = max($minLat, self::$MIN_LAT);
$maxLat = min($maxLat, self::$MAX_LAT);
$minLon = self::$MIN_LON;
$maxLon = self::$MAX_LON;
}
return array(
GeoLocation::fromRadians($minLat, $minLon),
GeoLocation::fromRadians($maxLat, $maxLon)
);
}
protected function getEarthsRadius($unit_of_measurement) {
$u = $unit_of_measurement;
if($u == 'miles' || $u == 'mi')
return $radius = self::EARTHS_RADIUS_MI;
elseif($u == 'kilometers' || $u == 'km')
return $radius = self::EARTHS_RADIUS_KM;
else throw new \Exception('You must supply a valid unit of measurement');
}
/**
* Retrieves Geocoding information from Google
* eg. $response = GeoLocation::getGeocodeFromGoogle($location);
* $latitude = $response->results[0]->geometry->location->lng;
* $longitude = $response->results[0]->geometry->location->lng;
* @param string $location address, city, state, etc.
* @return \stdClass
*/
public static function getGeocodeFromGoogle($location) {
$url = 'http://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($location).'&sensor=false';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
return json_decode(curl_exec($ch));
}
public static function MilesToKilometers($miles) {
return $miles * 1.6093439999999999;
}
public static function KilometersToMiles($km) {
return $km * 0.621371192237334;
}
}
我想创建函数createLocation,所以我可以像这样使用库:
$this->load->library('GeoLocation');
$lat=$this->input->post('latitude');
$lng=$this->input->post('longitude');
$radius=$this->input->post('radiuss');
$user_center = $this->GeoLocation->createLocation($lat, $lng);
$boundingCoordinates = $user_center->boundingCoordinates($radius, 'kilometers');
我试过了:
public function createLocation($latitude, $longitude)
{
$loc = GeoLocation::fromDegrees($latitude, $longitude);
return $loc;
}
但是Undefined property: Alerts::$GeoLocation
与createLocation
功能一致{。}}。