geolocation-8.x-3.x-dev/modules/geolocation_geometry/src/GeometryFormat/KML.php

modules/geolocation_geometry/src/GeometryFormat/KML.php
<?php

namespace Drupal\geolocation_geometry\GeometryFormat;

use Drupal\geolocation_geometry\GeometryType\GeometryCollection;
use Drupal\geolocation_geometry\GeometryType\GeometryTypeInterface;
use Drupal\geolocation_geometry\GeometryType\LineString;
use Drupal\geolocation_geometry\GeometryType\LinearRing;
use Drupal\geolocation_geometry\GeometryType\MultiLineString;
use Drupal\geolocation_geometry\GeometryType\MultiPoint;
use Drupal\geolocation_geometry\GeometryType\MultiPolygon;
use Drupal\geolocation_geometry\GeometryType\Point;
use Drupal\geolocation_geometry\GeometryType\Polygon;

/**
 * KML format type.
 */
class KML extends XML implements GeometryFormatInterface { // phpcs:ignore

  /**
   * {@inheritdoc}
   */
  public static function geometryByXML(?\SimpleXMLElement $xml = NULL): ?GeometryTypeInterface {

    switch (strtolower($xml->getName())) {
      case "kml":
      case "document":
      case "placemark":
        return static::parseChildren($xml);

      case "point":
        return new Point(static::parsePoint($xml));

      case "linestring":
        return new LineString(static::parseLineString($xml));

      case "linearring":
        return new LinearRing(static::parseLinearRing($xml));

      case "polygon":
        return new Polygon(static::parsePolygon($xml));

      case "multigeometry":
        $components = static::parseMultiGeometry($xml);

        if (count($components)) {
          $possibletype = $components[0]::TYPE;
          $sametype = TRUE;
          foreach (array_slice($components, 1) as $component) {
            if ($component::TYPE != $possibletype) {
              $sametype = FALSE;
              break;
            }
          }
          if ($sametype) {
            switch ($possibletype) {
              case "Point":
                return new MultiPoint($components);

              case "LineString":
                return new MultiLineString($components);

              case "Polygon":
                return new MultiPolygon($components);

              default:
                break;
            }
          }
        }
        return new GeometryCollection($components);

      default:
        return NULL;
    }
  }

  /**
   * Parse point.
   *
   * @param \SimpleXMLElement $xml
   *   XML.
   *
   * @return array
   *   Coordinates.
   */
  protected static function parsePoint(\SimpleXMLElement $xml): array {
    $coordinates = static::extractCoordinates($xml);

    $coords = explode(',', $coordinates[0]);
    return array_map("trim", $coords);
  }

  /**
   * Parse Line String.
   *
   * @param \SimpleXMLElement $xml
   *   XML.
   *
   * @return array
   *   Components.
   */
  protected static function parseLineString(\SimpleXMLElement $xml): array {
    $components = [];
    $coordinates = static::extractCoordinates($xml);
    foreach (preg_split('/\s+/', trim((string) $coordinates[0])) as $compstr) {
      $coords = explode(',', $compstr);
      $components[] = new Point($coords);
    }
    return $components;
  }

  /**
   * Parse Linear Ring.
   *
   * @param \SimpleXMLElement $xml
   *   XML.
   *
   * @return array
   *   Components.
   */
  protected static function parseLinearRing(\SimpleXMLElement $xml): array {
    return static::parseLineString($xml);
  }

  /**
   * Parse Polygon.
   *
   * @param \SimpleXMLElement $xml
   *   XML.
   *
   * @return array
   *   Components.
   */
  protected static function parsePolygon(\SimpleXMLElement $xml): array {
    $ring = [];
    foreach (static::childElements($xml, 'outerboundaryis') as $elem) {
      $ring = array_merge($ring, static::childElements($elem, 'linearring'));
    }

    if (count($ring) != 1) {
      throw new \Exception("Could not parse Geometry");
    }

    $components = [new LinearRing(static::parseLinearRing($ring[0]))];
    foreach (static::childElements($xml, 'innerboundaryis') as $elem) {
      foreach (static::childElements($elem, 'linearring') as $ring) {
        $components[] = new LinearRing(static::parseLinearRing($ring[0]));
      }
    }
    return $components;
  }

  /**
   * Parse Multi Geometry.
   *
   * @param \SimpleXMLElement $xml
   *   XML.
   *
   * @return array
   *   Components.
   */
  protected static function parseMultiGeometry(\SimpleXMLElement $xml): array {
    $components = [];
    foreach ($xml->children() as $child) {
      $components[] = static::geometryByXML($child);
    }
    return $components;
  }

  /**
   * Extract Coordinates.
   *
   * @param \SimpleXMLElement $xml
   *   XML.
   *
   * @return array
   *   Coordinates.
   */
  protected static function extractCoordinates(\SimpleXMLElement $xml): array {
    $coordinates = static::childElements($xml, 'coordinates');
    if (count($coordinates) != 1) {
      throw new \Exception("Could not parse Geometry");
    }
    return $coordinates;
  }

}

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

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