判断一个点是否在多边形内部 - 射线法Scala实现
2018-03-29 16:34
489 查看
原文链接
判断一个点是否在多边形内部 [1] 射线法思路、判断一个点是否在多边形内部 [2] 射线法实现最近有个需求,就是判断一个经纬度落在哪个城市上.用scala实现的
import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} import scala.collection.mutable.ArrayBuffer object Day29 { val sc: SparkContext = scInitialization //初始化sc def main(args: Array[String]): Unit = { getPoint } //判断某个点是否在一个多边形中 /** * * @param p 待测的某个点 类型:元组(Double,Double) * @param poly 存储多个城市边界的多边形顶点 类型:数组 存储的是元组(String,Array[(Double,Double)]) * @return */ def pointInPolygon(p: (Double, Double), poly: Array[(String,Array[(Double,Double)])]): String = { //遍历所有城市 for (i <- poly.indices) { val arrs = poly(i)._2 //取出第i个城市的边界顶点的集合 val f = rayCasting(p, arrs) if (f.equals("in")) { //in表示在第i个城市里面 return poly(i)._1 } } "外星人" } /** * 射线法的实现 * @param p 待测点 类型:元组(Double,Double) * @param poly 城市边界顶点集合 类型:存储元组(Double,Double)的数组 * @return "in"表示待测点在城市里面 "on"表示不在 */ def rayCasting(p: (Double, Double), poly: Array[(Double, Double)]): String ={ val px = p._1 //待测点的经度 相当于x val py = p._2 //带测点的纬度 相当于y var flag = false val l = poly.length var j = l - 1 for(i <-0 until poly.length ) { //取出边界的相邻两个点 val sx = poly(i)._1 val sy = poly(i)._2 val tx = poly(j)._1 val ty = poly(j)._2 // 点与多边形顶点重合 4000 if ((sx == px && sy == py) || (tx == px && ty == py)) { return "in" } // 判断线段两端点是否在射线两侧 //思路:作p点平行于y轴的射线 作s,t的平行线直线 如果射线穿过线段,则py的值在sy和ty之间 if ((sy < py && ty >= py) || (sy >= py && ty < py)) { // 线段上与射线 Y 坐标相同的点的 X 坐标 求射线与线段的交点 val x = sx + (py - sy) * (tx - sx) / (ty - sy) // 点在多边形的边上 if (x == px) { return "on" } // 射线穿过多边形的边界 if (x > px) { flag = !flag } } j = i } // 射线穿过多边形边界的次数为奇数时点在多边形内 if(flag) return "in" else return "on" } //获取多边形数据 /* *用一个集合来存取多边形的顶点,形成一个多边形范围 返回的是存储有n个城市 每个城市有n个边界点 */ def getPolygon: Array[(String,Array[(Double,Double)])] = { val input = sc.textFile("E:\\city.txt") val out = input.map(x => { //清洗数据 val s = x.split("\001")(4) val arr = new ArrayBuffer[(Double, Double)]() val p = s.split("[@;\\|]") for (i <- 0 until p.length if p(i).contains(",")) { val ar = p(i).split(",") arr.append((ar(0).toDouble, ar(1).toDouble)) } (x.split("\001")(1),arr.toArray) })//最后数据格式:(城市名,数组) //将rdd取出到内存中来 val s = out.collect() s } //获取待测点数据 def getPoint():Unit ={ val lines =sc.textFile("E:\\agps.txt") val out = lines.filter(f = x => { //清洗数据 val s = x.split("\\|") s.length > 13 && !s(12).isEmpty && !s(13).isEmpty }).map(f = x => { val s = x.split("\\|") val longitude = s(12).toDouble val latitude = s(13).toDouble ((longitude, latitude),1) }).reduceByKey(_+_).map(x=> x._1 )//最后数据格式 (经度,纬度) val rules = getPolygon //拿到城市边界集合数组 val file = out.map(x =>{ val city = pointInPolygon(x,rules) //并行处理,返回所在的城市名 s"${x._1}|${x._2}|$city" }) file.saveAsTextFile("E:\\output") } //sc初始化 private def scInitialization = { val conf = new SparkConf().setMaster("local").setAppName("Day27") val sc = new SparkContext(conf) sc } }本人只是一个scala初学者,写个播客做个记录备忘。有错误或者更好的见解欢迎留言指导
相关文章推荐
- 判断一个点是否在多边形内部 [2] 射线法实现
- 判断一个点是否在多边形内部 [2] 射线法实现
- 判断一个点是否在多边形内部,射线法思路,C#实现
- JS实现判断点是否在多边形内部(2)--射线法实现
- 判断一个点是否在多边形内部 - 射线法思路
- [射线法]判断一个点是否在多边形内部
- 判断一个点是否在多边形内部 [1] 射线法思路
- JS实现判断点是否在多边形内部(1)--射线法理论
- 判断一个坐标点是否在不规则多边形内部的算法
- 如何判断一个点是否在一个多边形内部(转)
- 点在多边形内算法——判断一个点是否在一个复杂多边形的内部
- 点在多边形内算法——判断一个点是否在一个复杂多边形的内部
- 点在多边形内算法——判断一个点是否在一个复杂多边形的内部
- 点在多边形内算法——判断一个点是否在一个复杂多边形的内部
- 点在多边形内算法,JS判断一个点是否在一个复杂多边形的内部
- 判断一个点是否在一个多边形内部
- JS实现判断点是否在多边形内部(3)--回转数法实现
- [转]如何判断一个点是否在一个多边形内部
- openlayers2 开发如何判断一个marker所在的点是否在一个多边形内部
- 如何判断一个点是否在多边形内部ne?