Created
November 4, 2021 23:46
-
-
Save eagle26/056c7d5e419ee347f31585db5d3543de to your computer and use it in GitHub Desktop.
PositionStack script to convert a free-text address or place to location data.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Class positionStack | |
* Forward Geocoding | |
* A simple class that uses the "positionstack" API to convert a free-text address or place to location data. | |
* To get an API token visit "https://positionstack.com/" | |
*/ | |
class positionStack{ | |
const API_KEY = 'YOUR_API_KEY'; | |
const API_URL = 'http://api.positionstack.com/v1/forward'; | |
const SECURE_API_URL = 'https://api.positionstack.com/v1/forward'; | |
private $_address; | |
private $_format = 'json'; | |
private $_limit = 1; | |
private $_secureRequest = false; // Only available in premium plans | |
public function __construct($address){ | |
$this->_address = $address; | |
} | |
/** | |
* It allows you to define if the request will use HTTP or HTTPs. | |
* The HTTPS Encryption is only available for premium plans on positionstack. | |
* @param bool $secure | |
*/ | |
public function setSecureRequest(bool $secure){ | |
$this->_secureRequest = $secure; | |
} | |
/** | |
* It allows you to set up the limit of the number of results returned per geocoding query | |
* @param int $limit | |
*/ | |
public function setResultsLimit(int $limit){ | |
$this->_limit = $limit; | |
} | |
/** | |
* It gets the Results in JSON format | |
* @return mixed | |
*/ | |
public function getResults(){ | |
return $this->getJSONOutput(); | |
} | |
/** | |
* It gets the Results in JSON format | |
* @return mixed | |
*/ | |
public function getJSONOutput(){ | |
$this->_format = 'json'; | |
return $this->_getAddressInfo(); | |
} | |
/** | |
* It gets the Results in XML format | |
* @return mixed | |
*/ | |
public function getXMLOutput(){ | |
$this->_format = 'xml'; | |
return $this->_getAddressInfo(); | |
} | |
/** | |
* It gets the Results in GeoJSON format | |
* @return mixed | |
*/ | |
public function getGeoJSONOutput(){ | |
$this->_format = 'geojson'; | |
return $this->_getAddressInfo(); | |
} | |
/** | |
* Do the query to the positionstack API and return the results | |
* @return mixed | |
* @throws RuntimeException | |
*/ | |
private function _getAddressInfo(){ | |
$queryString = http_build_query([ | |
'access_key' => self::API_KEY, | |
'query' => $this->_address, | |
'output' => $this->_format, | |
'limit' => $this->_limit, | |
]); | |
//Define if the request will use the secure URL or not. | |
$APIURL = ($this->_secureRequest ? self::SECURE_API_URL : self::API_URL); | |
//Do the request | |
$ch = curl_init(sprintf('%s?%s', $APIURL, $queryString)); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_FAILONERROR, false); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | |
curl_setopt($ch, CURLOPT_MAXREDIRS, 10); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 0); | |
curl_setopt($ch, CURLOPT_AUTOREFERER, true); | |
$result = curl_exec($ch); | |
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
// Verify if the response returns an error. If an error is detected an exception is thrown with the details. | |
if(!in_array($httpCode,[200,201,204])){ | |
$msg = "Unexpected Server Error"; | |
$code = $httpCode; | |
if(isset($result)){ | |
$result = json_decode($result, true); | |
if(array_key_exists('error', $result)){ | |
$error = $result['error']; | |
$msg = $error['message'] ?? $msg; | |
$code = $error['code'] ?? $code; | |
} | |
} | |
throw new \RuntimeException("[{$code}] {$msg}"); | |
} | |
curl_close($ch); | |
return ($this->_format === 'json' ? json_decode($result, true) : $result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment