如何在CI库中使用静态函数?

时间:2016-11-10 16:05:07

标签: php codeigniter

我在计算边界坐标和计算地球上两点之间的距离方面有很大的资源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::$GeoLocationcreateLocation功能一致{。}}。

0 个答案:

没有答案