package com.yssh.utils;
|
|
import java.awt.geom.Point2D;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
|
import com.yssh.entity.Coordinate;
|
import com.yssh.entity.DistanceSuYuan;
|
import com.yssh.entity.MonitorPointPosition;
|
import org.geotools.geometry.DirectPosition2D;
|
import org.geotools.referencing.CRS;
|
import org.geotools.referencing.GeodeticCalculator;
|
import org.geotools.referencing.crs.DefaultGeographicCRS;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|
public class CalculateUtils {
|
private final static SimpleDateFormat ymdh = new SimpleDateFormat("yyyyMMddHH");
|
|
/**
|
* 获取年月日时
|
*/
|
public static String getYearMonthDayHour(Date date) {
|
return ymdh.format(date);
|
}
|
|
/**
|
* 默认地球半径,赤道半径(单位m)
|
*/
|
private final static double EARTH_RADIUS1 = 6371000;
|
|
/**
|
* 转化为弧度(rad)
|
*/
|
private static double rad(double d) {
|
return d * Math.PI / 180.0;
|
}
|
|
/**
|
* 计算距离1
|
*/
|
public static double getDistance1(double lon1, double lat1, double lon2, double lat2) {
|
double radLat1 = rad(lat1);
|
double radLat2 = rad(lat2);
|
double a = radLat1 - radLat2;
|
double b = rad(lon1) - rad(lon2);
|
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_RADIUS1;
|
|
return round2(s);
|
}
|
|
/**
|
* 计算距离2
|
*/
|
public static double getDistance2(double x1, double y1, double x2, double y2) {
|
// 84坐标系构造GeodeticCalculator
|
GeodeticCalculator geodeticCalculator = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
|
|
// 起点经纬度
|
geodeticCalculator.setStartingGeographicPoint(x1, y1);
|
|
// 末点经纬度
|
geodeticCalculator.setDestinationGeographicPoint(x2, y2);
|
|
// 计算距离,单位:米
|
double distance = geodeticCalculator.getOrthodromicDistance();
|
|
return round2(distance);
|
}
|
|
/**
|
* 保留2位小数
|
*/
|
public static double round2(double d) {
|
return ((long) (d * 100)) / 100D;
|
}
|
|
/**
|
* 保留6位小数
|
*/
|
public static double round6(double d) {
|
return ((long) (d * 1000000)) / 1000000D;
|
}
|
|
/**
|
* 计算角度
|
*/
|
public static double getAngle(double x1, double y1, double x2, double y2) {
|
try {
|
CoordinateReferenceSystem crs = CRS.decode("EPSG:4326");
|
DirectPosition2D p1 = new DirectPosition2D(crs, x1, y1);
|
DirectPosition2D p2 = new DirectPosition2D(crs, x2, y2);
|
|
GeodeticCalculator gc = new GeodeticCalculator();
|
gc.setStartingGeographicPoint(p1);
|
gc.setDestinationGeographicPoint(p2);
|
|
double angle = gc.getAzimuth();
|
|
return round2(angle);
|
} catch (Exception ex) {
|
return 0;
|
}
|
}
|
|
/**
|
* 计算角度2
|
*/
|
public static double getAngle2(double x1, double y1, double x2, double y2) {
|
try {
|
DirectPosition2D p1 = new DirectPosition2D(x1, y1);
|
DirectPosition2D p2 = new DirectPosition2D(x2, y2);
|
|
GeodeticCalculator gc = new GeodeticCalculator();
|
gc.setStartingGeographicPoint(p1);
|
gc.setDestinationGeographicPoint(p2);
|
|
double angle = gc.getAzimuth();
|
|
return round2(angle);
|
} catch (Exception ex) {
|
return 0;
|
}
|
}
|
|
/**
|
* 获取坐标
|
*
|
* @param su
|
* @return
|
*/
|
public static Coordinate getCoordinate(DistanceSuYuan su) {
|
String[] sirs = su.getId().split("_");
|
|
int x = Integer.parseInt(sirs[0]);
|
int y = Integer.parseInt(sirs[1]);
|
double lon = CalculateUtils.getLon(x, y);
|
double lat = CalculateUtils.getLat(x, y);
|
|
return new Coordinate(lon, lat);
|
}
|
|
/**
|
* 计算经度
|
*
|
* @param @param x
|
* @param @param y
|
* @param @return 参数
|
* @return double 返回类型
|
* @throws
|
* @Title: getLon
|
* @Description: 计算经度
|
*/
|
public static double getLon(int x, int y) {
|
double lon = 115.9165227 + 0.000116732 * (x - 0.5) + 0.00000116862 * (y - 0.5);
|
if (lon < 115 || lon > 116) {
|
System.out.println("lon is invalid");
|
}
|
|
return round6(lon);
|
}
|
|
/**
|
* 计算维度
|
*
|
* @param @param x
|
* @param @param y
|
* @param @return 参数
|
* @return double 返回类型
|
* @throws
|
* @Title: getLat
|
* @Description: 计算维度
|
*/
|
public static double getLat(int x, int y) {
|
double lat = 39.77250000 + 0.000001000 * (x - 0.5) - 0.00009000000 * (y - 0.5);
|
if (lat < 39 || lat > 40) {
|
System.out.println("lat is invalid");
|
}
|
|
return round6(lat);
|
}
|
|
/**
|
* @param @param checkPoints
|
* @param @return 参数
|
* @return List<String> 返回类型
|
* @throws
|
* @Title: assembleId
|
* @Description: 组装id
|
*/
|
public static List<String> assembleId(List<MonitorPointPosition> checkPoints) {
|
List<String> ids2d = new ArrayList<>();
|
for (MonitorPointPosition point : checkPoints) {
|
// ids2d.add(point.getX() + "_" + point.getY() + "_" + point.getZ());
|
ids2d.add(point.getX() + "_" + point.getY() + "_" + 0);
|
}
|
return ids2d;
|
}
|
|
/**
|
* @param @param checkPoint
|
* @param @param range
|
* @param @return 参数
|
* @return List<String> 返回类型
|
* @Title: aloneCrosswiseScope
|
* @Description: 单独点位横向范围扩展
|
* @backup 强制将层级改为 0
|
*/
|
public static List<String> aloneCrosswiseExtend(MonitorPointPosition checkPoint, int range) {
|
List<String> ids = new ArrayList<>();
|
Integer x = checkPoint.getX();
|
Integer y = checkPoint.getY();
|
for (int i = x - range / 2; i <= x + range / 2; i++) {
|
for (int j = y - range / 2; j <= y + range / 2; j++) {
|
// ids.add(i + "_" + j + "_" + checkPoint.getZ());
|
ids.add(i + "_" + j + "_" + 0);
|
}
|
}
|
return ids;
|
}
|
|
public static List<String> temporary(MonitorPointPosition point, int range) {
|
List<String> ids3d = new ArrayList<>();
|
Integer x = point.getX();
|
Integer y = point.getY();
|
Integer z = point.getZ();
|
for (int i = x - range / 2; i <= x + range / 2; i++) {
|
for (int j = y - range / 2; j <= y + range / 2; j++) {
|
for (int k = z; k < 100; k++) {
|
ids3d.add(i + "_" + j + "_" + k);
|
}
|
}
|
}
|
return ids3d;
|
}
|
|
/**
|
* 获取方向
|
*/
|
public static String getDir(double direction) {
|
if (direction < 0) {
|
direction = direction + 360;
|
}
|
if (direction > 360) {
|
direction = direction - 360;
|
}
|
|
if (direction >= 22.5 && direction < 67.5)
|
return "东北";
|
if (direction >= 67.5 && direction < 112.5)
|
return "东";
|
if (direction >= 112.5 && direction < 157.5)
|
return "东南";
|
if (direction >= 157.5 && direction < 202.5)
|
return "南";
|
if (direction >= 202.5 && direction < 247.5)
|
return "西南";
|
if (direction >= 247.5 && direction < 292.5)
|
return "西";
|
if (direction >= 292.5 && direction < 337.5)
|
return "西北";
|
|
return "北";
|
}
|
|
/**
|
* 计算X、Y值的矩形框
|
*/
|
public static List<Coordinate> calcRect(double x, double y) {
|
double buffer = 10;
|
double dis = round6(Math.sqrt(Math.pow(buffer / 2, 2) * 2));
|
|
List<Coordinate> list = new ArrayList<>();
|
list.add(getPointByDisAndAngle(x, y, 315, dis));
|
list.add(getPointByDisAndAngle(x, y, 45, dis));
|
list.add(getPointByDisAndAngle(x, y, 135, dis));
|
list.add(getPointByDisAndAngle(x, y, 225, dis));
|
|
return list;
|
}
|
|
/**
|
* 根据距离和角度获取目标点
|
*/
|
private static Coordinate getPointByDisAndAngle(double x, double y, double angle, double dis) {
|
try {
|
DirectPosition2D p1 = new DirectPosition2D(x, y);
|
|
GeodeticCalculator gc = new GeodeticCalculator();
|
gc.setStartingGeographicPoint(p1);
|
gc.setDirection(angle, dis);
|
|
Point2D dest = gc.getDestinationGeographicPoint();
|
double newX = round6(dest.getX());
|
double newY = round6(dest.getY());
|
|
return new Coordinate(newX, newY);
|
} catch (Exception ex) {
|
return new Coordinate();
|
}
|
}
|
|
/**
|
* @param @return 参数
|
* @return Double 返回类型
|
* @throws
|
* @Title: getWindSpeed
|
* @Description: 计算风速
|
*/
|
public static Double getWindSpeed(double v, double u) {
|
return round6(Math.sqrt(v * v + u * u));
|
}
|
|
/**
|
* @param @param v
|
* @param @param u
|
* @param @return 参数
|
* @return double 返回类型
|
* @throws
|
* @Title: getWindDirection
|
* @Description: 计算风向
|
*/
|
public static double getWindDirection(double v, double u) {
|
double result = Math.atan(u / (v + Math.pow(10, -5))) / Math.PI * 180;
|
if (result < 0) {
|
result += 180;
|
} else if (u < 0 && v > 0) {
|
result += 360;
|
}
|
|
return round6(result);
|
}
|
|
/**
|
* @param @param list 排序对象
|
* @param @param property 排序参数
|
* @param @param order 排序顺序
|
* @param @return 参数
|
* @return List<Map < String, Object>> 返回类型
|
* @throws
|
* @Title: sort
|
* @Description: 排序
|
*/
|
public static List<Map<String, Object>> sort(List<Map<String, Object>> list, final String property, final boolean order) {
|
if (list == null || property == null) {
|
return null;
|
}
|
Collections.sort(list, new Comparator<Map<String, Object>>() {
|
@Override
|
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
|
try {
|
Object oo1 = o1.get(property);
|
Object oo2 = o2.get(property);
|
if (oo1 == null || "null".equals(oo1.toString()) || "".equals(oo1.toString()) || oo1.toString().endsWith("999")) {
|
oo1 = 0;
|
}
|
if (oo2 == null || "null".equals(oo2.toString()) || "".equals(oo2.toString()) || oo2.toString().endsWith("999")) {
|
oo2 = 0;
|
}
|
if (order) {
|
if (Double.parseDouble(oo1.toString()) < Double.parseDouble(oo2.toString())) {
|
return 1;
|
}
|
} else {
|
if (Double.parseDouble(oo1.toString()) > Double.parseDouble(oo2.toString())) {
|
return 1;
|
}
|
}
|
if (Double.parseDouble(oo1.toString()) == Double.parseDouble(oo2.toString())) {
|
return 0;
|
}
|
} catch (Exception ex) {
|
System.out.println(ex.getMessage());
|
}
|
return -1;
|
}
|
});
|
return list;
|
}
|
}
|