针对如何判断点是否在某一个不规则封闭区域内,主要采用的是向量积法,算法原理参考:
> https://blog.csdn.net/ezhchai/article/details/78864336?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
向量积计算参考:
> https://blog.csdn.net/qq_15906905/article/details/97074749?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
向量积法的核心是通过判断相邻边与待定点间的向量叉积(非点积)符号是否相同来判断,但该算法必须要求不规则多边形为凸多变形。但不规则多边形可以剖分成很多个三角形区域。因此,下面的function主要考虑的是三角形,该function针对叉积为0,待定点在边延长线上或在边上,均进行了处理:
def isInArea(lon: Double, lat: Double): Boolean = {
var isIn = true
val area = Array((113.517068, 22.938879), (114.86467, 23.291998), (114.149475, 21.972672))
val areaArea = new ArrayBuffer[(Double, Double)]()
for (i <- 0 until (area.length - 1)) {
areaArea.append((area(i + 1)._1 - area(i)._1, area(i + 1)._2 - area(i)._2))
}
areaArea.append((area.head._1 - area.last._1, area.head._2 - area.last._2))
val vector = new ArrayBuffer[(Double, Double)]()
for (vertex <- area) {
vector.append((lon - vertex._1, lat - vertex._2))
}
var vcp_pre = 0.0
var flag = true
for (i <- 0 until (area.length - 1) if flag) {
vcp_pre = vector(i)._1 * areaArea(i)._2 - vector(i)._2 * areaArea(i)._1
val vcp = vector(i + 1)._1 * areaArea(i + 1)._2 - vector(i + 1)._2 * areaArea(i + 1)._1
val cp = vcp_pre * vcp
if (cp == 0.0) {
flag = false
if (vcp_pre == 0.0) {
if ((lon - area(i)._1) * (lon - area(i + 1)._1) > 0) isIn = false
} else {
if (i < area.length - 2) {
if ((lon - area(i + 1)._1) * (lon - area(i + 2)._1) > 0) isIn = false
} else {
if ((lon - area.head._1) * (lon - area.last._1) > 0) isIn = false
}
}
} else if (cp < 0) {
flag = false
isIn = false
}
}
isIn
}