Java 获取水库流域并判断雨量站是否在水库流域范围内或附近

获取水库流域并判断雨量站是否在水库流域范围内或附近

在这里插入图片描述

准备工作

  • 水库流域区域的geojson文件
  • 雨量站的经纬度

工具类

这里有两个方法:

  • isInsideBoundary:判断雨量站是否在流域范围内
  • calculateNearestDistance:计算雨量站和流域边界点最近距离
    下面测试数据不是真实的数据,如果需要用真实数据可以上https://hxkj.vip/demo/echartsMap/下载
/**
 * 流域范围检查器
 */
public final class WatershedCheckerUtils {
    
    
    /**
     * 地球半径(单位:米)
     */
    public static final double RADIUS = 6371000;


    /**
     * 判断雨量站是否在流域范围内
     *
     * @param latitude             纬度
     * @param longitude            经度
     * @param distanceThreshold    距离阈值(米)
     * @param watershedCoordinates 流域经纬度点集合
     * @return 是否在范围内或距离阈值附近
     */
    public static boolean isWithinWatershed(double latitude, double longitude, double distanceThreshold, List<Coordinate> watershedCoordinates) {
    
    
        Coordinate point = new Coordinate(latitude, longitude);

        // 判断是否在流域范围内
        if (isInsideBoundary(point, watershedCoordinates)) {
    
    
            return true;
        }

        // 判断是否在流域范围附近
        double nearestDistance = calculateNearestDistance(point, watershedCoordinates);
        return nearestDistance <= distanceThreshold;
    }

    /**
     * 是否在流域内
     *
     * @param point                雨量站经纬度点
     * @param watershedCoordinates 流域经纬度点集合
     * @return 是否在范围内
     */
    private static boolean isInsideBoundary(Coordinate point, List<Coordinate> watershedCoordinates) {
    
    
        int numCoordinates = watershedCoordinates.size();
        int i, j;
        boolean isInside = false;

        for (i = 0, j = numCoordinates - 1; i < numCoordinates; j = i++) {
    
    
            if ((watershedCoordinates.get(i).getLatitude() > point.getLatitude()) != (watershedCoordinates.get(j).getLatitude() > point.getLatitude()) && (point.getLongitude() < (watershedCoordinates.get(j).getLongitude() - watershedCoordinates.get(i).getLongitude()) * (point.getLatitude() - watershedCoordinates.get(i).getLatitude()) / (watershedCoordinates.get(j).getLatitude() - watershedCoordinates.get(i).getLatitude()) + watershedCoordinates.get(i).getLongitude())) {
    
    
                isInside = !isInside;
            }
        }

        return isInside;
    }

    /**
     * 计算雨量站和流域边界点最近距离
     *
     * @param point                雨量站
     * @param watershedCoordinates 流域经纬度点集合
     * @return 距离
     */
    private static double calculateNearestDistance(Coordinate point, List<Coordinate> watershedCoordinates) {
    
    
        double nearestDistance = Double.MAX_VALUE;

        for (Coordinate coordinate : watershedCoordinates) {
    
    
            double distance = calculateDistance(point, coordinate);
//            System.out.println("距离:" + distance);
            if (distance < nearestDistance) {
    
    
                nearestDistance = distance;
            }
        }
        return nearestDistance;
    }

    /**
     * 计算距离
     *
     * @param point1 经纬度点1
     * @param point2 经纬度点2
     * @return 距离
     */
    private static double calculateDistance(Coordinate point1, Coordinate point2) {
    
    
        // 使用合适的距离计算方法,例如球面距离计算方法(Haversine公式)
        // 这里仅作示例,实际应使用适当的算法计算经纬度之间的距离
        double lat1 = point1.getLatitude();
        double lon1 = point1.getLongitude();
        double lat2 = point2.getLatitude();
        double lon2 = point2.getLongitude();

        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);

        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        // 计算距离
        return RADIUS * c;
    }

    /**
     * 坐标对象
     */
    public static class Coordinate {
    
    
        private final double latitude;
        private final double longitude;

        public Coordinate(double latitude, double longitude) {
    
    
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public double getLatitude() {
    
    
            return latitude;
        }

        public double getLongitude() {
    
    
            return longitude;
        }
    }

    public static void main(String[] args) {
    
    
        // 水库流域多边形的经纬度坐标
        double[][] watershedPolygon = {
    
    {
    
    112.2246504706506, 27.89331894735409}, {
    
    112.2231667245805, 27.8930976929575}, {
    
    112.2224171616424, 27.89312740614747}, {
    
    112.2198125288585, 27.89301372302097}, {
    
    112.2196147264229, 27.89244937140164}, {
    
    112.2196668624246, 27.89113398578384}, {
    
    112.21952504016, 27.89068603600653}, {
    
    112.2193137144224, 27.8904902354301}, {
    
    112.2192123456666, 27.89038083003742}, {
    
    112.2191029388865, 27.89027945864563}, {
    
    112.2189129661487, 27.89007442872255}, {
    
    112.2175221143923, 27.88996329410949}, {
    
    112.2174470057183, 27.88995729432916}, {
    
    112.2174498585854, 27.88988531066292}, {
    
    112.2173551362723, 27.88978308241103}, {
    
    112.2167842406153, 27.88964708935508}, {
    
    112.2167884954947, 27.88953973282437}, {
    
    112.2167808562865, 27.88934697976116}, {
    
    112.2168897859177, 27.88911617359126}, {
    
    112.2171045825144, 27.88880402278665}, {
    
    112.2172059506644, 27.88848384434527}, {
    
    112.2175111158424, 27.888339822815}, {
    
    112.2175324807167, 27.88780082778409}, {
    
    112.217509067572, 27.88721015284263}, {
    
    112.2179244645362, 27.88742996063582}, {
    
    112.2180530757113, 27.8873285917933}, {
    
    112.2181260141776, 27.88724986894875}, {
    
    112.2182598322594, 27.88627069232016}, {
    
    112.2183692408542, 27.88616931780004}, {
    
    112.2184706092277, 27.88605991678046}, {
    
    112.2188921621296, 27.88566932946918}, {
    
    112.218790793744, 27.88532219906094}, {
    
    112.218575842229, 27.88522074742269}, {
    
    112.2185807599619, 27.88509662854803}, {
    
    112.2181698045139, 27.88471585707811}, {
    
    112.2178190115458, 27.88391201574675}, {
    
    112.2175765397946, 27.88314614977452}, {
    
    112.2167147737508, 27.88294087938481}, {
    
    112.2165776416651, 27.88279288310572}, {
    
    112.2154846386031, 27.88264351067128}, {
    
    112.2152031281464, 27.88238266451835}, {
    
    112.2152511455304, 27.88117117689022}, {
    
    112.2147860429185, 27.88057973119688}, {
    
    112.2146380046403, 27.8804425675033}, {
    
    112.2144369123269, 27.8798688380282}, {
    
    112.2145752661971, 27.87974064078881}, {
    
    112.2146766341976, 27.87920968513857}, {
    
    112.214786043442, 27.87910831073689}, {
    
    112.21493006089, 27.87865342560184}, {
    
    112.2151995583769, 27.8783625661762}, {
    
    112.2154183719937, 27.8781598174417}, {
    
    112.2155197399324, 27.87794502832911}, {
    
    112.2160507000779, 27.87710593654217}, {
    
    112.216257457865, 27.8765749808243}, {
    
    112.2163668650884, 27.87647360704769}, {
    
    112.2164682336967, 27.87573187680455}, {
    
    112.2165776419124, 27.87563050105859}, {
    
    112.216679009921, 27.87499415909271}, {
    
    112.2171045827558, 27.87489278461579}, {
    
    112.2172210283142, 27.874767108822}, {
    
    112.2178960718794, 27.8747938674865}, {
    
    112.2181584639044, 27.87415506688821}, {
    
    112.2182598326079, 27.87362411321668}, {
    
    112.2183692411514, 27.8735227388104}, {
    
    112.2184706094095, 27.87341333606456}, {
    
    112.2190855927294, 27.87321862865826}, {
    
    112.2193112403756, 27.87300955022748}, {
    
    112.2195168841772, 27.87257382091527}, {
    
    112.219739286586, 27.87246885645125}, {
    
    112.2200413284838, 27.87120082815764}, {
    
    112.2208438522431, 27.87114949750527}, {
    
    112.2208945366746, 27.87120419949201}, {
    
    112.223160681661, 27.87142134274053}, {
    
    112.2233224847731, 27.87172712655238}, {
    
    112.2234238522755, 27.87194191607127}, {
    
    112.2235332601317, 27.87204329002644}, {
    
    112.2236346284771, 27.87352273851447}, {
    
    112.2245032024569, 27.87376485327822}, {
    
    112.224692530259, 27.87394027765809}, {
    
    112.2247938985388, 27.87404967949735}, {
    
    112.2251140833647, 27.87415105354112}, {
    
    112.2253044145829, 27.87435646519443}, {
    
    112.225812157801, 27.87448951205519}, {
    
    112.2265539013187, 27.87446011641715}, {
    
    112.2266908858294, 27.87489278431157}, {
    
    112.2271330894607, 27.87503279174681}, {
    
    112.2275315174725, 27.87540195960172}, {
    
    112.2276393791727, 27.8756305016523}, {
    
    112.2277487876063, 27.87573187654111}, {
    
    112.2278501555499, 27.87584127780409}, {
    
    112.228245689134, 27.87602794599981}, {
    
    112.2283811162184, 27.87615342885849}, {
    
    112.2284824845523, 27.87647360688423}, {
    
    112.2288574378002, 27.87659232350777}, {
    
    112.2294309815446, 27.877211323738}, {
    
    112.2295403830912, 27.87731269807101}, {
    
    112.2296417573962, 27.87742210056769}, {
    
    112.2300032378052, 27.87759270072354}, {
    
    112.2304854094745, 27.87803945502226}, {
    
    112.2305902507735, 27.87837059424028}, {
    
    112.2308050408276, 27.87847196825046}, {
    
    112.2309064155897, 27.87974064047511}, {
    
    112.2313319817784, 27.87984201445636}, {
    
    112.2314341735204, 27.88037727860036}, {
    
    112.2321380880584, 27.88034937507136}, {
    
    112.2323818489413, 27.88047835706523}, {
    
    112.2331235809615, 27.88057973127874}, {
    
    112.2333188804765, 27.88079050780895}, {
    
    112.2338612983287, 27.88068913376687}, {
    
    112.2340565977568, 27.8804783572452}, {
    
    112.2349506087328, 27.88058391319544}, {
    
    112.2349472153277, 27.88060167839957}, {
    
    112.2348097915129, 27.88132146235355}, {
    
    112.2346898781698, 27.88143257553994}, {
    
    112.2343038718332, 27.88225047920946}, {
    
    112.234173447936, 27.88237132973355}, {
    
    112.2340720739105, 27.88300767365271}, {
    
    112.2338633118568, 27.88320110760801}, {
    
    112.2337518958277, 27.8841629298505}, {
    
    112.2336386276707, 27.88534498222484}, {
    
    112.2334357314572, 27.88553297622335}, {
    
    112.2333343569863, 27.88616931859086}, {
    
    112.2332249545563, 27.8862706928852}, {
    
    112.2331235809011, 27.88701242389347}, {
    
    112.2329128042736, 27.88781683237312}, {
    
    112.2330141786585, 27.88817169385233}, {
    
    112.233123580827, 27.88848384425996}, {
    
    112.2332249543337, 27.88890941001995}, {
    
    112.2334350952644, 27.88910411895226}, {
    
    112.233448181599, 27.88943434483808}, {
    
    112.2334578644656, 27.88967859537178}, {
    
    112.2333993755356, 27.88986332752537}, {
    
    112.2333343573172, 27.89006868079419}, {
    
    112.2329664118204, 27.89040960974672}, {
    
    112.2327267609908, 27.89116654699214}, {
    
    112.2321670536744, 27.89143069920765}, {
    
    112.2317535342817, 27.8916495028125}, {
    
    112.231433356306, 27.89175087729198}, {
    
    112.2313319819687, 27.89186027951553}, {
    
    112.2304848626397, 27.8921724297101}, {
    
    112.2302781005252, 27.89228183238}, {
    
    112.2283370571502, 27.89239824511845}, {
    
    112.2277679907, 27.89269937071042}, {
    
    112.2276148685367, 27.89245320287092}, {
    
    112.2274052730284, 27.89200908537606}, {
    
    112.2270211052051, 27.89180580987184}, {
    
    112.2269056815369, 27.89186028281022}, {
    
    112.2264961812517, 27.89205354404187}, {
    
    112.2262693340598, 27.89238320429762}, {
    
    112.2261679645963, 27.89301954998214}, {
    
    112.2260585567846, 27.89312092155793}, {
    
    112.2259211934208, 27.89326917501942}, {
    
    112.2254714528641, 27.89303119301607}, {
    
    112.2246504706506, 27.89331894735409}};

        // 定义水库流域的经纬度点
        List<Coordinate> reservoirBounds = new ArrayList<>();
        for (double[] doubles : watershedPolygon) {
    
    
            reservoirBounds.add(new Coordinate(doubles[0], doubles[1]));
        }
        double latitude = 112.21866; // 待检查的纬度
        double longitude = 27.8856; // 待检查的经度

        boolean isWithinWatershed = isWithinWatershed(latitude, longitude, 500, reservoirBounds);

        if (isWithinWatershed) {
    
    
            System.out.println("该雨量站位于水库流域范围或流域边界附近。");
        } else {
    
    
            System.out.println("该雨量站不在水库流域范围或流域边界附近。");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45626288/article/details/131310323
今日推荐