<?php
namespace League\Geotools;
use League\Geotools\BoundingBox\BoundingBox;
use League\Geotools\BoundingBox\BoundingBoxInterface;
use League\Geotools\Coordinate\Coordinate;
use League\Geotools\Coordinate\CoordinateCollection;
use League\Geotools\Coordinate\Ellipsoid;
use League\Geotools\Exception\InvalidArgumentException;
abstract class GeometryCollection extends ArrayCollection implements GeometryInterface
{
private $ellipsoid;
private $precision;
public function __construct(array $geometries = array(), ?Ellipsoid $ellipsoid = null)
{
$this->precision = -1;
$this->ellipsoid = $ellipsoid ? : null;
$this->checkGeometriesArray($geometries);
parent::__construct($geometries);
}
abstract public function getGeometryType();
public function getPrecision()
{
return $this->precision;
}
public function getCoordinate()
{
if ($this->isEmpty()) {
return null;
}
return $this->offsetGet(0)->getCoordinate();
}
public function getCoordinates()
{
$coordinates = new CoordinateCollection(array(), $this->ellipsoid);
foreach ($this->elements as $element) {
$coordinates = $coordinates->merge($element->getCoordinates());
}
return $coordinates;
}
public function isEmpty()
{
return count($this->elements) === 0 ;
}
public function getBoundingBox()
{
$boundingBox = new BoundingBox();
foreach ($this->elements as $element) {
$boundingBox = $boundingBox->merge($element->getBoundingBox());
}
return $boundingBox;
}
public function set($key, $value)
{
$this->checkEllipsoid($value);
$this->elements[$key] = $value;
}
public function add($value)
{
$this->checkEllipsoid($value);
$this->elements[] = $value;
return true;
}
public function getEllipsoid()
{
return $this->ellipsoid;
}
private function checkGeometriesArray(array $geometries)
{
foreach ($geometries as $geometry) {
if (!$geometry instanceof GeometryInterface) {
throw new InvalidArgumentException("You didn't provide a geometry!");
}
$this->checkEllipsoid($geometry);
}
}
private function checkEllipsoid(GeometryInterface $geometry)
{
if (bccomp($geometry->getPrecision(), $this->precision) === 1) {
$this->precision = $geometry->getPrecision();
}
if ($this->ellipsoid === null) {
$this->ellipsoid = $geometry->getEllipsoid();
} elseif ($geometry->isEmpty() || $geometry->getEllipsoid() != $this->ellipsoid) {
throw new InvalidArgumentException("Geometry is invalid");
}
}
public function merge(ArrayCollection $collection)
{
if (!$collection instanceof GeometryCollection || $collection->getGeometryType() !== $this->getGeometryType()) {
throw new InvalidArgumentException("Collections types don't match, you can't merge.");
}
return parent::merge($collection);
}
}