You are here

class Polygon in geoPHP 7

Same name and namespace in other branches
  1. 8 geoPHP/lib/geometry/Polygon.class.php \Polygon

Polygon: A polygon is a plane figure that is bounded by a closed path, composed of a finite sequence of straight line segments

Hierarchy

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;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Collection::$components public property
Collection::asArray public function Overrides Geometry::asArray 1
Collection::endPoint public function Overrides Geometry::endPoint 1
Collection::equals public function Overrides Geometry::equals
Collection::explode public function Overrides Geometry::explode 2
Collection::geometryN public function Overrides Geometry::geometryN
Collection::getBBox public function Overrides Geometry::getBBox
Collection::getComponents public function Returns Collection component geometries
Collection::getPoints public function Overrides Geometry::getPoints
Collection::greatCircleLength public function Overrides Geometry::greatCircleLength 1
Collection::haversineLength public function Overrides Geometry::haversineLength 1
Collection::isClosed public function Overrides Geometry::isClosed 2
Collection::isEmpty public function Overrides Geometry::isEmpty
Collection::isRing public function Overrides Geometry::isRing 1
Collection::numGeometries public function Overrides Geometry::numGeometries
Collection::numPoints public function Overrides Geometry::numPoints 2
Collection::pointN public function Overrides Geometry::pointN 1
Collection::pointOnSurface public function Overrides Geometry::pointOnSurface
Collection::startPoint public function Overrides Geometry::startPoint 1
Collection::x public function Overrides Geometry::x
Collection::y public function Overrides Geometry::y
Collection::__construct public function Constructor: Checks and sets component geometries 1
Geometry::$geos private property
Geometry::$srid protected property
Geometry::asBinary public function
Geometry::asText public function
Geometry::buffer public function
Geometry::checkValidity public function
Geometry::contains public function
Geometry::convexHull public function
Geometry::coordinateDimension public function
Geometry::coveredBy public function
Geometry::covers public function
Geometry::crosses public function
Geometry::difference public function
Geometry::disjoint public function
Geometry::distance public function
Geometry::envelope public function
Geometry::equalsExact public function
Geometry::geometryType public function
Geometry::geos public function
Geometry::getArea public function
Geometry::getCentroid public function
Geometry::getGeomType public function
Geometry::getGeos public function
Geometry::getSRID public function
Geometry::getX public function
Geometry::getY public function
Geometry::hasZ public function
Geometry::hausdorffDistance public function
Geometry::intersection public function
Geometry::intersects public function
Geometry::is3D public function
Geometry::isMeasured public function
Geometry::m public function
Geometry::out public function
Geometry::overlaps public function
Geometry::project public function
Geometry::relate public function
Geometry::setGeos public function
Geometry::setSRID public function
Geometry::simplify public function
Geometry::SRID public function
Geometry::symDifference public function
Geometry::touches public function
Geometry::union public function
Geometry::within public function
Geometry::z public function 1
Polygon::$geom_type protected property Overrides Geometry::$geom_type
Polygon::area public function Overrides Collection::area
Polygon::boundary public function Overrides Collection::boundary
Polygon::centroid public function Overrides Collection::centroid
Polygon::dimension public function Overrides Collection::dimension
Polygon::exteriorRing public function Overrides Collection::exteriorRing
Polygon::interiorRingN public function Overrides Collection::interiorRingN
Polygon::isSimple public function Overrides Collection::isSimple
Polygon::length public function Overrides Collection::length
Polygon::numInteriorRings public function Overrides Collection::numInteriorRings
Polygon::outermostPoint public function * Find the outermost point from the centroid * * @returns Point The outermost point
Polygon::pointInPolygon public function For a given point, determine whether it's bounded by the given polygon. Adapted from http://www.assemblysys.com/dataServices/php_pointinpolygon.php
Polygon::pointOnVertex public function