From 34ae5e3de804217fe5519b3381c56982d8b9d548 Mon Sep 17 00:00:00 2001 From: Dmitry Kuznetsov Date: Sun, 10 Apr 2016 12:34:08 +0000 Subject: [PATCH] Added methods GeoObject::getFullAddressParts(), Response::getFirst(), fixed Api::load() method --- source/Yandex/Geo/Api.php | 19 ++++-- source/Yandex/Geo/Exception.php | 1 - source/Yandex/Geo/Exception/CurlError.php | 1 - source/Yandex/Geo/Exception/ServerError.php | 1 - source/Yandex/Geo/GeoObject.php | 75 +++++++++++++++++++-- source/Yandex/Geo/Response.php | 14 +++- 6 files changed, 97 insertions(+), 14 deletions(-) diff --git a/source/Yandex/Geo/Api.php b/source/Yandex/Geo/Api.php index 899988e..deefa7b 100644 --- a/source/Yandex/Geo/Api.php +++ b/source/Yandex/Geo/Api.php @@ -4,7 +4,6 @@ /** * Class Api * @package Yandex\Geo - * @author Dmitry Kuznetsov * @license The MIT License (MIT) * @see http://api.yandex.ru/maps/doc/geocoder/desc/concepts/About.xml */ @@ -56,12 +55,23 @@ public function __construct($version = null) $this->clear(); } - public function load() + /** + * @param array $options Curl options + * @return $this + * @throws Exception + * @throws Exception\CurlError + * @throws Exception\ServerError + */ + public function load(array $options = []) { $apiUrl = sprintf('https://geocode-maps.yandex.ru/%s/?%s', $this->_version, http_build_query($this->_filters)); $curl = curl_init($apiUrl); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_HTTPGET, 1); + $options += array( + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_HTTPGET => 1, + CURLOPT_FOLLOWLOCATION => 1, + ); + curl_setopt_array($curl, $options); $data = curl_exec($curl); $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); if (curl_errno($curl)) { @@ -80,6 +90,7 @@ public function load() } $this->_response = new \Yandex\Geo\Response($data); + return $this; } diff --git a/source/Yandex/Geo/Exception.php b/source/Yandex/Geo/Exception.php index 2cd83e4..819efb3 100644 --- a/source/Yandex/Geo/Exception.php +++ b/source/Yandex/Geo/Exception.php @@ -4,7 +4,6 @@ /** * Class Exception * @package Yandex\Geo - * @author Dmitry Kuznetsov * @license The MIT License (MIT) */ class Exception extends \Exception diff --git a/source/Yandex/Geo/Exception/CurlError.php b/source/Yandex/Geo/Exception/CurlError.php index 120f572..6abe478 100644 --- a/source/Yandex/Geo/Exception/CurlError.php +++ b/source/Yandex/Geo/Exception/CurlError.php @@ -4,7 +4,6 @@ /** * Class CurlError * @package Yandex\Geo\Exception - * @author Dmitry Kuznetsov * @license The MIT License (MIT) */ class CurlError extends \Yandex\Geo\Exception diff --git a/source/Yandex/Geo/Exception/ServerError.php b/source/Yandex/Geo/Exception/ServerError.php index d718a07..8699d41 100644 --- a/source/Yandex/Geo/Exception/ServerError.php +++ b/source/Yandex/Geo/Exception/ServerError.php @@ -4,7 +4,6 @@ /** * Class ServerError * @package Yandex\Geo\Exception - * @author Dmitry Kuznetsov * @license The MIT License (MIT) */ class ServerError extends \Yandex\Geo\Exception diff --git a/source/Yandex/Geo/GeoObject.php b/source/Yandex/Geo/GeoObject.php index c7dc671..e293a83 100644 --- a/source/Yandex/Geo/GeoObject.php +++ b/source/Yandex/Geo/GeoObject.php @@ -4,11 +4,19 @@ /** * Class GeoObject * @package Yandex\Geo - * @author Dmitry Kuznetsov * @license The MIT License (MIT) */ class GeoObject { + protected $_addressHierarchy = [ + 'Country' => array('AdministrativeArea'), + 'AdministrativeArea' => array('SubAdministrativeArea'), + 'SubAdministrativeArea' => array('Locality'), + 'Locality' => array('DependentLocality', 'Thoroughfare'), + 'DependentLocality' => array('DependentLocality', 'Thoroughfare'), + 'Thoroughfare' => array('Premise'), + 'Premise' => array(), + ]; protected $_data; protected $_rawData; @@ -17,11 +25,26 @@ public function __construct(array $rawData) $data = array( 'Address' => $rawData['metaDataProperty']['GeocoderMetaData']['text'], ); - array_walk_recursive($rawData, function($value, $key) use(&$data) { - if (in_array($key, array('CountryName', 'CountryNameCode', 'AdministrativeAreaName', 'SubAdministrativeAreaName', 'LocalityName', 'DependentLocalityName', 'ThoroughfareName', 'PremiseNumber'))) { - $data[$key] = $value; + array_walk_recursive( + $rawData, + function ($value, $key) use (&$data) { + if (in_array( + $key, + array( + 'CountryName', + 'CountryNameCode', + 'AdministrativeAreaName', + 'SubAdministrativeAreaName', + 'LocalityName', + 'DependentLocalityName', + 'ThoroughfareName', + 'PremiseNumber', + ) + )) { + $data[$key] = $value; + } } - }); + ); if (isset($rawData['Point']['pos'])) { $pos = explode(' ', $rawData['Point']['pos']); $data['Longitude'] = (float)$pos[0]; @@ -44,7 +67,7 @@ public function getRawData() { return $this->_rawData; } - + /** * Обработанные данные * @return array @@ -151,4 +174,44 @@ public function getPremiseNumber() { return isset($this->_data['PremiseNumber']) ? $this->_data['PremiseNumber'] : null; } + + /** + * Полный адрес + * @return array + */ + public function getFullAddressParts() + { + return array_unique( + $this->_parseLevel( + $this->_rawData['metaDataProperty']['GeocoderMetaData']['AddressDetails']['Country'], + 'Country' + ) + ); + } + + /** + * + * @param array $level + * @param String $levelName + * @param array $address + * @return array + */ + protected function _parseLevel(array $level, $levelName, &$address = []) + { + if (!isset($this->_addressHierarchy[$levelName])) { + return; + } + + $nameProp = $levelName === 'Premise' ? 'PremiseNumber' : $levelName.'Name'; + $address[] = $level[$nameProp]; + + foreach ($this->_addressHierarchy[$levelName] as $child) { + if (!isset($level[$child])) { + continue; + } + $this->_parseLevel($level[$child], $child, $address); + } + + return $address; + } } diff --git a/source/Yandex/Geo/Response.php b/source/Yandex/Geo/Response.php index 6b6a8be..1359f6d 100644 --- a/source/Yandex/Geo/Response.php +++ b/source/Yandex/Geo/Response.php @@ -4,7 +4,6 @@ /** * Class Response * @package Yandex\Geo - * @author Dmitry Kuznetsov * @license The MIT License (MIT) */ class Response @@ -45,6 +44,19 @@ public function getList() return $this->_list; } + /** + * @return null|GeoObject + */ + public function getFirst() + { + $result = null; + if (count($this->_list)) { + $result = $this->_list[0]; + } + + return $result; + } + /** * Возвращает исходный запрос * @return string|null