目录:
- 获取AB连线与正北方向的角度
- 求距离此点一定距离、一定夹角的点经纬度
- 判断point点 在线段startPoint-etartPoint的左侧或者右侧
- 米转换为弧度
- 弧度转换为米
定义Point点
public class LatLngPoint {
final static double RC = 6378137;
final static double RJ = RC;
double longitude, latitude;
double radLongitude, radLatitude;
double Ec;
double Ed;
static final String LatLngPointString = "%.6f:%.6f";
public LatLngPoint(double longitude, double latitude) {
this.longitude = longitude;
this.latitude = latitude;
radLongitude = this.longitude * Math.PI / 180.;
radLatitude = this.latitude * Math.PI / 180.;
Ec = RJ + (RC - RJ) * (90. - latitude) / 90.;
Ed = Ec * Math.cos(radLatitude);
}
public String getString() {
return String.format(LatLngPointString, longitude, latitude);
}
}
import com.vividsolutions.jts.algorithm.Angle;
import com.vividsolutions.jts.geom.Coordinate;
import org.locationtech.spatial4j.distance.DistanceUtils;
import java.math.BigDecimal;
public class LatLngAngleUtil {
/**
* 获取AB连线与正北方向的角度
*
* @param startPoint
* A点的经纬度
* @param endPoint
* B点的经纬度
* @return AB连线与正北方向的角度(0~360)
*/
public static double getAngleByTwoPoint(LatLngPoint startPoint, LatLngPoint endPoint) {
double dx = (endPoint.radLongitude - startPoint.radLongitude) * startPoint.Ed;
double dy = (endPoint.radLatitude - startPoint.radLatitude) * startPoint.Ec;
double angle = 0.0;
angle = Math.atan(Math.abs(dx / dy)) * 180. / Math.PI;
double dLo = endPoint.longitude - startPoint.longitude;
double dLa = endPoint.latitude - startPoint.latitude;
if (dLo > 0 && dLa <= 0) {
angle = (90. - angle) + 90;
} else if (dLo <= 0 && dLa < 0) {
angle = angle + 180.;
} else if (dLo < 0 && dLa >= 0) {
angle = (90. - angle) + 270;
}
return angle;
}
/**
* 求距离此点一定距离、一定夹角的点经纬度
*
* @param distance
* 两点之间的距离 单位 m
* @param angle
* 两点连线与正北方向的夹角(0~360)
* @return 算出的点的经纬度
*/
public static LatLngPoint getLatLngPointByDistanceAndAngle(LatLngPoint startPoint,double distance, double angle) {
double dx = distance * Math.sin(Math.toRadians(angle));
double dy = distance * Math.cos(Math.toRadians(angle));
double bjd = new BigDecimal((dx / startPoint.Ed + startPoint.radLongitude) * 180. / Math.PI)
.setScale(7, BigDecimal.ROUND_HALF_UP).doubleValue();
double bwd = new BigDecimal((dy / startPoint.Ec + startPoint.radLatitude) * 180. / Math.PI)
.setScale(7, BigDecimal.ROUND_HALF_UP).doubleValue();
return new LatLngPoint(bjd, bwd);
}
/**
* 判断point点 在线段startPoint-etartPoint的左侧或者右侧
* @param point 需要判断的点
* @param startPoint 线段开始点
* @param endPoint 线段结束点
* @return 大于0为右侧,小于0为左侧
*/
public static double isLeftOrRight(Coordinate point, Coordinate startPoint, Coordinate endPoint) {
double angleLeft = Angle.angleBetweenOriented(point,startPoint,endPoint);
return angleLeft;
}
/**
* 米转换为弧度
* 弧度=角度*PI/180
* 弧长=半径*弧度
* 地球赤道半径=6378137
* @param me
* @return
*/
public static double meToDegree(double me){
double radius = DistanceUtils.EARTH_MEAN_RADIUS_KM; //地球平均半径
BigDecimal bigDecimalCm = new BigDecimal(me);
BigDecimal bigDecimalFM = new BigDecimal(1000);
double bufferDegree = bigDecimalCm.divide(bigDecimalFM).doubleValue();
double kmToDegree = DistanceUtils.dist2Degrees(bufferDegree, radius);
return kmToDegree;
}
/**
* 弧度转换为米
* 弧度=角度*PI/180
* 弧长=半径*弧度
* 地球赤道半径=6378137
* @param degree
* @return
*/
public static double degreeToMe(double degree){
return DistanceUtils.degrees2Dist(degree, DistanceUtils.EARTH_MEAN_RADIUS_KM) * 1000;
}