java判斷座標是否在多邊形內
阿新 • • 發佈:2018-12-21
正經學徒,佛系記錄,不搞事情
/** * 判斷點是否在多邊形內 * @param point 檢測點 * @param pts 多邊形的頂點 * @return 點在多邊形內返回true, 否則返回false */ public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts) { int N = pts.size(); boolean boundOrVertex = true; //如果點位於多邊形的頂點或邊上,也算做點在多邊形內,直接返回true int intersectCount = 0;//cross points count of x double precision = 2e-10; //浮點型別計算時候與0比較時候的容差 Point2D.Double p1, p2;//neighbour bound vertices Point2D.Double p = point; //當前點 p1 = pts.get(0);//left vertex for (int i = 1; i <= N; ++i) {//check all rays if (p.equals(p1)) { return boundOrVertex;//p is an vertex } p2 = pts.get(i % N);//right vertex if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) {//ray is outside of our interests p1 = p2; continue;//next ray left point } if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) {//ray is crossing over by the algorithm (common part of) if (p.y <= Math.max(p1.y, p2.y)) {//x is before of ray if (p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)) {//overlies on a horizontal ray return boundOrVertex; } if (p1.y == p2.y) {//ray is vertical if (p1.y == p.y) {//overlies on a vertical ray return boundOrVertex; } else {//before ray ++intersectCount; } } else {//cross point on the left side double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y if (Math.abs(p.y - xinters) < precision) {//overlies on a ray return boundOrVertex; } if (p.y < xinters) {//before ray ++intersectCount; } } } } else {//special case when ray is crossing through the vertex if (p.x == p2.x && p.y <= p2.y) {//p crossing over p2 Point2D.Double p3 = pts.get((i + 1) % N); //next vertex if (p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) {//p.x lies between p1.x & p3.x ++intersectCount; } else { intersectCount += 2; } } } p1 = p2;//next ray left point } return intersectCount % 2 != 0; }
使用方法(親測可用):
List<Point2D.Double> polygon = new ArrayList<Point2D.Double>(); for(Map<String,Double> item : list){ polygon.add(new Point2D.Double(item.get("lon"),item.get("lat"))); } Point2D.Double point = new Point2D.Double(param.get("lon"),param.get("lat")); boolean flag = GeoUtil.IsPtInPoly(point, polygon);