Java生成一个区域内的经纬度随机点的方式

准备:
1、四个角点(四个点确定一个框)
2、想要细分程度 (这里说的是经纬度,这里没有对经纬度做更细的区分)
如:0.000001约等于0.1m,0.00001约等于1m,0.0001约等于10m 。。。
思路:
1、四个角点的lon和lat分别放入lonList和latList中并排序(从小到大)
2、画一个最大框

 左上角的点应当取 lonList的第三位 ,latList的第零位
 左下角的点应当取 lonList的第零位 ,latList的第零位
 右上角的点应当取 lonList的第三位 ,latList的第三位
 右下角的点应当取 lonList的第零位 ,latList的第三位

上面做的就是画了一个极限包含我们需要点的矩形;
3、以左下角为坐标系的中心,根据unit分辨率向resList添加可能点
4、根据四个点确定的矩形来过滤resList的所有可能点,得到我们真正框内的点集合(过滤条件:落在四个点的框内)
ps:我这里得到的四个点无法确认谁左谁右,谁上谁下,所以需要画最大框

演示图:
1、我画了四个点
在这里插入图片描述
2、得到的最大框
在这里插入图片描述
3、过滤后的落点
在这里插入图片描述
此时你需要取随机点random一下list其实就可以了

demo:

    public static void main(String[] args) {
        //1、构建四个角落点
        List<Point> points = Lists.newArrayList(
                new Point(112.5743064, 26.8286825),
                new Point(112.5744284, 26.8283794),
                new Point(112.574591, 26.8284339),
                new Point(112.5745134, 26.8286289)
        );
        //2、对角落点补点
        List<Point> theoryPoints = getInPoints(points.get(0), points.get(1), points.get(2), points.get(3), 0.00002);
        //3、对落在四个角点构建框内的数据进行过滤(注意四个角点需要按照顺时针或者逆时针的形式排列)
        List<Point> inPoints = theoryPoints.stream().filter(point -> isPtInPoly(point.getLon(), point.getLat(), points)).collect(Collectors.toList());
        System.out.println("inPoints = " + inPoints);
    }

实体:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Point {
    private double lon;//经度
    private double lat;//纬度
    private double alt;//高度
    public Point(double lon, double lat) {
        this.lon = lon;
        this.lat = lat;
    }

}

code:
重置四边形,获取四边形内所有点

    /**
     * 
     *
     * @param leftOnPoint    四个角点(可以不按照名称来,因为方法会重新构建最大框)
     * @param leftDownPoint
     * @param rightOnPoint
     * @param rightDownPoint
     * @param unit 分辨率
     * @return
     */
    public static List<Point> getInPoints(Point leftOnPoint, Point leftDownPoint, Point rightOnPoint, Point rightDownPoint, double unit) {
        //重组最符合逻辑的四边形区域
        List<Double> lonList = new ArrayList<>();
        List<Double> latList = new ArrayList<>();
        lonList.add(leftOnPoint.getLon());
        lonList.add(leftDownPoint.getLon());
        lonList.add(rightOnPoint.getLon());
        lonList.add(rightDownPoint.getLon());
        latList.add(leftDownPoint.getLat());
        latList.add(leftOnPoint.getLat());
        latList.add(rightDownPoint.getLat());
        latList.add(rightOnPoint.getLat());
        lonList.sort(Double::compareTo);
        latList.sort(Double::compareTo);
        Point leftOnPointRel = new Point(lonList.get(lonList.size() - 1), latList.get(0));
        Point leftDownPointRel = new Point(lonList.get(0), latList.get(0));
        Point rightOnPointRel = new Point(lonList.get(lonList.size() - 1), latList.get(latList.size() - 1));
        Point rightDownPointRel = new Point(lonList.get(0), latList.get(latList.size() - 1));
        List<Point> list = new ArrayList<>();
        double lon = leftDownPointRel.getLon();
        while (true) {
            double lat = leftDownPointRel.getLat();
            while (true) {
                if (lat >= Math.max(rightDownPointRel.getLat(), rightOnPointRel.getLat())) {
                    break;
                }
                list.add(new Point(lon, lat));
                lat += unit;
            }
            if (lon >= Math.max(leftOnPointRel.getLon(), rightOnPointRel.getLon())) {
                break;
            }
            lon += unit;
        }
        return list;
    }

过滤方法:

   /**
     * 判断某一个经纬度点是否在一组经纬度范围内
     *
     * @param ALon A点经度
     * @param ALat A点纬度
     * @param ps   范围多边形经纬度集合
     * @author Klay
     * @date 2023/2/8 18:06
     */
    public static boolean isPtInPoly(double ALon, double ALat, List<Point> ps) {
        if (CollectionUtils.isEmpty(ps)) {
            logger.warn("当前传入点集合为空");
            return false;
        }
        int iSum, iCount, iIndex;
        double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon;
        if (ps.size() < 3) {
            return false;
        }
        iSum = 0;
        iCount = ps.size();
        for (iIndex = 0; iIndex < iCount; iIndex++) {
            if (iIndex == iCount - 1) {
                dLon1 = ps.get(iIndex).getLon();
                dLat1 = ps.get(iIndex).getLat();
                dLon2 = ps.get(0).getLon();
                dLat2 = ps.get(0).getLat();
            } else {
                dLon1 = ps.get(iIndex).getLon();
                dLat1 = ps.get(iIndex).getLat();
                dLon2 = ps.get(iIndex + 1).getLon();
                dLat2 = ps.get(iIndex + 1).getLat();
            }
            // 以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上
            if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) {
                if (Math.abs(dLat1 - dLat2) > 0) {
                    //得到 A点向左射线与边的交点的x坐标:
                    dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);
                    // 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一:
                    if (dLon < ALon) {
                        iSum++;
                    }
                }
            }
        }
        if ((iSum % 2) != 0) {
            return true;
        }
        return false;
    }

如有纰漏,还望补充,小子改正

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值