Saltar al contenido

Buscar punto en polígono PHP

Si hallas algún error en tu código o trabajo, recuerda probar siempre en un ambiente de testing antes añadir el código al proyecto final.

Solución:

Esta es una función que convertí de otro idioma a PHP:

$vertices_x = array(37.628134, 37.629867, 37.62324, 37.622424);    // x-coordinates of the vertices of the polygon
$vertices_y = array(-77.458334,-77.449021,-77.445416,-77.457819); // y-coordinates of the vertices of the polygon
$points_polygon = count($vertices_x) - 1;  // number vertices - zero-based array
$longitude_x = $_GET["longitude"];  // x-coordinate of the point to test
$latitude_y = $_GET["latitude"];    // y-coordinate of the point to test

if (is_in_polygon($points_polygon, $vertices_x, $vertices_y, $longitude_x, $latitude_y))
  echo "Is in polygon!";

else echo "Is not in polygon";


function is_in_polygon($points_polygon, $vertices_x, $vertices_y, $longitude_x, $latitude_y)

  $i = $j = $c = 0;
  for ($i = 0, $j = $points_polygon ; $i < $points_polygon; $j = $i++) 
    if ( (($vertices_y[$i]  >  $latitude_y != ($vertices_y[$j] > $latitude_y)) &&
     ($longitude_x < ($vertices_x[$j] - $vertices_x[$i]) * ($latitude_y - $vertices_y[$i]) / ($vertices_y[$j] - $vertices_y[$i]) + $vertices_x[$i]) ) )
       $c = !$c;
  
  return $c;

Adicional:
Para más funciones, le aconsejo que use la clase polygon.php disponible aquí. Crea la Clase usando tus vértices y llama a la función. isInside con su punto de prueba como entrada para tener otra función que resuelva su problema.

La respuesta popular anterior contiene errores tipográficos. En otros lugares, este código se ha limpiado. El código corregido es el siguiente:

 $latitude_y != ($vertices_y[$j] > $latitude_y)) &&
    ($longitude_x < ($vertices_x[$j] - $vertices_x[$i]) * ($latitude_y - $vertices_y[$i]) / ($vertices_y[$j] - $vertices_y[$i]) + $vertices_x[$i]) ) ) 
        $c = !$c;
  
  return $c;

?>

La solución anterior no funciona como esperaba, en lugar de usar la solución anterior, puede preferir las soluciones a continuación

  1. Con PHP

    function pointInPolygon($point, $polygon, $pointOnVertex = true) 
        $this->pointOnVertex = $pointOnVertex;
    
        // Transform string coordinates into arrays with x and y values
        $point = $this->pointStringToCoordinates($point);
        $vertices = array(); 
        foreach ($polygon as $vertex) 
            $vertices[] = $this->pointStringToCoordinates($vertex); 
        
    
        // Check if the lat lng sits exactly on a vertex
        if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) 
            return "vertex";
        
    
        // Check if the lat lng 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'] 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
                return "boundary";
            
            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'])  
         
        // If the number of edges we passed through is odd, then it's in the polygon. 
        if ($intersections % 2 != 0) 
            return "inside";
         else 
            return "outside";
        
    
    
    function pointOnVertex($point, $vertices) 
      foreach($vertices as $vertex) 
          if ($point == $vertex) 
              return true;
          
      
    
    
    
    function pointStringToCoordinates($pointString) 
        $coordinates = explode(" ", $pointString);
        return array("x" => $coordinates[0], "y" => $coordinates[1]);
    
    // Function to check lat lng
    function check()
        $points = array("22.367582 70.711816", "21.43567582 72.5811816","22.367582117085913 70.71181669186944","22.275334996986643 70.88614147123701","22.36934302329968 70.77627818998701"); // Array of latlng which you want to find
        $polygon = array(
            "22.367582117085913 70.71181669186944",
            "22.225161442616514 70.65582486840117",
            "22.20736264867434 70.83229276390898",
            "22.18701840565626 70.9867880031668",
            "22.22452581029355 71.0918447658621",
            "22.382709129816103 70.98884793969023",
            "22.40112042636022 70.94078275414336",
            "22.411912121843205 70.7849142238699",
            "22.367582117085913 70.71181669186944"
        );
        // The last lat lng must be the same as the first one's, to "close the loop"
        foreach($points as $key => $point) 
            echo "(Lat Lng) " . ($key+1) . " ($point): " . $this->pointInPolygon($point, $polygon) . "
    ";
  2. Con MySql

CREATE TABLE `TestPoly` (
   `id` int(11) NOT NULL,
   `name` varchar(255) NOT NULL,
   `pol` polygon NOT NULL
 )

SET @g = 'POLYGON((22.367582117085913 70.71181669186944, 22.225161442616514 70.65582486840117, 22.20736264867434 70.83229276390898, 22.18701840565626 70.9867880031668, 22.22452581029355 71.0918447658621, 22.382709129816103 70.98884793969023, 22.40112042636022 70.94078275414336, 22.411912121843205 70.7849142238699, 22.367582117085913 70.71181669186944))';
INSERT INTO TestPoly (pol) VALUES (ST_GeomFromText(@g))

set @p = GeomFromText('POINT(22.4053386588057 70.86240663480157)');
select * FROM TestPoly where ST_Contains(pol, @p);

Valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *