Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Map: is a lat/lng within a polygon?

Given a pair of lat/lng values, how do I determine if the pair is within a polygon? I need to do this in PHP. I see that Google Maps API has a containsLocation method: https://developers.google.com/maps/documentation/javascript/reference. Is there a way to leverage this from PHP?

like image 896
StackOverflowNewbie Avatar asked Nov 10 '12 03:11

StackOverflowNewbie


People also ask

How do I extract a polygon from Google Maps?

Assuming you have a Google account, creating a map is explained here and by using draw a line tool, you can create polygons. Even though it says line, the sub menu says Add line or shape and closing your line will create a polygon. Once you finish your map, in the map options, you will find Export to KML.


2 Answers

One way to find if a point is in a polygon is to count how many times a line drawn from the point (in any direction) intersects with the polygon boundary. If they intersect an even number of times, then the point is outside.

I have implemented the C code from this Point in Polygon article in php and used the polygon below to illustrate.

polygon

<?php
//Point-In-Polygon Algorithm
$polySides  = 4; //how many corners the polygon has
$polyX    =  array(4,9,11,2);//horizontal coordinates of corners
$polyY    =  array(10,7,2,2);//vertical coordinates of corners
$x = 3.5;
$y = 13.5;//Outside
//$y = 3.5;//Inside

function pointInPolygon($polySides,$polyX,$polyY,$x,$y) {
  $j = $polySides-1 ;
  $oddNodes = 0;
  for ($i=0; $i<$polySides; $i++) {
    if ($polyY[$i]<$y && $polyY[$j]>=$y 
 ||  $polyY[$j]<$y && $polyY[$i]>=$y) {
    if ($polyX[$i]+($y-$polyY[$i])/($polyY[$j]-$polyY[$i])*($polyX[$j]-$polyX[$i])<$x)    {
    $oddNodes=!$oddNodes; }}
   $j=$i; }

  return $oddNodes; }


 if (pointInPolygon($polySides,$polyX,$polyY,$x,$y)){
  echo "Is in polygon!";
}
else echo "Is not in polygon";
?>
like image 140
david strachan Avatar answered Sep 20 '22 10:09

david strachan


very big thanks to David Strachan and Darel Rex Finley

i want to share my php version, is slightly different beacause it takes the point as an array ([lat, lng]) and the polygon as an array of point ([[lat, lng],[lat, lng],...])

  function pointInPolygon($point, $polygon){//http://alienryderflex.com/polygon/
     $return = false;
     foreach($polygon as $k=>$p){
        if(!$k) $k_prev = count($polygon)-1;
        else $k_prev = $k-1;

        if(($p[1]< $point[1] && $polygon[$k_prev][1]>=$point[1] || $polygon[$k_prev][1]< $point[1] && $p[1]>=$point[1]) && ($p[0]<=$point[0] || $polygon[$k_prev][0]<=$point[0])){
           if($p[0]+($point[1]-$p[1])/($polygon[$k_prev][1]-$p[1])*($polygon[$k_prev][0]-$p[0])<$point[0]){
              $return = !$return;
           }
        }
     }
     return $return;
  }
like image 38
c3k Avatar answered Sep 19 '22 10:09

c3k