Find Point in polygon PHP
This is a function i converted from another language into 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;
}
Additional:
For more functions i advise you to use the polygon.php class available here.
Create the Class using your vertices and call the function isInside
with your testpoint as input to have another function solving your problem.
detecting point within polygon (latitude and longitude) in PHP
If you are just wanting to check if the polygon contains your point using Google maps you can try : Google Maps API
If you want to calculate it in PHP then your question is a duplicate of this: Check if Google Map Point is in polygon from PHP
Find Point 2 mile away from polygon PHP
If you consider that your points are near compare to the size of the earth, you could compute distance from a coordinate to another using this formula :
It's a csharp function but easy to port to php
double getGroundDistance(double latA, double lonA, double latB, double lonB)
{
double a = Math.PI / 180;
double lat1 = latA * a;
double lat2 = latB * a;
double lon1 = lonA * a;
double lon2 = lonB * a;
double t1 = Math.Sin(lat1) * Math.Sin(lat2);
double t2 = Math.Cos(lat1) * Math.Cos(lat2);
double t3 = Math.Cos(lon1 - lon2);
double t4 = t2 * t3;
double t5 = t1 + t4;
double radDist = Math.Atan(-t5 / Math.Sqrt(-t5 * t5 + 1)) + 2 * Math.Atan(1);
return (radDist * 3437.74677 * 1.1508) * 1.6093470878864446 * 1000;
}
So you just need to check your distance from each point.
Hope it help
Point-in-Polygon PHP Errors
There were a couple of problems with the original code, closing the polygons fixed one of these but the code also gave incorrect results for points on the boundary lines of the polygon. The if..else statement at the end of the isWithinBoundary function only needs to be executed if a point IS NOT on a boundary. As a point on the boundary won't actually intersect the boundary then the count of intersections would always be odd for a boundary point meaning that this final IF statement would always return FALSE for a boundary point.
I have tweaked the code a little, this version is a self contained page that has some simple test data and it outputs the decisions being made.
<?php
$myPolygon = array('4,3', '4,6', '7,6', '7,3','4,3');
$test_points = array('0,0','1,1','2,2','3,3','3.99999,3.99999','4,4','5,5','6,6','6.99999,5.99999','7,7');
echo "The test polygon has the co-ordinates ";
foreach ($myPolygon as $polypoint){
echo $polypoint.", ";
}
echo "<br/>";
foreach ($test_points as $apoint)
{
echo "Point ".$apoint." is ";
if (!isWithinBoundary($apoint,$myPolygon))
{
echo " NOT ";
}
echo "inside the test polygon<br />";
}
function pointStringToCoordinates($pointString)
{
$coordinates = explode(",", $pointString);
return array("x" => trim($coordinates[0]), "y" => trim($coordinates[1]));
}
function isWithinBoundary($point,$polygon)
{
$result =FALSE;
$point = pointStringToCoordinates($point);
$vertices = array();
foreach ($polygon as $vertex)
{
$vertices[] = pointStringToCoordinates($vertex);
}
// 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'] and $vertex1['y'] == $point['y'] and $point['x'] > min($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x']))
{
// This point is on an horizontal polygon boundary
$result = TRUE;
// set $i = $vertices_count so that loop exits as we have a boundary point
$i = $vertices_count;
}
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'])
{
$xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
if ($xinters == $point['x'])
{ // This point is on the polygon boundary (other than horizontal)
$result = TRUE;
// set $i = $vertices_count so that loop exits as we have a boundary point
$i = $vertices_count;
}
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.
// Have to check here also to make sure that we haven't already determined that a point is on a boundary line
if ($intersections % 2 != 0 && $result == FALSE)
{
$result = TRUE;
}
return $result;
}
?>
You've probably spotted and fixed these problems yourself by now, but this might help other people who find and use this code.
Check if Google Map Point is in polygon from PHP
Did you try searching for "php point in polygon" in your favourite search engine? Top hit:
http://assemblysys.com/php-point-in-polygon-algorithm/
It uses a scanline algorithm, and there's some examples. All you need to do is read your polygon file into the right format (you neglected to say what format you have) and call the function.
Point in Polygon algorithm giving wrong results sometimes
Have been there :-) I also travelled through Stackoverflow's PiP-suggestions, including your reference and this thread. Unfortunately, none of the suggestions (at least those I tried) were flawless and sufficient for a real-life scenario: like users plotting complex polygons on a Google map in freehand, "vicious" right vs left issues, negative numbers and so on.
The PiP-algorithm must work in all cases, even if the polygon consists of hundreds of thousands of points (like a county-border, nature park and so on) - no matter how "crazy" the polygon is.
So I ended up building a new algorithm, based on some source from an astronomy-app:
//Point class, storage of lat/long-pairs
class Point {
public $lat;
public $long;
function Point($lat, $long) {
$this->lat = $lat;
$this->long = $long;
}
}
//the Point in Polygon function
function pointInPolygon($p, $polygon) {
//if you operates with (hundred)thousands of points
set_time_limit(60);
$c = 0;
$p1 = $polygon[0];
$n = count($polygon);
for ($i=1; $i<=$n; $i++) {
$p2 = $polygon[$i % $n];
if ($p->long > min($p1->long, $p2->long)
&& $p->long <= max($p1->long, $p2->long)
&& $p->lat <= max($p1->lat, $p2->lat)
&& $p1->long != $p2->long) {
$xinters = ($p->long - $p1->long) * ($p2->lat - $p1->lat) / ($p2->long - $p1->long) + $p1->lat;
if ($p1->lat == $p2->lat || $p->lat <= $xinters) {
$c++;
}
}
$p1 = $p2;
}
// if the number of edges we passed through is even, then it's not in the poly.
return $c%2!=0;
}
Illustrative test :
$polygon = array(
new Point(1,1),
new Point(1,4),
new Point(4,4),
new Point(4,1)
);
function test($lat, $long) {
global $polygon;
$ll=$lat.','.$long;
echo (pointInPolygon(new Point($lat,$long), $polygon)) ? $ll .' is inside polygon<br>' : $ll.' is outside<br>';
}
test(2, 2);
test(1, 1);
test(1.5333, 2.3434);
test(400, -100);
test(1.01, 1.01);
Outputs :
2,2 is inside polygon
1,1 is outside
1.5333,2.3434 is inside polygon
400,-100 is outside
1.01,1.01 is inside polygon
It is now more than a year since I switched to the above algorithm on several sites. Unlike the "SO-algorithms" there have not been any complaints so far. See it in action here (national mycological database, sorry for the Danish). You can plot a polygon, or select a "kommune" (a county) - ultimately compare a polygon with thousands of points to thousands of records).
Update
Note, this algorithm is targeting geodata / lat,lngs which can be very precise (n'th decimal), therefore considering "in polygon" as inside polygon - not on border of polygon. 1,1 is considered outside, since it is on the border. 1.0000000001,1.01 is not.
Related Topics
Programmatically Creating New Order in Woocommerce
How to Execute PHP Code Within JavaScript
Create Image from Url Any File Type
Make a Path Work Both on Linux and Windows
How Are Associative Arrays Implemented in PHP
MySQL Can't Perform More Than 1 Query at a Time
How to Paginate a Merged Collection in Laravel 5
How to Add Square Braces Around Subarray Data Inside of a JSON Encoded String
What Is the Pdo Equivalent of Function MySQL_Real_Escape_String
Get Div Content from External Website
Algorithm to Get All Possible String Combinations from Array Up to Certain Length
How to Parse a CSV File to Grab the Column Names First Then the Rows That Relate to It
Checking If Process Still Running
$Stmt->Execute():How to Know If Db Insert Was Successful
Fatal Error: Call to Undefined Function SQLsrv_Connect() in C:\Xampp\Htdocs
How to Query Employee Details and Relate Their Performance Metrics