From d0cc2b6fc14425acc0579bc5dd4efbe7545bc273 Mon Sep 17 00:00:00 2001 From: Skylar Date: Sun, 27 Mar 2016 12:47:02 -0600 Subject: [PATCH] Add GeoLocation library --- composer.json | 3 +- composer.lock | 49 +++- proximity.php | 10 + vendor/anthonymartin/geo-location/README.md | 80 ++++++ .../anthonymartin/geo-location/composer.json | 24 ++ .../AnthonyMartin/GeoLocation/GeoLocation.php | 240 ++++++++++++++++++ vendor/composer/autoload_namespaces.php | 1 + vendor/composer/installed.json | 47 ++++ 8 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 proximity.php create mode 100644 vendor/anthonymartin/geo-location/README.md create mode 100644 vendor/anthonymartin/geo-location/composer.json create mode 100644 vendor/anthonymartin/geo-location/src/AnthonyMartin/GeoLocation/GeoLocation.php diff --git a/composer.json b/composer.json index 69c0b93..285efc6 100644 --- a/composer.json +++ b/composer.json @@ -8,6 +8,7 @@ } ], "require": { - "catfan/medoo": "dev-master" + "catfan/medoo": "dev-master", + "anthonymartin/geo-location": "^1.0" } } diff --git a/composer.lock b/composer.lock index 98d9ee3..844e354 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,54 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "cd601712cf0bad7d16f8a6559ee81b64", - "content-hash": "9718bf7d5a744cc861b207c4e67c28f7", + "hash": "6a03ffb1694f3ef4b0f1e02f7ab979f0", + "content-hash": "6aed0888384e1dbb0d616ba71ea1970a", "packages": [ + { + "name": "anthonymartin/geo-location", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/anthonymartin/GeoLocation.php.git", + "reference": "a54a562dfe8ae3eef9a5863552401d26bc80e921" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/anthonymartin/GeoLocation.php/zipball/a54a562dfe8ae3eef9a5863552401d26bc80e921", + "reference": "a54a562dfe8ae3eef9a5863552401d26bc80e921", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "class", + "autoload": { + "psr-0": { + "AnthonyMartin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "CC 3.0" + ], + "authors": [ + { + "name": "Anthony Martin", + "email": "anthony@replaycreative.com", + "homepage": "http://replaycreative.com", + "role": "Developer" + } + ], + "description": "Retrieve bounding coordinates, distances, longitude and latitude with GeoLocation.class.php", + "homepage": "https://github.com/anthonymartin/GeoLocation.php", + "keywords": [ + "bounding coordinates", + "distances", + "geocoding", + "geolocation" + ], + "time": "2013-10-25 21:13:03" + }, { "name": "catfan/medoo", "version": "dev-master", diff --git a/proximity.php b/proximity.php new file mode 100644 index 0000000..2a8591f --- /dev/null +++ b/proximity.php @@ -0,0 +1,10 @@ +select('messages', ['username', 'message', 'time'], ['AND' => [ + 'lat[>]' => $searchbounds[0]->getLatitudeInDegrees(), + 'lat[<]' => $searchbounds[1]->getLatitudeInDegrees(), + 'long[>]' => $searchbounds[0]->getLongitudeInDegrees(), + 'long[<]' => $searchbounds[1]->getLongitudeInDegrees()], + "ORDER" => "time DESC", + "LIMIT" => 30 + ]); \ No newline at end of file diff --git a/vendor/anthonymartin/geo-location/README.md b/vendor/anthonymartin/geo-location/README.md new file mode 100644 index 0000000..a3bdae9 --- /dev/null +++ b/vendor/anthonymartin/geo-location/README.md @@ -0,0 +1,80 @@ +GeoLocation +=========== + +Retrieve bounding coordinates and distances with GeoLocation. + +This is a PHP port of Java code that was originally published at + +http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates. A few modifications were made and an additional helper method to retrieve latitude and longitude from an address has been provided using Google's Geocoding API.
+ +License: +http://creativecommons.org/licenses/by/3.0/ + +Examples +======== + +Get distance between two points: +-------------------------------------------------------- +
+	
+		use AnthonyMartin\GeoLocation\GeoLocation as GeoLocation;
+		
+		// Set locations
+		$edison_nj = GeoLocation::fromDegrees(40.5187154, -74.4120953);
+		$brooklyn_ny = GeoLocation::fromDegrees(40.65, -73.95);
+
+		echo "Distance from Edison, NJ to Brookyln, NY: " . 
+			$edison_nj->distanceTo($brooklyn_ny, 'miles') . " miles \n";
+
+		# Distance from Edison, NJ to Brookyln, NY: 25.888611494606 miles 
+
+
+		echo "Distance from Edison, NJ to Brooklyn, NY: " . 
+			$edison_nj->distanceTo($brooklyn_ny, 'kilometers') . " kilometers \n";
+
+		# Distance from Edison, NJ to Brooklyn, NY: 41.663681581973 kilometers 
+
+	
+
+ + +Get bounding coordinates +-------------------------------------------------------- +
+	
+		use AnthonyMartin\GeoLocation\GeoLocation as GeoLocation;
+		
+		$edison = GeoLocation::fromDegrees(40.5187154, -74.4120953);
+		$coordinates = $edison->boundingCoordinates(3, 'miles');
+
+		echo "min latitude: " . $coordinates[0]->getLatitudeInDegrees() . " \n";
+		echo "min longitude: " . $coordinates[0]->getLongitudeInDegrees() . " \n";
+
+		echo "max latitude: " . $coordinates[1]->getLatitudeInDegrees() . " \n";
+		echo "max longitude: " . $coordinates[1]->getLongitudeInDegrees() . " \n";
+
+		/**
+		*	Returns:
+		*	min latitude: 40.47529593323 
+		*	min longitude: -74.469211617725 
+		*	max latitude: 40.56213486677 
+		*	max longitude: -74.354978982275 
+		**/
+
+	
+
+ +Get latitude and longitude from address or location +-------------------------------------------------------- +
+	
+	use AnthonyMartin\GeoLocation\GeoLocation as GeoLocation;
+	
+	$location = 'New York City';
+	$response = GeoLocation::getGeocodeFromGoogle($location);
+	$latitude = $response->results[0]->geometry->location->lat;
+	$longitude = $response->results[0]->geometry->location->lng;
+	echo $latitude . ', ' . $longitude;
+	# 40.7143528, -74.0059731
+	
+
diff --git a/vendor/anthonymartin/geo-location/composer.json b/vendor/anthonymartin/geo-location/composer.json new file mode 100644 index 0000000..2dfff4e --- /dev/null +++ b/vendor/anthonymartin/geo-location/composer.json @@ -0,0 +1,24 @@ +{ + "name": "anthonymartin/geo-location", + "type": "class", + "description": "Retrieve bounding coordinates, distances, longitude and latitude with GeoLocation.class.php", + "keywords": ["geolocation","geocoding", "bounding coordinates", "distances"], + "homepage": "https://github.com/anthonymartin/GeoLocation.php", + "license": "CC 3.0", + "authors": [ + { + "name": "Anthony Martin", + "email": "anthony@replaycreative.com", + "homepage": "http://replaycreative.com", + "role": "Developer" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-0": { + "AnthonyMartin": "src/" + } + } +} diff --git a/vendor/anthonymartin/geo-location/src/AnthonyMartin/GeoLocation/GeoLocation.php b/vendor/anthonymartin/geo-location/src/AnthonyMartin/GeoLocation/GeoLocation.php new file mode 100644 index 0000000..9cede87 --- /dev/null +++ b/vendor/anthonymartin/geo-location/src/AnthonyMartin/GeoLocation/GeoLocation.php @@ -0,0 +1,240 @@ +Represents a point on the surface of a sphere. (The Earth is almost + * spherical.)

+ * + *

To create an instance, call one of the static methods fromDegrees() or + * fromRadians().

+ * + *

This is a PHP port of Java code that was originally published at + * + * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java.

+ * + * Many thanks to the original author: Jan Philip Matuschek + * + * @author Anthony Martin + * @version November 21 2012 + */ +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 + } + + /** + * @param double $latitude the latitude, in degrees. + * @param double $longitude the longitude, in degrees. + * @return GeoLocation + */ + public 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 + */ + public 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"; + } + + + /** + *

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.

+ *

For more information about the formulae used in this method visit + * + * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates.

+ * + * @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: + */ + 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; + } +} + diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc012..58d20bd 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'AnthonyMartin' => array($vendorDir . '/anthonymartin/geo-location/src'), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index b700d49..0db90cb 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -55,5 +55,52 @@ "sql", "sqlite" ] + }, + { + "name": "anthonymartin/geo-location", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/anthonymartin/GeoLocation.php.git", + "reference": "a54a562dfe8ae3eef9a5863552401d26bc80e921" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/anthonymartin/GeoLocation.php/zipball/a54a562dfe8ae3eef9a5863552401d26bc80e921", + "reference": "a54a562dfe8ae3eef9a5863552401d26bc80e921", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2013-10-25 21:13:03", + "type": "class", + "installation-source": "dist", + "autoload": { + "psr-0": { + "AnthonyMartin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "CC 3.0" + ], + "authors": [ + { + "name": "Anthony Martin", + "email": "anthony@replaycreative.com", + "homepage": "http://replaycreative.com", + "role": "Developer" + } + ], + "description": "Retrieve bounding coordinates, distances, longitude and latitude with GeoLocation.class.php", + "homepage": "https://github.com/anthonymartin/GeoLocation.php", + "keywords": [ + "bounding coordinates", + "distances", + "geocoding", + "geolocation" + ] } ]