1<?php 2 3namespace geoPHP\Geometry; 4 5use geoPHP\geoPHP; 6 7/** 8 * MultiPolygon: A collection of Polygons 9 * 10 * @method Polygon[] getComponents() 11 * @property Polygon[] $components 12 */ 13class MultiPolygon extends MultiSurface 14{ 15 16 public function __construct($components = []) 17 { 18 parent::__construct($components, true, Polygon::class); 19 } 20 21 public function geometryType() 22 { 23 return Geometry::MULTI_POLYGON; 24 } 25 26 public function centroid() 27 { 28 if ($this->isEmpty()) { 29 return null; 30 } 31 32 if ($this->getGeos()) { 33 // @codeCoverageIgnoreStart 34 /** @noinspection PhpUndefinedMethodInspection */ 35 return geoPHP::geosToGeometry($this->getGeos()->centroid()); 36 // @codeCoverageIgnoreEnd 37 } 38 39 $x = 0; 40 $y = 0; 41 $totalArea = 0; 42 foreach ($this->getComponents() as $component) { 43 if ($component->isEmpty()) { 44 continue; 45 } 46 $componentArea = $component->area(); 47 $totalArea += $componentArea; 48 $componentCentroid = $component->centroid(); 49 $x += $componentCentroid->x() * $componentArea; 50 $y += $componentCentroid->y() * $componentArea; 51 } 52 return new Point($x / $totalArea, $y / $totalArea); 53 } 54 55 public function area() 56 { 57 if ($this->getGeos()) { 58 // @codeCoverageIgnoreStart 59 /** @noinspection PhpUndefinedMethodInspection */ 60 return $this->getGeos()->area(); 61 // @codeCoverageIgnoreEnd 62 } 63 64 $area = 0; 65 foreach ($this->components as $component) { 66 $area += $component->area(); 67 } 68 return $area; 69 } 70 71 public function boundary() 72 { 73 $rings = []; 74 foreach ($this->getComponents() as $component) { 75 $rings = array_merge($rings, $component->components); 76 } 77 return new MultiLineString($rings); 78 } 79} 80