如何检查多边形内是否存在纬度/经度坐标 - PHP

时间:2014-12-19 16:03:41

标签: php google-maps geolocation geocoding

我想在PHP中编写一些代码来检查单个纬度/长度坐标以对齐多边形的坐标。并且返回true或false是否存在于多边形内部。

e.g。我在这里创建了一个多边形 http://www.geocodezip.com/polygonTool.asp

0:53.34545,-6.255083 1:53.340121,-6.239033 2:53.338788,-6.238947 3:53.337405,-6.240492 4:53.334227,-6.245642 5:53.332074,-6.252937 6:53.330024,-6.264353 7:53.333766,-6.264868 8:53.33761,-6.265812 9:53.338583,-6.266155 10:53.341607,-6.265383 11:53.342683,-6.264439 12:53.344067,-6.264696 13:53.344733,-6.259632

我的用户位置为...... 53.338839,-6.249386(这个多边形内部确实存在)。

是否有一种简单的方法可以验证它是在多边形内部还是外部?

2 个答案:

答案 0 :(得分:1)

查找点是否在多边形中的一种方法是计算从该点(在任何方向上)绘制的线与多边形边界相交的次数。如果它们相交偶数次,则该点在外面。

以下PHP代码需要2个数组$ polyX =多边形经度点的数组。重复第一个点以关闭多边形。 $ polyy =多边形的纬度点数组,

$polySides  = 13; //how many corners the polygon has
$polyX = array(53.34545,53.340121,53.338788,53.337405,53.334227,53.332074,53.330024,53.333766,53.33761,53.338583,53.341607,53.342683,53.344067,53.344733,53.34545);
$polyY = array(6.255083,-6.239033,-6.238947,-6.240492,-6.245642,-6.252937,-6.264353,-6.264868,-6.265812,-6.266155,-6.265383,-6.264439,-6.264696,-6.259632,6.255083);
$x =53.338839;//your coordinates
$y =-6.249386;


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";

查看this以获取javascript实现。

答案 1 :(得分:0)

从我的Geodetic classes开始,基本功能是:

function isInRegion(Geodetic_LatLong $position)
{
    $latitude = $position->getLatitude()->getValue();
    $longitude = $position->getLongitude()->getValue();
    $perimeterNodeCount = count($this->_nodePoints);
    $jIndex = $perimeterNodeCount - 1 ;
    $oddNodes = FALSE;
    for ($iIndex = 0; $iIndex < $perimeterNodeCount; ++$iIndex) {
        $iLatitude = $this->_nodePoints[$iIndex]->getLatitude()->getValue();
        $jLatitude = $this->_nodePoints[$jIndex]->getLatitude()->getValue();
        if (($iLatitude < $latitude && $jLatitude >= $latitude) ||
            ($jLatitude < $latitude && $iLatitude >= $latitude)) {
            $iLongitude = $this->_nodePoints[$iIndex]->getLongitude()->getValue();
            $jLongitude = $this->_nodePoints[$jIndex]->getLongitude()->getValue();
            if ($iLongitude +
                ($latitude - $iLatitude) /
                ($jLatitude - $iLatitude) * ($jLongitude - $iLongitude) < $longitude) {
                $oddNodes = !$oddNodes;
            }
        }
        $jIndex = $iIndex;
    }
    return $oddNodes;
}