geolocation-8.x-3.x-dev/modules/geolocation_geometry/src/Plugin/geolocation/DataProvider/GeolocationGeometry.php

modules/geolocation_geometry/src/Plugin/geolocation/DataProvider/GeolocationGeometry.php
<?php

namespace Drupal\geolocation_geometry\Plugin\geolocation\DataProvider;

use Drupal\geolocation\Attribute\DataProvider;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\geolocation\DataProviderBase;
use Drupal\geolocation\DataProviderInterface;
use Drupal\views\Plugin\views\field\EntityField;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\ResultRow;

/**
 * Provides GPX.
 */
#[DataProvider(
  id: 'geolocation_geometry',
  name: new \Drupal\Core\StringTranslation\TranslatableMarkup('Geolocation Geometry'),
  description: new \Drupal\Core\StringTranslation\TranslatableMarkup('Points, Polygons, Polyines.')
)]
class GeolocationGeometry extends DataProviderBase implements DataProviderInterface {

  /**
   * {@inheritdoc}
   */
  protected static function defaultSettings(): array {
    $settings = parent::defaultSettings();

    $settings['color_randomize'] = TRUE;

    $settings['stroke_color'] = '#FF0044';
    $settings['stroke_width'] = 1;
    $settings['stroke_opacity'] = 0.9;

    $settings['fill_color'] = '#0033FF';
    $settings['fill_opacity'] = 0.2;

    return $settings;

  }

  /**
   * {@inheritdoc}
   */
  public function isViewsGeoOption(FieldPluginBase $viewsField): bool {
    if (
      $viewsField instanceof EntityField
      && $viewsField->getPluginId() == 'field'
    ) {
      $field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($viewsField->getEntityType());
      if (!empty($field_storage_definitions[$viewsField->field])) {
        $field_storage_definition = $field_storage_definitions[$viewsField->field];

        if (in_array($field_storage_definition->getType(), [
          'geolocation_geometry_geometry',
          'geolocation_geometry_geometrycollection',
          'geolocation_geometry_point',
          'geolocation_geometry_linestring',
          'geolocation_geometry_polygon',
          'geolocation_geometry_multipoint',
          'geolocation_geometry_multilinestring',
          'geolocation_geometry_multipolygon',
        ])) {
          return TRUE;
        }
      }
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function getSettingsForm(array $settings, array $parents = []): array {
    $element = parent::getSettingsForm($settings, $parents);

    $settings = $this->getSettings($settings);

    $element['color_randomize'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Randomize colors'),
      '#description' => $this->t('Set stroke and fill color to the same random value. Enabling ignores any set specific color values.'),
      '#default_value' => $settings['color_randomize'],
    ];

    $element['stroke_color'] = [
      '#type' => 'color',
      '#title' => $this->t('Stroke color'),
      '#default_value' => $settings['stroke_color'],
    ];

    $element['stroke_width'] = [
      '#type' => 'number',
      '#title' => $this->t('Stroke Width'),
      '#description' => $this->t('Width of the stroke in pixels.'),
      '#default_value' => $settings['stroke_width'],
    ];

    $element['stroke_opacity'] = [
      '#type' => 'number',
      '#step' => 0.01,
      '#title' => $this->t('Stroke Opacity'),
      '#description' => $this->t('Opacity of the stroke from 1 = fully visible, 0 = complete see through.'),
      '#default_value' => $settings['stroke_opacity'],
    ];

    $element['fill_color'] = [
      '#type' => 'color',
      '#title' => $this->t('Fill color'),
      '#default_value' => $settings['fill_color'],
    ];

    $element['fill_opacity'] = [
      '#type' => 'number',
      '#step' => 0.01,
      '#title' => $this->t('Fill Opacity'),
      '#description' => $this->t('Opacity of the polygons from 1 = fully visible, 0 = complete see through.'),
      '#default_value' => $settings['fill_opacity'],
    ];

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function getLocationsFromViewsRow(ResultRow $row, ?FieldPluginBase $viewsField = NULL): array {
    $locations = parent::getLocationsFromViewsRow($row, $viewsField);

    $current_style = $viewsField->displayHandler->getPlugin('style');

    if (!is_subclass_of($current_style, 'Drupal\geolocation\Plugin\views\style\GeolocationStyleBase')) {
      return $locations;
    }

    foreach ($locations as &$location) {
      if (!is_array($location)) {
        continue;
      }
      $location['#title'] = $current_style->getTitleField($row);
      $location['#label'] = $current_style->getLabelField($row);
    }

    return $locations;
  }

  /**
   * {@inheritdoc}
   */
  public function getShapesFromViewsRow(ResultRow $row, ?FieldPluginBase $viewsField = NULL): array {
    $shapes = parent::getShapesFromViewsRow($row, $viewsField);

    if (empty($shapes)) {
      return $shapes;
    }

    $current_style = $viewsField->displayHandler->getPlugin('style');

    if (!is_subclass_of($current_style, 'Drupal\geolocation\Plugin\views\style\GeolocationStyleBase')) {
      return $shapes;
    }

    foreach ($shapes as &$shape) {
      if (!is_array($shape)) {
        continue;
      }
      $shape['#title'] = $current_style->getTitleField($row);
    }

    return $shapes;
  }

  /**
   * {@inheritdoc}
   */
  public function getShapesFromItem(FieldItemInterface $fieldItem): array {
    $settings = $this->getSettings();

    $shapes = [];

    foreach ($this->getShapeGeometriesFromGeoJson($fieldItem->get('geojson')->getString()) as $geometry) {
      $shapes[] = self::getRenderedElementByGeoJSON($geometry, $settings);
    }

    return $shapes;
  }

  /**
   * {@inheritdoc}
   */
  public function getLocationsFromItem(FieldItemInterface $fieldItem): array {
    $settings = $this->getSettings();

    $locations = [];

    foreach ($this->getLocationGeometriesFromGeoJson($fieldItem->get('geojson')->getString()) as $geometry) {
      $locations[] = self::getRenderedElementByGeoJSON($geometry, $settings);
    }

    return $locations;
  }

  /**
   * Get render element.
   *
   * @param object $geojson
   *   GeoJSON.
   * @param array|null $settings
   *   Optional settings.
   *
   * @return array
   *   Render Element.
   */
  public static function getRenderedElementByGeoJSON(object $geojson, ?array $settings = NULL): array {
    $settings = $settings ?? self::defaultSettings();

    if (!isset($settings['stroke_width'])) {
      $settings['stroke_width'] = self::defaultSettings()['stroke_width'];
    }
    if (!isset($settings['stroke_opacity'])) {
      $settings['stroke_opacity'] = self::defaultSettings()['stroke_opacity'];
    }
    if (!isset($settings['fill_opacity'])) {
      $settings['fill_opacity'] = self::defaultSettings()['fill_opacity'];
    }

    $random_color = sprintf('#%06X', mt_rand(0, 0xFFFFFF));
    switch ($geojson->type) {
      case 'Point':
        return [
          '#type' => 'geolocation_map_location',
          '#coordinates' => [
            'lat' => $geojson->coordinates[1],
            'lng' => $geojson->coordinates[0],
          ],
        ];

      case 'MultiPoint':
        $container = [
          '#type' => 'container',
          '#attributes' => [
            'class' => [
              'geolocation-multipoint',
            ],
          ],
        ];
        foreach ($geojson->coordinates as $key => $point) {
          $position = [
            '#type' => 'geolocation_map_location',
            '#coordinates' => [
              'lat' => $point->coordinates[1],
              'lng' => $point->coordinates[0],
            ],
          ];
          $container[$key] = $position;
        }
        return $container;

      case 'Polygon':
        return [
          '#type' => 'geolocation_map_shape',
          '#geometry' => json_encode($geojson),
          '#geometry_type' => 'polygon',
          '#stroke_color' => $settings['color_randomize'] ? $random_color : $settings['stroke_color'],
          '#stroke_width' => (int) $settings['stroke_width'],
          '#stroke_opacity' => (float) $settings['stroke_opacity'],
          '#fill_color' => $settings['color_randomize'] ? $random_color : $settings['fill_color'],
          '#fill_opacity' => (float) $settings['fill_opacity'],
        ];

      case 'MultiPolygon':
        return [
          '#type' => 'geolocation_map_shape',
          '#geometry' => json_encode($geojson),
          '#geometry_type' => 'multipolygon',
          '#stroke_color' => $settings['color_randomize'] ? $random_color : $settings['stroke_color'],
          '#stroke_width' => (int) $settings['stroke_width'],
          '#stroke_opacity' => (float) $settings['stroke_opacity'],
          '#fill_color' => $settings['color_randomize'] ? $random_color : $settings['fill_color'],
          '#fill_opacity' => (float) $settings['fill_opacity'],
        ];

      case 'LineString':
        return [
          '#type' => 'geolocation_map_shape',
          '#geometry' => json_encode($geojson),
          '#geometry_type' => 'line',
          '#stroke_color' => $settings['color_randomize'] ? $random_color : $settings['stroke_color'],
          '#stroke_width' => (int) $settings['stroke_width'],
          '#stroke_opacity' => (float) $settings['stroke_opacity'],
        ];

      case 'MultiLineString':
        return [
          '#type' => 'geolocation_map_shape',
          '#geometry' => json_encode($geojson),
          '#geometry_type' => 'multiline',
          '#stroke_color' => $settings['color_randomize'] ? $random_color : $settings['stroke_color'],
          '#stroke_width' => (int) $settings['stroke_width'],
          '#stroke_opacity' => (float) $settings['stroke_opacity'],
        ];

      default:
        return [];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function isFieldGeoOption(FieldDefinitionInterface $fieldDefinition): bool {
    return (in_array($fieldDefinition->getType(), [
      'geolocation_geometry_geometry',
      'geolocation_geometry_geometrycollection',
      'geolocation_geometry_point',
      'geolocation_geometry_linestring',
      'geolocation_geometry_polygon',
      'geolocation_geometry_multipoint',
      'geolocation_geometry_multilinestring',
      'geolocation_geometry_multipolygon',
    ]));
  }

  /**
   * Get Shapes from GeoJSON.
   *
   * @param string $geoJson
   *   GeoJSON.
   *
   * @return array
   *   Shapes.
   */
  protected function getShapeGeometriesFromGeoJson(string $geoJson): array {
    $geometries = [];

    $json = json_decode($geoJson);

    if (
      is_object($json)
      && isset($json->type)
    ) {
      $json = [$json];
    }

    foreach ($json as $entry) {
      if (empty($entry->type)) {
        continue;
      }
      switch ($entry->type) {
        case 'FeatureCollection':
          if (empty($entry->features)) {
            continue 2;
          }
          $geometries = array_merge($geometries, $this->getShapeGeometriesFromGeoJson(is_string($entry->features) ?: json_encode($entry->features)));
          break;

        case 'Feature':
          if (empty($entry->geometry)) {
            continue 2;
          }
          $geometries = array_merge($geometries, $this->getShapeGeometriesFromGeoJson(is_string($entry->geometry) ?: json_encode($entry->geometry)));
          break;

        case 'GeometryCollection':
          if (empty($entry->geometries)) {
            continue 2;
          }
          $geometries = array_merge($geometries, $this->getShapeGeometriesFromGeoJson(is_string($entry->geometries) ?: json_encode($entry->geometries)));
          break;

        case 'MultiPolygon':
        case 'Polygon':
        case 'MultiLineString':
        case 'LineString':
          if (empty($entry->coordinates)) {
            continue 2;
          }
          $geometries[] = $entry;
          break;
      }
    }

    return $geometries;
  }

  /**
   * Get Locations from GeoJSON.
   *
   * @param string $geoJson
   *   GeoJSON.
   *
   * @return array
   *   Locations.
   */
  protected function getLocationGeometriesFromGeoJson(string $geoJson): array {
    $geometries = [];

    $json = json_decode($geoJson);

    if (
      is_object($json)
      && isset($json->type)
    ) {
      $json = [$json];
    }

    foreach ($json as $entry) {
      if (empty($entry->type)) {
        continue;
      }
      switch ($entry->type) {
        case 'FeatureCollection':
          if (empty($entry->features)) {
            continue 2;
          }
          $geometries = array_merge($geometries, $this->getLocationGeometriesFromGeoJson(is_string($entry->features) ?: json_encode($entry->features)));
          break;

        case 'Feature':
          if (empty($entry->geometry)) {
            continue 2;
          }
          $geometries = array_merge($geometries, $this->getLocationGeometriesFromGeoJson(is_string($entry->geometry) ?: json_encode($entry->geometry)));
          break;

        case 'GeometryCollection':
          if (empty($entry->geometries)) {
            continue 2;
          }
          $geometries = array_merge($geometries, $this->getLocationGeometriesFromGeoJson(is_string($entry->geometries) ?: json_encode($entry->geometries)));
          break;

        case 'MultiPoint':
        case 'Point':
          if (empty($entry->coordinates)) {
            continue 2;
          }
          $geometries[] = $entry;
          break;
      }
    }

    return $geometries;
  }

}

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

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