Хочу поделиться своими наработками. так же хотелось доработать скрипт.
Если есть желающие, то подключайтесь. (хочу разложить адрес на составляющие, ещё было бы лучше анализировать все результаты с google и yandex и собрать максимальную информацию)
Хочу поделиться своими наработками. так же хотелось доработать скрипт.
Если есть желающие, то подключайтесь. (хочу разложить адрес на составляющие, ещё было бы лучше анализировать все результаты с google и yandex и собрать максимальную информацию)
Как это работает:
Размещаете файл geocoder на сервере/хостинге или на своё сервере apache с поддержкой PHP
Файл принимает как $_POST (отдельные параметры) так и тело JSON
Обязательные ключи:
Возвращаемое значение JSON (Ключи):
Содержание фала geocoder.php:
<?
# Получаем массив с заголовками headers
$headers = getallheaders();
# Определяем переменные по умолчанию для входящего JSON
$isJSON = false;
$php_input = null;
if (isset($headers['Content-Type'])) {
if ($headers['Content-Type'] = 'application/json') { # Проверяем заголовк на тип JSON
$php_input = file_get_contents('php://input'); # Получаем не обработанные данные
$isJSON = true; # Это JSON
}
}
# Генерируем массив для ответа
$result = array();
$result[msg] = 'Невозможно определить данный формат запроса';
if ($isJSON && $php_input != null) { # Если входящий запрос в формате JSON
$postJSON = json_decode($php_input, true);
$result[success] = true;
$result[msg] = 'Данные обработаны';
$result[query][type] = $postJSON['type'];
$result[query][api] = $postJSON['api'];
$result[query][name] = $postJSON['name'];
$result[query][lat] = (real) $postJSON['lat'];
$result[query][lng] = (real) $postJSON['lng'];
$result[query][key] = $postJSON['key'];
} else {
$result[success] = true;
$result[msg] = 'Данные обработаны';
$result[query][type] = $_POST['type'];
$result[query][api] = $_POST['api'];
$result[query][name] = $_POST['name'];
$result[query][lat] = (real) $_POST['lat'];
$result[query][lng] = (real) $_POST['lng'];
$result[query][key] = $_POST['key'];
}
# Проверяем сгенерированный ключ 'query'
if (array_key_exists('query', $result)) {
# Проверяем тип получаемых данных и какой api использовать
if (isset($result[query][type]) && isset($result[query][api])) {
# Используем API yandex
if ($result[query][api] == 'yandex') {
# Формируем тело запроса
if ($result[query][type] == 'LL') {
$query = $result[query][lng]. ',' .$result[query][lat];
} else if ($result[query][type] == 'address') {
$query = urlencode($result[query][name]);
}
# Выполняем запрос к серверу API
$geocoder = 'https://geocode-maps.yandex.ru/1.x/';
# 1. инициализация
$ch = curl_init(); # Создаем дескриптор cURL
# 2. устанавливаем опции, включая урл
curl_setopt($ch, CURLOPT_URL, $geocoder);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, "geocode=$query&format=json");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); # Устанавливаем параметр, чтобы curl возвращал данные, вместо того, чтобы выводить их в браузер.
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
# 3. выполнение запроса и получение ответа
$response = curl_exec($ch); # Запускаем
if ($response === FALSE) {
$result[success] = false;
$result[msg] = curl_error($ch);
} else {
# Если тело ответа не пустое
if (!empty($response)) {
# Преобразуем в массив
$json = json_decode($response, true);
# Устанавливаем ответ сервера
$result[response] = $json;
# Если результат является массивом
if (is_array($json)) {
$found = $json[response][GeoObjectCollection][featureMember];
$components = $found[0][GeoObject][metaDataProperty][GeocoderMetaData][Address];
$point = $found[0][GeoObject][Point][pos];
$pos = explode(' ', $point);
$address = array();
$address[address] = $components[formatted];
$address[lat] = (real) $pos[1];
$address[lng] = (real) $pos[0];
$result[data] = $address;
}
} else {
$result[success] = false;
$result[msg] = 'Пустой ответ сервера';
}
}
# 4. очистка ресурсов
curl_close($ch); # Закрываем дескриптор
}
# Используем API google
if ($result[query][api] == 'google') {
# Определяем тип запроса
if ($result[query][type] == 'LL') {
$query = 'latlng=';
$query .= $result[query][lat];
$query .= ',';
$query .= $result[query][lng];
$query .= '&key=';
$query .= $result[query][key];
$query .= '&language=ru';
}
# Определяем тип запроса
if ($result[query][type] == 'address') {
$query = 'address=';
$query .= urlencode($result[query][name]);
$query .= '&key=';
$query .= $result[query][key];
$query .= '&language=ru';
}
# Выполняем запрос к серверу API
$geocoder = 'https://maps.googleapis.com/maps/api/geocode/json'. '?' .$query;
# 1. инициализация
$ch = curl_init(); # Создаем дескриптор cURL
# 2. устанавливаем опции, включая урл
curl_setopt($ch, CURLOPT_URL, $geocoder);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); # Устанавливаем параметр, чтобы curl возвращал данные, вместо того, чтобы выводить их в браузер.
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
# 3. выполнение запроса и получение ответа
$response = curl_exec($ch); # Запускаем
if ($response === FALSE) {
$result[success] = false;
$result[msg] = curl_error($ch);
} else {
# Если тело ответа не пустое
if (!empty($response)) {
# Преобразуем в массив
$json = json_decode($response, true);
# Устанавливаем ответ сервера
$result[response] = $json;
# Если результат является массивом
if (is_array($json)) {
$components = $json[results][0];
$address = array();
$address[address] = $components[formatted_address];
$address[lat] = (real) $components[geometry][location][lat];
$address[lng] = (real) $components[geometry][location][lng];
$result[data] = $address;
}
} else {
$result[success] = false;
$result[msg] = 'Пустой ответ сервера';
}
}
# 4. очистка ресурсов
curl_close($ch); # Закрываем дескриптор
}
}
}
/* с этим я не стал пока разбираться, хотел разложить */
# Класс для работы с результатом JSON
class Response {
# GeoObject[]
protected $_list = array();
protected $_data;
public function __construct(array $data) {
$this->_data = $data;
if (isset($data['response']['GeoObjectCollection']['featureMember'])) {
foreach ($data['response']['GeoObjectCollection']['featureMember'] as $entry) {
$this->_list[] = new GeoObject($entry['GeoObject']);
}
}
}
# Исходные данные
public function getData() {
return $this->_data;
}
# GeoObject[]
public function getList() {
return $this->_list;
}
# @return null|GeoObject
public function getFirst() {
$result = null;
if (count($this->_list)) {
$result = $this->_list[0];
}
return $result;
}
# Возвращает исходный запрос
public function getQuery() {
$result = null;
if (isset($this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['request'])) {
$result = $this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['request'];
}
return $result;
}
# Кол-во найденных результатов
public function getFoundCount() {
$result = null;
if (isset($this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'])) {
$result = (int)$this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'];
}
return $result;
}
# Широта в градусах. Имеет десятичное представление с точностью до семи знаков после запятой
public function getLatitude() {
$result = null;
if (isset($this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['Point']['pos'])) {
list(,$latitude) = explode(' ', $this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['Point']['pos']);
$result = (float) $latitude;
}
return $result;
}
# Долгота в градусах. Имеет десятичное представление с точностью до семи знаков после запятой
public function getLongitude() {
$result = null;
if (isset($this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['Point']['pos'])) {
list($longitude,) = explode(' ', $this->_data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['Point']['pos']);
$result = (float)$longitude;
}
return $result;
}
}
# Дополнительный класс
class GeoObject {
protected $_addressHierarchy = [
'Country' => array('AdministrativeArea'),
'AdministrativeArea' => array('SubAdministrativeArea', 'Locality'),
'SubAdministrativeArea' => array('Locality'),
'Locality' => array('DependentLocality', 'Thoroughfare'),
'DependentLocality' => array('DependentLocality', 'Thoroughfare'),
'Thoroughfare' => array('Premise'),
'Premise' => array(),
];
protected $_data;
protected $_rawData;
public function __construct(array $rawData) {
$data = array(
'Address' => $rawData['metaDataProperty']['GeocoderMetaData']['text'],
'Kind' => $rawData['metaDataProperty']['GeocoderMetaData']['kind']
);
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];
$data['Latitude'] = (float)$pos[1];
}
$this->_data = $data;
$this->_rawData = $rawData;
}
public function __sleep() {
return array('_data');
}
# Необработанные данные
# @return array
public function getRawData() {
return $this->_rawData;
}
# Обработанные данные
# @return array
public function getData() {
return $this->_data;
}
# Широта в градусах. Имеет десятичное представление с точностью до семи знаков после запятой
# @return float|null
public function getLatitude() {
return isset($this->_data['Latitude']) ? $this->_data['Latitude'] : null;
}
# Долгота в градусах. Имеет десятичное представление с точностью до семи знаков после запятой
# @return float|null
public function getLongitude() {
return isset($this->_data['Longitude']) ? $this->_data['Longitude'] : null;
}
# Полный адрес
# @return string|null
public function getAddress() {
return isset($this->_data['Address']) ? $this->_data['Address'] : null;
}
# Тип
# @return string|null
public function getKind() {
return isset($this->_data['Kind']) ? $this->_data['Kind'] : null;
}
# Страна
# @return string|null
public function getCountry() {
return isset($this->_data['CountryName']) ? $this->_data['CountryName'] : null;
}
# Код страны
# @return string|null
public function getCountryCode() {
return isset($this->_data['CountryNameCode']) ? $this->_data['CountryNameCode'] : null;
}
# Административный округ
# @return string|null
public function getAdministrativeAreaName() {
return isset($this->_data['AdministrativeAreaName']) ? $this->_data['AdministrativeAreaName'] : null;
}
# Область/край
# @return string|null
public function getSubAdministrativeAreaName() {
return isset($this->_data['SubAdministrativeAreaName']) ? $this->_data['SubAdministrativeAreaName'] : null;
}
# Населенный пункт
# @return string|null
public function getLocalityName() {
return isset($this->_data['LocalityName']) ? $this->_data['LocalityName'] : null;
}
# @return string|null
public function getDependentLocalityName() {
return isset($this->_data['DependentLocalityName']) ? $this->_data['DependentLocalityName'] : null;
}
# Улица
# @return string|null
public function getThoroughfareName() {
return isset($this->_data['ThoroughfareName']) ? $this->_data['ThoroughfareName'] : null;
}
# Номер дома
# @return string|null
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';
if (isset($level[$nameProp])) {
$address[] = $level[$nameProp];
}
foreach ($this->_addressHierarchy[$levelName] as $child) {
if (!isset($level[$child])) {
continue;
}
$this->_parseLevel($level[$child], $child, $address);
}
return $address;
}
}
# Возвращаем результат
echo json_encode($result);
?>
получение данные из JavaScript
data = new FormData();
data.append('api', 'google');
data.append('type', 'address');
data.append('lat', $('#lat').val());
data.append('lng', $('#lng').val());
data.append('name', $('#name').val());
data.append('key', 'lkjahfjghjahljkfhadshfljkasd-5wFhzayGf0');
$.ajax({
type: 'POST',
method: 'POST',
url: '/api/geocoder',
headers: {'Cache-Control': 'no-cache'},
data: data,
dataType: 'json',
contentType: false,
processData: false,
cache: false,
success: function(response) {
/* response - Это JS объект*/
process_the_answer_of_a_geo_server(response);
}
});
Получение данных из 1С 8.3
&НаКлиенте
Процедура ПолучитьДанные(Команда)
Данные = Новый Структура;
Данные.Вставить("api", "google");
Данные.Вставить("type", "address");
Данные.Вставить("lat", "");
Данные.Вставить("lng", "");
Данные.Вставить("name", "105120, Москва г, Мрузовский пер");
Данные.Вставить("key", "lkjbhfsdkjhgkjsdfhgjhlsdfhgjfdsl");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Данные);
JSON = ЗаписьJSON.Закрыть();
Соединение = Новый HTTPСоединение("eta.api", 8080);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Запрос = Новый HTTPЗапрос("/api/geocoder", Заголовки);
Запрос.УстановитьТелоИзСтроки(JSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Результат = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
СообщениеПользователю = Новый СообщениеПользователю;
СообщениеПользователю.Текст = Результат;
СообщениеПользователю.Сообщить();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Результат);
Параметр = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
КонецПроцедуры
Да и в каталоге где лежит файл geocoder.php там я ещё файл такой создал .htaccess
содержание .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}
!-f RewriteRule ^([^\.]+)$ $1.php [NC,L]"
Это я вызываю его без расширения *.php