JAVA判断一个地理坐标是否在一个多边形区域内和是否在一个圆形区域内(经纬度)

怎么样判断一个坐标点在一个多边形区域内?包括规则多边形,不规则多边形,还有圆。。。

1 判断一个坐标是否在圆形区域内?

多边形和圆分开写,首先简单的就是判断是否在圆里面,如何判断一个坐标是否在圆形区域内,相信不用我说都知道,计算这个坐标点和圆心之间的距离,然后跟圆的半径进行比较,如果比半径大,就不在圆形区域内,如果小于等于圆的半径,则该坐标点在圆形区域内。

数学上的计算公式是这样的:

代码采用谷歌地图计算距离的方式,应该算是比较精确。

private static double EARTH_RADIUS = 6378.137;

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 通过经纬度获取距离(单位:米)
     *
     * @param lat1
     * @param lng1
     * @param lat2
     * @param lng2
     * @return
     */
    public static double getDistance(double lat1, double lng1, double lat2,
                                     double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        return s;
    }

    /**
     * 判断一个点是否在圆形区域内
     */
    public static boolean isInCircle(double lng1, double lat1, double lng2, double lat2, String radius) {
        return getDistance(lat1, lng1, lat2, lng2) > Double.parseDouble(radius);
    }
### 使用 JTS Geometry API 判断是否经纬度围栏内 为了判断一个圆形区域是否位于由经纬度定义的地理围栏内,可以利用 `JTS Topology Suite (JTS)` 库中的几何对象及其关系操作。具体来说,通过创建表示圆形多边形(围栏)的几何形状,并调用相应的函数来检测它们之间的包含关系。 #### 创建几何对象 首先需要构建两个几何实体:一个是代表圆形的对象;另一个则是描述地理围栏边界线或多边形结构。对于圆形而言,在实际应用中通常会将其近似为具有足够数量顶点的正多边形[^1]。 ```java import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.geom.LinearRing; import org.locationtech.jts.geom.Coordinate; // 定义工厂实例用于创建几何体 GeometryFactory geometryFactory = new GeometryFactory(); // 坐标以及半径参数设置 double centerX = 0; // 替换为目标位置经度值 double centerY = 0; // 替换为目标位置纬度值 double radiusInDegrees = 0.01; // 半径大小取决于应用场景需求, 这里假设单位是度数 int numberOfSides = 36; // 控制精度: 边越多越接近真实圆形 List<Coordinate> circleCoordinates = new ArrayList<>(); for(int i=0;i<=numberOfSides;i++){ double angle = Math.toRadians(i * 360 / numberOfSides); double offsetX = radiusInDegrees * Math.cos(angle); double offsetY = radiusInDegrees * Math.sin(angle); Coordinate coordinate = new Coordinate(centerX + offsetX ,centerY +offsetY ); circleCoordinates.add(coordinate); } LinearRing shell = geometryFactory.createLinearRing(circleCoordinates.toArray(new Coordinate[circleCoordinates.size()])); Polygon polygonCircleApproximation = geometryFactory.createPolygon(shell,null); // 构建围栏多边形... // 假设有一个 List<Coordinate> fencePoints 存储了构成围栏轮廓的一系列点位数据 LinearRing fenceShell = geometryFactory.createLinearRing(fencePoints.toArray(new Coordinate[fencePoints.size()])); Polygon geofencePolygon = geometryFactory.createPolygon(fenceShell, null); ``` #### 执行空间查询 一旦拥有了上述两种类型的几何图形之后,则可通过调用 `within()` 方法测试前者是否完全处于后者内部: ```java boolean isWithinGeofence = polygonCircleApproximation.within(geofencePolygon); System.out.println("The circular area " + (isWithinGeofence ? "" : "does not ") +"lie within the defined geographic boundary."); ``` 此过程基于矢量运算完成,因此能够高效而精确地处理复杂的地理位置逻辑判定问题[^2]。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值