这个需求是在绘制地图过程中,通过经纬度边界绘制地图的点阵。有这么几个方法:
- 射线法:从判断点向某个统一方向作射线,依交点个数的奇偶判断;
- 转角法:按照多边形顶点逆时针顺序,根据顶点和判断点连线的方向正负(设定角度逆时针为正)求和判断;
- 夹角和法:求判断点与所有边的夹角和,等于360度则在多边形内部。
- 面积和法:求判断点与多边形边组成的三角形面积和,等于多边形面积则点在多边形内部。
比较下来面积计算比较复杂,角度计算开销比较大,射线法也要对每个边进行求交运算,但总体来说还是比其它方法好一些,下面就是最常用的射线法。
射线法
方法是从验证点向任意方向引一条射线,与多边形相交。计算射线与多边形的边的交点个数。

交点个数为奇数,则判断点在多边形内;偶数,则在多边形外。
但是,有这样的特殊情况: 
因此定义了以下规则:
- 射线与多边形的边重叠不计。
- 相交点是边的上端点时不计。
这时:
a:与边6一个交点
b:与边4一个交点,与边3交点不计。
c:与边1、2交点不计,与边3一个交点。
d:与边4交点不计,与边5平行不计,与边6一个交点。
那么下面说说代码实现:(由于我获取的地理边界是PHP接口,下面用PHP说明,当然,翻译成别的语言也很容易)
/** @pt* @polys*/function PointInPoly($pt, $polys) {$c = 0; //$l = count($polys); //$p1 = $polys[0];for ($i = 1; $i <= $l; $i++) {$p2 = $polys[$i]; // p1p2if ($pt[0] > min([$p1[0], $p2[0]])&& $pt[0] <= max([$p1[0], $p2[0]])&& $pt[1] <= max([$p1[1], $p2[1]])&& $p1[0] != $p2[0]) {if ($p1[1] == $p2[1]) {$c++;} else {$x = ($pt[0] - $p1[0]) * ($p2[1] - $p1[1]) / ($p2[0] - $p1[0]) + $p1[1];if ($pt[1] <= $x) {$c++;}}}$p1 = $p2;}return $c % 2 != 0;}
