获取水库流域并判断雨量站是否在水库流域范围内或附近
准备工作
- 水库流域区域的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("该雨量站不在水库流域范围或流域边界附近。");
}
}
}