package com.artfess.manage.utils; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; import com.artfess.base.util.StringUtil; import java.util.ArrayList; import java.util.List; public class GeoUtils { static class Point { float x; float y; Point() { } Point(float x, float y) { this.x = x; this.y = y; } } public static boolean pointInPolygon(String p, String polyStr) { if (StringUtil.isEmpty(polyStr)) { return false; } List polys = new ArrayList(); JSONUtil.parseArray(polyStr).forEach(e -> { JSONArray pt = (JSONArray) e; polys.add(new Point(Float.valueOf(pt.get(0) + ""), Float.valueOf(pt.get(1) + ""))); }); String[] point = p.split(","); return ray(new Point(Float.valueOf(point[0] + ""), Float.valueOf(point[1] + "")), polys); } public static boolean ray(Point p, List poly) { float nx = p.x; float ny = p.y; int cnt = 0; //计算射线穿过多边形的点的数目 int len = poly.size(); for (int i = 0, j = len - 1; i < len; j = i, ++i) { float bx = poly.get(i).x; float by = poly.get(i).y; float ux = poly.get(j).x; float uy = poly.get(j).y; //点与多边形顶点重合 if ((nx == bx && ny == by) || (nx == ux && nx == uy)) { return true; } if ((by < ny && uy >= ny) || (by >= ny && uy < ny)) { //边上与点的坐标y相同的x坐标 float x = bx + (ny - by) * (ux - bx) / (uy - by); //点在多边形的边上 if (x == nx) { return true; } if (x > nx) { cnt += 1; } } } if (cnt % 2 == 1) { return true; } else { return false; } } }