求经纬度xy 到x1 y1 |x2 y2组成的直线的垂直距离

package com.pojo.common.core.utils;


import java.math.BigDecimal;

import java.time.LocalDateTime;

public class CaculateDistanceUtil {

    private final static double EARTH_RADIUS = 6378.137;
    private final static double a = 6378137.0D;
    private final static double f = 0.003352810681;
    private final static double b = 6356752.314141519D;
    private final static double e2 = 2 * f - f * f;

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 根据两点间经纬度坐标(double值),计算两点间距离,单位为米
     */
    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        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_RADIUS;
        s = (s * 10000) / 10;
        return s;
    }

    public static double getDistance(BigDecimal lat1, BigDecimal lng1, BigDecimal lat2, BigDecimal lng2) {
        return getDistance(lat1.doubleValue(), lng1.doubleValue(), lat2.doubleValue(), lng2.doubleValue());
    }


    public static double[] WGS84ToECEF(double longitude, double latitude, double h) {
        latitude = latitude / 180 * Math.PI; // converting to radians
        longitude = longitude / 180 * Math.PI; // converting to radians
        double chi = Math.sqrt(1 - e2 * Math.pow(Math.sin(latitude), 2));
        double X = (a / chi + h) * Math.cos(latitude) * Math.cos(longitude);
        double Y = (a / chi + h) * Math.cos(latitude) * Math.sin(longitude);
        double Z = (a * (1 - e2) / chi + h) * Math.sin(latitude);
        return new double[]{X, Y, Z};
    }

    public static double[] ECEFToENU(double Xr, double Yr, double Zr, double X, double Y, double Z) {
        double phiP = Math.atan2(Zr, Math.sqrt(Xr * Xr + Yr * Yr));
        double lambda = Math.atan2(Yr, Xr);
        double e = -Math.sin(lambda) * (X - Xr) + Math.cos(lambda) * (Y - Yr);
        double n = -Math.sin(phiP) * Math.cos(lambda) * (X - Xr) - Math.sin(phiP) * Math.sin(lambda) * (Y - Yr) + Math.cos(phiP) * (Z - Zr);
        double u = Math.cos(phiP) * Math.cos(lambda) * (X - Xr) + Math.cos(phiP) * Math.sin(lambda) * (Y - Yr) + Math.sin(phiP) * (Z - Zr);
        return new double[]{e, n, u};
    }

    public static boolean checkDistance(double e1, double n1, double e2, double n2) {
        if (Math.abs(e2 - e1) < 1 || Math.abs(n2 - n1) < 1) {
            return true;
        } else {
            double distance = Math.abs(e1 - n1 * (e2 - e1) / (n2 - n1)) / Math.sqrt(1 + Math.pow((e2 - e1) / (n2 - n1), 2));
            if (distance < 100) {
                return true;
            } else {
                return false;
            }
        }
    }


    public static double verticalDistance(double e1, double n1, double e2, double n2) {
        if (Math.abs(e2 - e1) < 1 || Math.abs(n2 - n1) < 1) {
            //表示点在直线上
            return 0;
        } else {
            double distance = Math.abs(e1 - n1 * (e2 - e1) / (n2 - n1)) / Math.sqrt(1 + Math.pow((e2 - e1) / (n2 - n1), 2));
            return distance;
        }
    }

    /**
     * 求 给定经纬度 (lng,lat) 到 (lng1,lat1| lng2,lat2组成的直线的垂直距离)
     *
     * @param lat1
     * @param lng1
     * @param lat2
     * @param lng2
     * @param lat
     * @param lng
     * @return
     */
    public static double verticalDistance(BigDecimal lat1, BigDecimal lng1, BigDecimal lat2, BigDecimal lng2, BigDecimal lat, BigDecimal lng) {
        double lng1d = lng1.doubleValue();
        double lat1d = lat1.doubleValue();
        double alt1d = 0.0;

        double lng2d = lng2.doubleValue();
        double lat2d = lat2.doubleValue();
        double alt2d = 0.0;

        double lngd = lng.doubleValue();
        double latd = lat.doubleValue();
        double altd = 0.0;

        // Convert WGS84 to ECEF
        double[] XYZ1 = WGS84ToECEF(lng1d, lat1d, alt1d);
        double[] XYZ2 = WGS84ToECEF(lng2d, lat2d, alt2d);
        double[] XYZ = WGS84ToECEF(lngd, latd, altd);

        // Convert ECEF to ENU
        double[] enu1 = ECEFToENU(XYZ1[0], XYZ1[1], XYZ1[2], XYZ[0], XYZ[1], XYZ[2]);
        double[] enu2 = ECEFToENU(XYZ2[0], XYZ2[1], XYZ2[2], XYZ[0], XYZ[1], XYZ[2]);

        // Check distance
        double result = verticalDistance(enu1[0], enu1[1], enu2[0], enu2[1]);
        return result;

    }


    public static void main(String[] args) {
//         Test data
//
//        double Long1 = 116.502846000000000;
//        double Lat1 = 31.860445000000000;
//        double Alt1 = 0.0;
//        double Long2 =116.582846000000000;
//        double Lat2 =31.860445000000000;
//        double Alt2 = 0;
//        double Long = 116.522846000000000;
//        double Lat = 31.860445000000000;
//        double Alt = 0;
//
//
//
//        // Convert WGS84 to ECEF
//        double[] XYZ1 = WGS84ToECEF(Long1, Lat1, Alt1);
//        double[] XYZ2 = WGS84ToECEF(Long2, Lat2, Alt2);
//        double[] XYZ = WGS84ToECEF(Long, Lat, Alt);
//
//        // Convert ECEF to ENU
//        double[] enu1 = ECEFToENU(XYZ1[0], XYZ1[1], XYZ1[2], XYZ[0], XYZ[1], XYZ[2]);
//        double[] enu2 = ECEFToENU(XYZ2[0], XYZ2[1], XYZ2[2], XYZ[0], XYZ[1], XYZ[2]);
//
//        // Check distance
//        double result = verticalDistance(enu1[0], enu1[1], enu2[0], enu2[1]);
//        System.out.println(result);

        BigDecimal x1 = new BigDecimal(31.860445000000000);
        BigDecimal x2 = new BigDecimal(31.860445000000000);
        BigDecimal x = new BigDecimal(31.860445000000000);
        BigDecimal y1 = new BigDecimal(116.502846000000000);
        BigDecimal y2 = new BigDecimal(116.582846000000000);
        BigDecimal y = new BigDecimal(116.582846000000000);
        //求经纬度xy 到x1 y1 |x2 y2组成的直线的垂直距离
        double result = verticalDistance(x1, y1, x2, y2, x, y);
        System.out.println(result);

//        System.out.println(StringUtils.station("K275+650"));
//        System.out.println(LocalDateUtil.localDateTimeToString(LocalDateTime.now(),LocalDateUtil.DATE_PATTERN_yyyyMMdd));
//        System.out.println(LocalDateUtil.getMonthEndTime());
//        System.out.println(LocalDateUtil.getWeekStartTime());
//        System.out.println(LocalDateUtil.getWeekEndTime());
//        System.out.println(LocalDateUtil.getTodayStart());
//        System.out.println(LocalDateUtil.getTodayEnd());
//        System.out.println(getDistance(31.817077442754957,117.16533299864935,31.816731016717863,117.16559952340532));

    }

}

    /**
     * 勾股定理 求斜边长度
     *
     * @param a 直角边长度
     * @param b 直角边长度
     * @return
     */
    public static double hypotenuse(double a, double b) {
        double root = Math.sqrt(a * a + b * b);
        return root;
    }

    /**
     * 勾股定理 求直角边长度
     *
     * @param ht 斜边长度
     * @param b  直角边长度
     * @return
     */
    public static double angledEdge(double ht, double b) {
        double root = Math.sqrt(ht * ht - b * b);
        return root;
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Python中,可以使用haversine公式来计算两个地点之间的直线距离。Haversine公式是一种用于计算两个球面坐标之间距离的算法,可以用于计算两个经纬度坐标之间的距离。其公式如下: d = 2r * arcsin(sqrt(sin((lat2-lat1)/2)^2 + cos(lat1) * cos(lat2) * sin((lon2-lon1)/2)^2)) 其中,d是两个地点之间的距离,lat1,lon1是第一个地点的纬度和经度,lat2,lon2是第二个地点的纬度和经度,r是地球的平均半径,约为6371km。 因此,我们可以使用Python中的math库来计算两点之间的距离,并且使用的公式为Haversine公式。 下面是一个使用Python计算经纬度之间距离的例子: ```python from math import radians, cos, sin, asin, sqrt def calc_distance(lat1, lon1, lat2, lon2): # 转换经纬度为弧度 lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) # Haversine公式计算距离 dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * asin(sqrt(a)) r = 6371 #地球半径,单位为公里 return c * r # 举例:计算北京和上海之间的距离 lat1, lon1 = 39.9042, 116.4074 # 北京的经纬度 lat2, lon2 = 31.2304, 121.4737 # 上海的经纬度 distance = calc_distance(lat1, lon1, lat2, lon2) print("北京和上海之间的距离为:",distance,"km") ``` 以上代码会输出:北京和上海之间的距离为: 1068.9046696384106 km 即北京和上海之间的大约距离为1068.9公里。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值