PHP如何改造单多边形点定位代码 实现多多边形范围判断功能
PHP点入多多边形判断改造方案
改造思路
原有单多边形判断逻辑已经稳定可直接复用,只需要新增一层批量校验逻辑即可:
- 将所有待判断的多边形整理为二维数组,每个子元素对应一个单多边形的Point对象数组
- 新增批量判断函数,遍历所有多边形,逐个调用原有
pointInPolygon方法校验 - 只要目标点落在任意一个多边形内就直接返回
true,全部校验不通过再返回false
完整改造代码
class Point { public $lat; public $long; // 兼容PHP5.x老式构造方法,PHP7+可替换为__construct function Point($lat, $long) { $this->lat = $lat; $this->long = $long; } } // 原有单多边形判断函数,无需修改 function pointInPolygon($p, $polygon) { $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; } return $c%2!=0; } // 新增多多边形批量判断函数 function pointInAnyPolygon($p, $polygons) { // 全局超时设置可以放在这里,避免循环重复调用 set_time_limit(60); foreach ($polygons as $polygon) { // 可选优化:先判断点是否在当前多边形的最小外包矩形内,不在直接跳过校验,提升性能 if (pointInPolygon($p, $polygon)) { return true; } } return false; } // 示例:定义多个多边形 $polygonA = array( new Point(54.992883, -9.860767), new Point(54.992775, -9.860289), new Point(54.992236, -9.861030), new Point(54.992473, -9.862007) ); $polygonB = array( new Point(55.001234, -9.870123), new Point(55.002345, -9.871234), new Point(55.003456, -9.870345), new Point(55.002345, -9.869234) ); // 所有多边形整理为二维数组 $allPolygons = [$polygonA, $polygonB]; // 调用示例 $targetPoint = new Point(54.9925, -9.861); $isInAny = pointInAnyPolygon($targetPoint, $allPolygons); var_dump($isInAny); // 点落在polygonA内,返回bool(true)
性能优化建议
- 多边形数量较多时,可先计算每个多边形的最小外包矩形(经纬度最大最小值),先判断点是否在矩形内,不在则直接跳过射线法判断,减少不必要的计算
- 若存在互斥的多边形(比如重叠区域取优先级),可调整遍历顺序,优先校验优先级高的多边形,提前返回结果
- 高频调用场景可以将多边形的外包矩形预计算缓存,避免每次校验重复计算
内容的提问来源于stack exchange,提问作者jonas
相关产品推荐
相关产品推荐

