2024-02-16 15:35:01 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PHP Shapefile - PHP library to read and write ESRI Shapefiles, compatible with WKT and GeoJSON
|
|
|
|
*
|
|
|
|
* @package Shapefile
|
|
|
|
* @author Gaspare Sganga
|
2024-03-13 12:03:56 +01:00
|
|
|
* @version 4.0.0dev
|
2024-02-16 15:35:01 +01:00
|
|
|
* @license MIT
|
|
|
|
* @link https://gasparesganga.com/labs/php-shapefile/
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Shapefile\Geometry;
|
|
|
|
|
|
|
|
use Shapefile\Shapefile;
|
|
|
|
use Shapefile\ShapefileException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Abstract base class for all Geometry Collections.
|
|
|
|
* It defines some common public methods and some helper protected functions.
|
|
|
|
*/
|
|
|
|
abstract class GeometryCollection extends Geometry
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var \Shapefile\Geometry\Geometry[] The actual geometries in the collection.
|
|
|
|
* They are enforced to be all of the same type by addGeometry() method.
|
|
|
|
*/
|
|
|
|
protected $geometries = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////// ABSTRACT ///////////////////////////////
|
|
|
|
/**
|
|
|
|
* Gets the class name of the base geometries in the collection.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
abstract protected function getCollectionClass();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////// PUBLIC ///////////////////////////////
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param \Shapefile\Geometry\Geometry[] $geometries Optional array of geometries to initialize the collection.
|
|
|
|
*/
|
|
|
|
public function __construct(array $geometries = null)
|
|
|
|
{
|
|
|
|
if ($geometries !== null) {
|
|
|
|
foreach ($geometries as $Geometry) {
|
|
|
|
$this->addGeometry($Geometry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function getBoundingBox()
|
|
|
|
{
|
|
|
|
if ($this->isEmpty()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
$ret = $this->getCustomBoundingBox();
|
|
|
|
if (!$ret) {
|
|
|
|
$is_z = $this->isZ();
|
|
|
|
$is_m = $this->isM();
|
|
|
|
foreach ($this->geometries as $Geometry) {
|
|
|
|
$bbox = $Geometry->getBoundingBox();
|
|
|
|
if (!$ret) {
|
|
|
|
$ret = $bbox;
|
|
|
|
} elseif ($bbox) {
|
|
|
|
if ($bbox['xmin'] < $ret['xmin']) {
|
|
|
|
$ret['xmin'] = $bbox['xmin'];
|
|
|
|
}
|
|
|
|
if ($bbox['xmax'] > $ret['xmax']) {
|
|
|
|
$ret['xmax'] = $bbox['xmax'];
|
|
|
|
}
|
|
|
|
if ($bbox['ymin'] < $ret['ymin']) {
|
|
|
|
$ret['ymin'] = $bbox['ymin'];
|
|
|
|
}
|
|
|
|
if ($bbox['ymax'] > $ret['ymax']) {
|
|
|
|
$ret['ymax'] = $bbox['ymax'];
|
|
|
|
}
|
|
|
|
if ($is_z) {
|
|
|
|
if ($bbox['zmin'] < $ret['zmin']) {
|
|
|
|
$ret['zmin'] = $bbox['zmin'];
|
|
|
|
}
|
|
|
|
if ($bbox['zmax'] > $ret['zmax']) {
|
|
|
|
$ret['zmax'] = $bbox['zmax'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($is_m) {
|
|
|
|
if ($ret['mmin'] === false || $bbox['mmin'] < $ret['mmin']) {
|
|
|
|
$ret['mmin'] = $bbox['mmin'];
|
|
|
|
}
|
|
|
|
if ($ret['mmax'] === false || $bbox['mmax'] > $ret['mmax']) {
|
|
|
|
$ret['mmax'] = $bbox['mmax'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////// PROTECTED ///////////////////////////////
|
|
|
|
/**
|
|
|
|
* Adds a Geometry to the collection.
|
|
|
|
* It enforces all geometries to be of the same type.
|
|
|
|
*
|
|
|
|
* @param \Shapefile\Geometry\Geometry $Geometry
|
|
|
|
*
|
|
|
|
* @return self Returns $this to provide a fluent interface.
|
|
|
|
*/
|
|
|
|
protected function addGeometry(Geometry $Geometry)
|
|
|
|
{
|
|
|
|
if (!is_a($Geometry, $this->getCollectionClass())) {
|
|
|
|
throw new ShapefileException(Shapefile::ERR_INPUT_GEOMETRY_TYPE_NOT_VALID, $this->getCollectionClass());
|
|
|
|
}
|
|
|
|
if (!$Geometry->isEmpty()) {
|
|
|
|
if ($this->isEmpty()) {
|
|
|
|
$this->setFlagEmpty(false);
|
|
|
|
$this->setFlagZ($Geometry->isZ());
|
|
|
|
$this->setFlagM($Geometry->isM());
|
|
|
|
} else {
|
|
|
|
if ($this->isZ() !== $Geometry->isZ() || $this->isM() !== $Geometry->isM()) {
|
|
|
|
throw new ShapefileException(Shapefile::ERR_GEOM_MISMATCHED_DIMENSIONS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->geometries[] = $Geometry;
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a Geometry at specified index from the collection.
|
|
|
|
*
|
|
|
|
* @param int $index The index of the Geometry.
|
|
|
|
*
|
|
|
|
* @return \Shapefile\Geometry\Geometry
|
|
|
|
*/
|
|
|
|
protected function getGeometry($index)
|
|
|
|
{
|
|
|
|
if (!isset($this->geometries[$index])) {
|
|
|
|
throw new ShapefileException(Shapefile::ERR_INPUT_GEOMETRY_INDEX_NOT_VALID, $index);
|
|
|
|
}
|
|
|
|
return $this->geometries[$index];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets all the geometries in the collection.
|
|
|
|
*
|
|
|
|
* @return \Shapefile\Geometry\Geometry[]
|
|
|
|
*/
|
|
|
|
protected function getGeometries()
|
|
|
|
{
|
|
|
|
return $this->geometries;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the number of geometries in the collection.
|
|
|
|
*
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
protected function getNumGeometries()
|
|
|
|
{
|
|
|
|
return count($this->geometries);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reverses the order of geometries in the collection.
|
|
|
|
*
|
|
|
|
* @return self Returns $this to provide a fluent interface.
|
|
|
|
*/
|
|
|
|
protected function reverseGeometries()
|
|
|
|
{
|
|
|
|
$this->geometries = array_reverse($this->geometries);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
}
|