geolocation-8.x-3.x-dev/modules/geolocation_yandex/src/Plugin/geolocation/Geocoder/Yandex.php

modules/geolocation_yandex/src/Plugin/geolocation/Geocoder/Yandex.php
<?php

namespace Drupal\geolocation_yandex\Plugin\geolocation\Geocoder;

use Drupal\geolocation\Attribute\Geocoder;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\geolocation\GeocoderBase;
use Drupal\geolocation\GeocoderInterface;
use Drupal\geolocation_yandex\Plugin\geolocation\MapProvider\Yandex as YandexMapProvider;
use GuzzleHttp\Exception\RequestException;

/**
 * Provides the Yandex.
 */
#[Geocoder(
  id: 'yandex',
  name: new \Drupal\Core\StringTranslation\TranslatableMarkup('Yandex'),
  description: new \Drupal\Core\StringTranslation\TranslatableMarkup('See https://tech.yandex.com/maps/doc/geocoder/desc/concepts/about-docpage/ for details.'),
  locationCapable: TRUE,
  boundaryCapable: TRUE,
  frontendCapable: TRUE
)]
class Yandex extends GeocoderBase implements GeocoderInterface {

  /**
   * {@inheritdoc}
   */
  public function alterRenderArray(array &$render_array, $identifier): ?array {
    parent::alterRenderArray($render_array, $identifier);

    $render_array['#attached'] = BubbleableMetadata::mergeAttachments(
      $render_array['#attached'] ?? [],
      [
        'drupalSettings' => [
          'geolocation' => [
            'geocoder' => [
              $this->getPluginId() => [],
            ],
          ],
        ],
      ]
    );

    return $render_array;
  }

  /**
   * {@inheritdoc}
   */
  public function geocode($address): ?array {
    if (empty($address)) {
      return NULL;
    }

    $config = \Drupal::config('geolocation_yandex.settings');

    $url = Url::fromUri('https://geocode-maps.yandex.ru/1.x/', [
      'query' => [
        'geocode' => $address,
        'format' => 'json',
        'apikey' => $config->get('api_key'),
        'lang' => YandexMapProvider::getApiUrlLangcode(),
      ],
    ]);

    try {
      $result = Json::decode(\Drupal::httpClient()->get($url->toString())->getBody());
    }
    catch (RequestException $e) {
      $logger = \Drupal::logger('geolocation');
      Error::logException($logger, $e);
      return NULL;
    }

    $location = [];

    if (empty($result['response']['GeoObjectCollection']['featureMember'][0])) {
      return NULL;
    }
    else {
      $coordinates = explode(' ', $result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos']);
      $location['location'] = [
        'lat' => $coordinates[1],
        'lng' => $coordinates[0],
      ];
    }

    if (!empty($result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['boundedBy']['Envelope'])) {
      $lowerCoordinates = explode(' ', $result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['boundedBy']['Envelope']['lowerCorner']);
      $upperCoordinates = explode(' ', $result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['boundedBy']['Envelope']['upperCorner']);
      $location['boundary'] = [
        'lat_north_east' => $upperCoordinates[1],
        'lng_north_east' => $upperCoordinates[0],
        'lat_south_west' => $lowerCoordinates[1],
        'lng_south_west' => $lowerCoordinates[0],
      ];
    }

    if (!empty($result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['description'])) {
      $location['address'] = $result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['description'];
    }

    return $location;
  }

  /**
   * {@inheritdoc}
   */
  public function reverseGeocode(float $latitude, float $longitude): ?array {
    $config = \Drupal::config('geolocation_yandex.settings');

    $url = Url::fromUri('https://geocode-maps.yandex.ru/1.x/', [
      'query' => [
        'geocode' => $longitude . "," . $latitude,
        'format' => 'json',
        'apikey' => $config->get('api_key'),
        'lang' => YandexMapProvider::getApiUrlLangcode(),
      ],
    ]);

    try {
      $result = Json::decode(\Drupal::httpClient()->get($url->toString())->getBody());
    }
    catch (RequestException $e) {
      $logger = \Drupal::logger('geolocation');
      Error::logException($logger, $e);
      return NULL;
    }

    if (empty($result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject'])) {
      return NULL;
    }

    $data = $result['response']['GeoObjectCollection']['featureMember'][0]['GeoObject'];

    // @todo $data['boundedBy']
    // @todo $data['Point']['pos']
    if (empty($data['metaDataProperty']['GeocoderMetaData']['Address']['Components'])) {
      return NULL;
    }

    $address_atomics = [
      'countryCode' => mb_strtolower($data['metaDataProperty']['GeocoderMetaData']['Address']['country_code']),
      'formatted_address' => $data['metaDataProperty']['GeocoderMetaData']['Address']['formatted'],
    ];

    foreach ($data['metaDataProperty']['GeocoderMetaData']['Address']['Components'] as $component) {
      switch ($component['kind']) {
        case 'country':
          $address_atomics['country'] = $component['name'];
          break;

        case 'province':
          $address_atomics['administrative_area'] = $component['name'];
          break;

        case 'locality':
          $address_atomics['locality'] = $component['name'];
          break;

        case 'street':
          $address_atomics['street'] = $component['name'];
          break;

        case 'house':
          $address_atomics['number'] = $component['name'];
          break;

      }
    }

    return [
      'atomics' => $address_atomics,
      'elements' => $this->addressElements($address_atomics),
      'formatted_address' => empty($result['display_name']) ? '' : $result['display_name'],
    ];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc