You are here

public function Polygon::pointInPolygon in geoPHP 7

For a given point, determine whether it's bounded by the given polygon. Adapted from http://www.assemblysys.com/dataServices/php_pointinpolygon.php

Parameters

Point $point :

boolean $pointOnBoundary - whether a boundary should be considered "in" or not:

boolean $pointOnVertex - whether a vertex should be considered "in" or not:

Return value

boolean

See also

http://en.wikipedia.org/wiki/Point%5Fin%5Fpolygon

File

geoPHP/lib/geometry/Polygon.class.php, line 153

Class

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

Code

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