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