70 lines
3.1KB

  1. <?php
  2. namespace Lc\ShopBundle\Services ;
  3. class PointLocationUtils {
  4. var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices?
  5. function pointLocation() {
  6. }
  7. function pointInPolygon($point, $polygon, $pointOnVertex = true) {
  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($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x'])) { // Check if point is on an horizontal polygon boundary
  26. return "boundary";
  27. }
  28. if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max($vertex1['y'], $vertex2['y']) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) {
  29. $xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
  30. if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal)
  31. return "boundary";
  32. }
  33. if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
  34. $intersections++;
  35. }
  36. }
  37. }
  38. // If the number of edges we passed through is odd, then it's in the polygon.
  39. if ($intersections % 2 != 0) {
  40. return "inside";
  41. } else {
  42. return "outside";
  43. }
  44. }
  45. function pointOnVertex($point, $vertices) {
  46. foreach($vertices as $vertex) {
  47. if ($point == $vertex) {
  48. return true;
  49. }
  50. }
  51. }
  52. function pointStringToCoordinates($pointString) {
  53. $coordinates = explode(" ", $pointString);
  54. return array("x" => $coordinates[0], "y" => $coordinates[1]);
  55. }
  56. }