| | |
| | | |
| | | /** |
| | | * 获取两经纬度间的距离 |
| | | * @return 返回两点间距离,单位:米 |
| | | */ |
| | | fun getDistance(lng1: Double, lat1: Double, lng2: Double, lat2: Double): Double { |
| | | // lat1 = lat1 || 0; |
| | |
| | | result; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断坐标点是否在多边形的四至范围内 |
| | | * @param point 坐标点 |
| | | * @param polygon 多边形坐标点数组 |
| | | */ |
| | | fun inBBox(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>): Boolean { |
| | | |
| | | val x = point.first |
| | | val y = point.second |
| | | // 计算多边形顶点经度范围和纬度范围 |
| | | val xsSort = polygon.map { it.first }.sorted() |
| | | val ysSort = polygon.map { it.second }.sorted() |
| | | |
| | | val xMin = xsSort[0] |
| | | val yMin = ysSort[0] |
| | | val xMax = xsSort[xsSort.lastIndex] |
| | | val yMax = ysSort[ysSort.lastIndex] |
| | | |
| | | return x >= xMin && x <= xMax && y >= yMin && y <= yMax |
| | | } |
| | | |
| | | /** |
| | | * 判断坐标点是否在多边形的边上 |
| | | * @param point 坐标点 |
| | | * @param polygon 多边形坐标点数组 |
| | | */ |
| | | fun onBorder(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>): Boolean { |
| | | var res = false |
| | | // 循环判断每一条边 |
| | | for (i in polygon.indices) { |
| | | val p1 = polygon[i] |
| | | val p2 = if (i + 1 == polygon.size) { |
| | | polygon[0] |
| | | } else { |
| | | polygon[i + 1] |
| | | } |
| | | // 计算边的两个顶点纬度差和经度差的比值 |
| | | val k1 = (p2.second - p1.second) / (p2.first - p1.first) |
| | | // 计算坐标点和其中一个顶点的纬度差和经度差的比值 |
| | | val k2 = (p2.second - point.second) / (p2.first - point.first) |
| | | // 如果比值相同,说明三个点在同一直线上,即坐标点在边上 |
| | | if (k1 == k2) { |
| | | res = true |
| | | break |
| | | } |
| | | } |
| | | return res |
| | | } |
| | | |
| | | /** |
| | | * 判断坐标点是否在多边形内部(射线法) |
| | | * @param point 坐标点 |
| | | * @param polygon 多边形坐标点数组 |
| | | */ |
| | | fun inPolygon(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>):Boolean { |
| | | val x = point.first |
| | | val y = point.second |
| | | var j = polygon.size - 1 |
| | | var odd = false |
| | | for (i in polygon.indices) { |
| | | if ( |
| | | ((polygon[i].second > y) != (polygon[j].second > y)) |
| | | && (x < ((polygon[j].first - polygon[i].first) * (y - polygon[i].second) |
| | | / (polygon[j].second - polygon[i].second) + polygon[i].first)) |
| | | ) { |
| | | odd = !odd; |
| | | } |
| | | j = i; |
| | | } |
| | | return odd |
| | | } |
| | | |
| | | /** |
| | | * 判断坐标点是否在多边形内部 |
| | | */ |
| | | fun isPointInPolygon(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>): Boolean { |
| | | if (polygon.size < 3) throw IllegalArgumentException("not a polygon") |
| | | |
| | | // 不在四至范围内,则一定不在多边形内 |
| | | if (!inBBox(point, polygon)) return false |
| | | // 在多边形边上,也认为在多边形内 |
| | | if (onBorder(point, polygon)) return true |
| | | // 计算是否在多边形内部 |
| | | return inPolygon(point, polygon) |
| | | } |
| | | } |