class Polygon in geoPHP 7
Same name and namespace in other branches
Polygon: A polygon is a plane figure that is bounded by a closed path, composed of a finite sequence of straight line segments
Hierarchy
- class \Geometry
- class \Collection
- class \Polygon
- class \Collection
Expanded class hierarchy of Polygon
5 string references to 'Polygon'
- EWKB::write in geoPHP/
lib/ adapters/ EWKB.class.php - Serialize geometries into an EWKB binary string.
- geoPHP::geometryList in geoPHP/
geoPHP.inc - geoPHP::geometryReduce in geoPHP/
geoPHP.inc - WKB::write in geoPHP/
lib/ adapters/ WKB.class.php - Serialize geometries into WKB string.
- WKT::extractData in geoPHP/
lib/ adapters/ WKT.class.php - Extract geometry to a WKT string
File
- geoPHP/
lib/ geometry/ Polygon.class.php, line 7
View source
class Polygon extends Collection {
protected $geom_type = 'Polygon';
// The boundary of a polygin is it's outer ring
public function boundary() {
return $this
->exteriorRing();
}
public function area($exterior_only = FALSE, $signed = FALSE) {
if ($this
->isEmpty()) {
return 0;
}
if ($this
->geos() && $exterior_only == FALSE) {
return $this
->geos()
->area();
}
$exterior_ring = $this->components[0];
$pts = $exterior_ring
->getComponents();
$c = count($pts);
if ((int) $c == '0') {
return NULL;
}
$a = '0';
foreach ($pts as $k => $p) {
$j = ($k + 1) % $c;
$a = $a + $p
->getX() * $pts[$j]
->getY() - $p
->getY() * $pts[$j]
->getX();
}
if ($signed) {
$area = $a / 2;
}
else {
$area = abs($a / 2);
}
if ($exterior_only == TRUE) {
return $area;
}
foreach ($this->components as $delta => $component) {
if ($delta != 0) {
$inner_poly = new Polygon(array(
$component,
));
$area -= $inner_poly
->area();
}
}
return $area;
}
public function centroid() {
if ($this
->isEmpty()) {
return NULL;
}
if ($this
->geos()) {
return geoPHP::geosToGeometry($this
->geos()
->centroid());
}
$exterior_ring = $this->components[0];
$pts = $exterior_ring
->getComponents();
$c = count($pts);
if ((int) $c == '0') {
return NULL;
}
$cn = array(
'x' => '0',
'y' => '0',
);
$a = $this
->area(TRUE, TRUE);
// If this is a polygon with no area. Just return the first point.
if ($a == 0) {
return $this
->exteriorRing()
->pointN(1);
}
foreach ($pts as $k => $p) {
$j = ($k + 1) % $c;
$P = $p
->getX() * $pts[$j]
->getY() - $p
->getY() * $pts[$j]
->getX();
$cn['x'] = $cn['x'] + ($p
->getX() + $pts[$j]
->getX()) * $P;
$cn['y'] = $cn['y'] + ($p
->getY() + $pts[$j]
->getY()) * $P;
}
$cn['x'] = $cn['x'] / (6 * $a);
$cn['y'] = $cn['y'] / (6 * $a);
$centroid = new Point($cn['x'], $cn['y']);
return $centroid;
}
/**
* Find the outermost point from the centroid
*
* @returns Point The outermost point
*/
public function outermostPoint() {
$centroid = $this
->getCentroid();
$max = array(
'length' => 0,
'point' => null,
);
foreach ($this
->getPoints() as $point) {
$lineString = new LineString(array(
$centroid,
$point,
));
if ($lineString
->length() > $max['length']) {
$max['length'] = $lineString
->length();
$max['point'] = $point;
}
}
return $max['point'];
}
public function exteriorRing() {
if ($this
->isEmpty()) {
return new LineString();
}
return $this->components[0];
}
public function numInteriorRings() {
if ($this
->isEmpty()) {
return 0;
}
return $this
->numGeometries() - 1;
}
public function interiorRingN($n) {
return $this
->geometryN($n + 1);
}
public function dimension() {
if ($this
->isEmpty()) {
return 0;
}
return 2;
}
public function isSimple() {
if ($this
->geos()) {
return $this
->geos()
->isSimple();
}
$segments = $this
->explode();
foreach ($segments as $i => $segment) {
foreach ($segments as $j => $check_segment) {
if ($i != $j) {
if ($segment
->lineSegmentIntersect($check_segment)) {
return FALSE;
}
}
}
}
return TRUE;
}
/**
* For a given point, determine whether it's bounded by the given polygon.
* Adapted from http://www.assemblysys.com/dataServices/php_pointinpolygon.php
* @see http://en.wikipedia.org/wiki/Point%5Fin%5Fpolygon
*
* @param Point $point
* @param boolean $pointOnBoundary - whether a boundary should be considered "in" or not
* @param boolean $pointOnVertex - whether a vertex should be considered "in" or not
* @return boolean
*/
public function pointInPolygon($point, $pointOnBoundary = true, $pointOnVertex = true) {
$vertices = $this
->getPoints();
// Check if the point sits exactly on a vertex
if ($this
->pointOnVertex($point, $vertices)) {
return $pointOnVertex ? TRUE : FALSE;
}
// Check if the point is inside the polygon or on the boundary
$intersections = 0;
$vertices_count = count($vertices);
for ($i = 1; $i < $vertices_count; $i++) {
$vertex1 = $vertices[$i - 1];
$vertex2 = $vertices[$i];
if ($vertex1
->y() == $vertex2
->y() && $vertex1
->y() == $point
->y() && $point
->x() > min($vertex1
->x(), $vertex2
->x()) && $point
->x() < max($vertex1
->x(), $vertex2
->x())) {
// Check if point is on an horizontal polygon boundary
return $pointOnBoundary ? TRUE : FALSE;
}
if ($point
->y() > min($vertex1
->y(), $vertex2
->y()) && $point
->y() <= max($vertex1
->y(), $vertex2
->y()) && $point
->x() <= max($vertex1
->x(), $vertex2
->x()) && $vertex1
->y() != $vertex2
->y()) {
$xinters = ($point
->y() - $vertex1
->y()) * ($vertex2
->x() - $vertex1
->x()) / ($vertex2
->y() - $vertex1
->y()) + $vertex1
->x();
if ($xinters == $point
->x()) {
// Check if point is on the polygon boundary (other than horizontal)
return $pointOnBoundary ? TRUE : FALSE;
}
if ($vertex1
->x() == $vertex2
->x() || $point
->x() <= $xinters) {
$intersections++;
}
}
}
// If the number of edges we passed through is even, then it's in the polygon.
if ($intersections % 2 != 0) {
return TRUE;
}
else {
return FALSE;
}
}
public function pointOnVertex($point) {
foreach ($this
->getPoints() as $vertex) {
if ($point
->equals($vertex)) {
return true;
}
}
}
// Not valid for this geometry type
// --------------------------------
public function length() {
return NULL;
}
}