You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
2.8KB

  1. <?php
  2. namespace Lc\SovBundle\Component;
  3. class PointLocationComponent
  4. {
  5. var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices?
  6. function pointInPolygon($point, $polygon, $pointOnVertex = true)
  7. {
  8. $this->pointOnVertex = $pointOnVertex;
  9. // Transform string coordinates into arrays with x and y values
  10. $point = $this->pointStringToCoordinates($point);
  11. $vertices = array();
  12. foreach ($polygon as $vertex) {
  13. $vertices[] = $this->pointStringToCoordinates($vertex);
  14. }
  15. // Check if the point sits exactly on a vertex
  16. if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) {
  17. return "vertex";
  18. }
  19. // Check if the point is inside the polygon or on the boundary
  20. $intersections = 0;
  21. $vertices_count = count($vertices);
  22. for ($i = 1; $i < $vertices_count; $i++) {
  23. $vertex1 = $vertices[$i - 1];
  24. $vertex2 = $vertices[$i];
  25. if ($vertex1['y'] == $vertex2['y'] and $vertex1['y'] == $point['y'] and $point['x'] > min(
  26. $vertex1['x'],
  27. $vertex2['x']
  28. ) and $point['x'] < max(
  29. $vertex1['x'],
  30. $vertex2['x']
  31. )) { // Check if point is on an horizontal polygon boundary
  32. return "boundary";
  33. }
  34. if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max(
  35. $vertex1['y'],
  36. $vertex2['y']
  37. ) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) {
  38. $xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
  39. if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal)
  40. return "boundary";
  41. }
  42. if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
  43. $intersections++;
  44. }
  45. }
  46. }
  47. // If the number of edges we passed through is odd, then it's in the polygon.
  48. if ($intersections % 2 != 0) {
  49. return "inside";
  50. } else {
  51. return "outside";
  52. }
  53. }
  54. function pointOnVertex($point, $vertices)
  55. {
  56. foreach ($vertices as $vertex) {
  57. if ($point == $vertex) {
  58. return true;
  59. }
  60. }
  61. }
  62. function pointStringToCoordinates($pointString)
  63. {
  64. $coordinates = explode(" ", $pointString);
  65. return array("x" => $coordinates[0], "y" => $coordinates[1]);
  66. }
  67. }