如何判断某点是否在多边形内?java实现

最近在做一个ai算法,只检测划定的区域内的物体,所以需要判断某点是否在所绘制的区域内,整理了一下,具体代码如下(基本可以直接用)

1.编写点的实体类

//点的实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Point {
        //x坐标
        private Double lngx;
        //y坐标
        private Double laty;
        
}

2.编写检测算法

public class CheckIsInPolygons {

    /**
     * 判断当前位置是否在多边形区域内
     *
     * @param checkPoint 当前经纬度
     * @param areaAround 围栏范围
     * @return
     */
    public static boolean checkIsInPolygon(Point checkPoint, List<Point> areaAround) {
        Point2D.Double point = new Point2D.Double(checkPoint.getLaty(), checkPoint.getLngx());
        List<Point2D.Double> pointList = new ArrayList<>();
        for (Point everyPoint : areaAround) {
            Point2D.Double polygonPoint = new Point2D.Double(everyPoint.getLaty(), everyPoint.getLngx());
            pointList.add(polygonPoint);
        }
        return checkIsPtInPoly(point, pointList);
    }
    /**
     * 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
     *
     * @param point 检测点
     * @param pts   多边形的顶点
     * @return 点在多边形内返回true, 否则返回false
     */
    public static boolean checkIsPtInPoly(Point2D.Double point, List<Point2D.Double> pts) {
        int N = pts.size();
        //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
        boolean boundOrVertex = true;
        //cross points count of x
        int intersectCount = 0;
        //浮点类型计算时候与0比较时候的容差
        double precision = 2e-10;
        //neighbour bound vertices
        Point2D.Double p1, p2;
        //当前点
        Point2D.Double p = point;
        //left vertex
        p1 = pts.get(0);
        //check all rays
        for (int i = 1; i <= N; ++i) {
            if (p.equals(p1)) {
                //p is an vertex
                return boundOrVertex;
            }
            //right vertex
            p2 = pts.get(i % N);
            //ray is outside of our interests
            if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) {
                p1 = p2;
                //next ray left point
                continue;
            }
            //ray is crossing over by the algorithm (common part of)
            if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) {
                //x is before of ray
                if (p.y <= Math.max(p1.y, p2.y)) {
                    //overlies on a horizontal ray
                    if (p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)) {
                        return boundOrVertex;
                    }
                    //ray is vertical
                    if (p1.y == p2.y) {
                        //overlies on a vertical ray
                        if (p1.y == p.y) {
                            return boundOrVertex;
                            //before ray
                        } else {
                            ++intersectCount;
                        }
                    } else {
                        //cross point on the left side
                        //cross point of y
                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;
                        //overlies on a ray
                        if (Math.abs(p.y - xinters) < precision) {
                            return boundOrVertex;
                        }
                        //before ray
                        if (p.y < xinters) {
                            ++intersectCount;
                        }
                    }
                }
            } else {
                //special case when ray is crossing through the vertex
                //p crossing over p2
                if (p.x == p2.x && p.y <= p2.y) {
                    //next vertex
                    Point2D.Double p3 = pts.get((i + 1) % N);
                    //p.x lies between p1.x & p3.x
                    if (p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) {
                        ++intersectCount;
                    } else {
                        intersectCount += 2;
                    }
                }
            }
            //next ray left point
            p1 = p2;
        }
        //偶数在多边形外
        if (intersectCount % 2 == 0) {
            return false;
        } else {
            //奇数在多边形内
            return true;
        }
    }

// 测试算法,返回true,则代表在区域内,返回false,代表不在区域内

 public static void main(String[] args) {
        //待检测的点的坐标
        Point checkPoint=new Point();
        checkPoint.setLngx(3.0);
        checkPoint.setLaty(2.1);

       //区域坐标
        List<Point> areaAround=new ArrayList<>();
        Point areaPoint01=new Point();
        areaPoint01.setLngx(1.0);
        areaPoint01.setLaty(0.0);
        areaAround.add(areaPoint01);

        Point areaPoint02=new Point();
        areaPoint02.setLngx(3.0);
        areaPoint02.setLaty(0.0);
        areaAround.add(areaPoint02);
        Point areaPoint03=new Point();
        areaPoint03.setLngx(3.0);
        areaPoint03.setLaty(2.0);
        areaAround.add(areaPoint03);
        Point areaPoint04=new Point();
        areaPoint04.setLngx(1.0);
        areaPoint04.setLaty(2.0);
        areaAround.add(areaPoint04);
        Boolean res=checkIsInPolygon(checkPoint,areaAround);
        System.out.println(res);
    }


}
在Spring Boot中判断GIS坐标点是否在某地理区域内,你可以使用Java的Geometry库来实现。下面是一个简单的示例代码: 首先,你需要引入相关的依赖: ```xml <dependency> <groupId>org.locationtech.jts</groupId> <artifactId>jts-core</artifactId> <version>1.18.0</version> </dependency> ``` 然后,你可以创建一个方法来判断坐标点是否在指定的地理区域内: ```java import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; public class GisUtils { public static boolean isPointInPolygon(double lat, double lon, double[] polygonCoordinates) { GeometryFactory geometryFactory = new GeometryFactory(); // 创建坐标点 Coordinate coordinate = new Coordinate(lon, lat); Point point = geometryFactory.createPoint(coordinate); // 创建多边形 Coordinate[] coordinates = new Coordinate[polygonCoordinates.length / 2]; for (int i = 0; i < polygonCoordinates.length; i += 2) { coordinates[i / 2] = new Coordinate(polygonCoordinates[i + 1], polygonCoordinates[i]); } Polygon polygon = geometryFactory.createPolygon(coordinates); // 判断是否多边形内 return polygon.contains(point); } } ``` 在上面的代码中,`isPointInPolygon`方法接受一个纬度(lat)、经度(lon)以及地理区域的坐标数组(polygonCoordinates)。它会创建一个坐标点和一个多边形,并使用JTS库的`contains`方法来判断是否多边形内部。 你可以在Spring Boot应用中使用该方法来判断坐标点是否在指定的地理区域内。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值