其他分享
首页 > 其他分享> > 计算经纬度距离,点到直线的距离,点到点的距离

计算经纬度距离,点到直线的距离,点到点的距离

作者:互联网

计算经纬度距离,点到直线的距离,点到点的距离

一、计算经纬度距离

根据坐标点经纬度计算两点间距离。(单位:km)

1.1 Java

public static void main(String[] args) {
    System.out.println(getDistance(40.00694,116.394476,40.007538,116.375561));
    }
//根据经纬度计算两点距离
public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = lat1 * Math.PI / 180.0;
        double radLat2 = lat2 * Math.PI / 180.0;
        double lng_1 = lng1 * Math.PI / 180.0;
        double lng_2 = lng2 * Math.PI / 180.0;
        double a = radLat1 - radLat2;// 两点纬度差
        double b = lng_1 - lng_2;// 两点的经度差
        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 * 6378.137;
        return s;
}

1.2 scala

def main(args: Array[String]): Unit = {
    val aa :Double  = getDistatce(40.00694,116.394476,40.007538,116.375561)
}

//根据经纬度计算两点距离
def getDistatce(lat1: Double, lon1: Double, lat2: Double, lon2: Double) = {
    if (lat1 != 0 && lon1 != 0 && lat2 != 0 && lon2 != 0) {
      val R = 6378.137
      val radLat1 = lat1 * Math.PI / 180
      val radLat2 = lat2 * Math.PI / 180
      val a = radLat1 - radLat2
      val b = lon1 * Math.PI / 180 - lon2 * Math.PI / 180
      val s = 2 * Math.sin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
      BigDecimal.decimal(s * R).setScale(2, BigDecimal.RoundingMode.HALF_UP).doubleValue()
    } else {
      BigDecimal.decimal(0).setScale(2, BigDecimal.RoundingMode.HALF_UP).doubleValue()
    }
  }

1.3 scala计算两个Gps点之间的距离

通常进行轨迹数据的挖掘,都会用到经纬度转换距离。

object getDistance{
   def main(args: Array[String]) {
     
    val lon1 = 108.956769;val lat1 = 34.229644
    val lon2 = 108.958830;val lat2 =34.229701
    def getDistance(lon1: Double, lat1: Double, lon2: Double, lat2: Double): Double ={   
      //pi为π,r为地球半径
      val pi = 3.1415926
      val r: Double  = 6370.99681
      //a1、a2、b1、b2分别为上面数据的经纬度转换为弧度
      val a1 = lat1 * pi /180.0
      val a2 = lon1 * pi /180.0
      val b1 = lat2 * pi /180.0
      val b2 = lon2 * pi /180.0
      var t1: Double = Math.cos(a1) * Math.cos(a2) * Math.cos(b1)* Math.cos(b2)
      var t2: Double = Math.cos(a1) * Math.sin(a2) * Math.cos(b1)* Math.sin(b2)
      var t3: Double = Math.sin(a1) * Math.sin(b1)
      val distance = Math.acos(t1 + t2 + t3) * r
      distance
    }
    println(getDistance(lon1,lat1,lon2,lat2))
   }
}
二、经纬度和距离之间的计算
import org.junit.Test;
import org.springframework.util.Assert;

public class GeoUtils {

    public final static float EARTH_RADIUS = 6378137; // 地球半径

    @Test
    public void test2() {
//        GeoUtils.getBoxByCoordinate(120.0, 40.0, 2000.0);
        Double distance = GeoUtils.getDistance(new Point(119.9765412051408, 39.98202952055585),
                new Point(120.0234587948592, 40.01797047944415));
        System.out.println(distance);
    }
    
    /**
     * 根据中心点获取box
     * @return
     */
    public static Double[] getBoxByCoordinate(Double longitude, Double latitude, Double raidusMile) {
        Assert.notNull(longitude);
        Assert.notNull(latitude);

        Double degree = (24901 * 1609) / 360.0; // 获取每度弧长

        Double mpdLng = Double.parseDouble((degree * Math.cos(latitude * (Math.PI / 180)) + "").replace("-", ""));
        Double dpmLng = 1 / mpdLng;
        Double radiusLng = dpmLng * raidusMile;
        // 获取最小经度
        Double minLat = longitude - radiusLng;
        // 获取最大经度
        Double maxLat = longitude + radiusLng;

        Double dpmLat = 1 / degree;
        Double radiusLat = dpmLat * raidusMile;
        // 获取最小纬度
        Double minLng = latitude - radiusLat;
        // 获取最大纬度
        Double maxLng = latitude + radiusLat;
        System.out.println(minLat + ": " + maxLat + ": " + minLng + ": " + maxLng);
        return null;
    }

    /**
     * 获取距离
     * @param from
     *            开始点
     * @param to
     *            结束点
     * @return
     */
    public static Double getDistance(Point from, Point to) {
        if (from == null || to == null || from.getLat() == null || from.getLng() == null || to.getLat() == null
                || to.getLng() == null) {
            return Double.NaN;
        } else {
            double lat1 = from.getLat() * Math.PI / 180.0;
            double lat2 = to.getLat() * Math.PI / 180.0;
            double a = lat1 - lat2;
            double b = (from.getLng() - to.getLng()) * Math.PI / 180.0;

            double sa2, sb2;
            sa2 = Math.sin(a / 2.0);
            sb2 = Math.sin(b / 2.0);
            return 2 * EARTH_RADIUS * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));
        }
    }

    /**
     * 点
     */
    public static class Point {
        public Double lat; // 纬度
        public Double lng; // 经度

        public Point() {            super();        }

        /**
         * @param lat
         * @param lng
         */
        public Point(Double lat, Double lng) {
            super();
            this.lat = lat;
            this.lng = lng;
        }

        /**
         * @return the lat
         */
        public Double getLat() {
            return lat;
        }

        /**
         * @param lat
         *            the lat to set
         */
        public void setLat(Double lat) {
            this.lat = lat;
        }

        /**
         * @return the lng
         */
        public Double getLng() {
            return lng;
        }

        /**
         * @param lng
         *            the lng to set
         */
        public void setLng(Double lng) {
            this.lng = lng;
        }
    }
}

2.1 角度计算

package com.iwhere.easy.travel.tool;

import org.junit.Test;

public class GeoTools {

    public static double getAngle(double lat1, double lng1, double lat2, double lng2) {
        double x1 = lng1;
        double y1 = lat1;
        double x2 = lng2;
        double y2 = lat2;
        double pi = Math.PI;
        double w1 = y1 / 180 * pi;
        double j1 = x1 / 180 * pi;
        double w2 = y2 / 180 * pi;
        double j2 = x2 / 180 * pi;
        double ret;
        if (j1 == j2) {
            if (w1 > w2)
                return 270; // 北半球的情况,南半球忽略
            else if (w1 < w2)
                return 90;
            else
                return -1;// 位置完全相同
        }
        ret = 4 * Math.pow(Math.sin((w1 - w2) / 2), 2)
                - Math.pow(Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)), 2);
        ret = Math.sqrt(ret);
        double temp = (Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2)));
        ret = ret / temp;
        ret = Math.atan(ret) / pi * 180;
        if (j1 > j2) { // 1为参考点坐标
            if (w1 > w2)
                ret += 180;
            else
                ret = 180 - ret;
        } else if (w1 > w2)
            ret = 360 - ret;
        return ret;
    }

    /**
     * @param lat1
     *            纬度1,参考点
     * @param lng1
     *            经度1,参考点
     * @param lat2
     *            纬度2
     * @param lng2
     *            经度2
     * @return 方向
     */
    public static String getDirection(double lat1, double lng1, double lat2, double lng2) {
        double jiaodu = getAngle(lat1, lng1, lat2, lng2);
        if ((jiaodu <= 10) || (jiaodu > 350))
            return "正东方";
        if ((jiaodu > 10) && (jiaodu <= 80))
            return "东北方";
        if ((jiaodu > 80) && (jiaodu <= 100))
            return "正北方";
        if ((jiaodu > 100) && (jiaodu <= 170))
            return "西北方";
        if ((jiaodu > 170) && (jiaodu <= 190))
            return "正西方";
        if ((jiaodu > 190) && (jiaodu <= 260))
            return "西南方";
        if ((jiaodu > 260) && (jiaodu <= 280))
            return "正南方";
        if ((jiaodu > 280) && (jiaodu <= 350))
            return "东南方";
        return "";
    }

    /**
     * 获取方位角描述
     * 前一个点
     * 参照点
     * 目标点
     * @return
     */
    public static String getAzimuth(double preLng, double preLat, double referLng, double referLat, double poiLng,
            double poiLat) {
        double jiaodu1 = getAngle(preLat, preLng, referLat, referLng);
        double jiaodu2 = getAngle(referLat, referLng, poiLat, poiLng);
        double jiaodu = jiaodu2 - jiaodu1;
        if (((jiaodu <=10 && jiaodu > 0) || jiaodu > 350) || ((jiaodu >= -10 && jiaodu < 0) || jiaodu < -350)) {
            return "正前方";
        }else if ((jiaodu <= 80 && jiaodu > 10) || (jiaodu >= -350 && jiaodu < -280)) {
            return "左前方";
        }else if ((jiaodu <= 100 && jiaodu > 80) || (jiaodu >= -280 && jiaodu < -260)) {
            return "左侧";
        }else if ((jiaodu <= 170 && jiaodu > 100) || (jiaodu >= -260 && jiaodu < -190)) {
            return "左后方";
        }else if ((jiaodu <= 190 && jiaodu > 170) || (jiaodu >= -190 && jiaodu < -170)) {
            return "后方";
        }else if ((jiaodu <=260 && jiaodu > 190) || (jiaodu >= -170 && jiaodu < -100)) {
            return "右后方";
        }else if ((jiaodu <=280 && jiaodu > 260) || (jiaodu >= -100 && jiaodu < -80)) {
            return "右侧";
        }else if ((jiaodu <= 350 && jiaodu > 280) || (jiaodu >= -80 && jiaodu < -10)) {
            return "右前方";
        }
        return "";
    }
    
    @Test
    public void test() {
        String azimuth = GeoTools.getAzimuth(0d, 0d, -40d, 20d, 30d, 30d);
        System.out.println(azimuth);
    }

    public static void main(String[] args) {
        String str = getDirection(0, 0, -40, -34);
        System.out.println(str);
    }
}
三、通过经纬度坐标计算两个点之间的距离

单位:米

public static double getDistance(double lat1, double longt1, double lat2,
			double longt2) {
		double PI = 3.14159265358979323; // 圆周率
		double R = 6371229; // 地球的半径
 
		double x, y, distance;
		x = (longt2 - longt1) * PI * R
				* Math.cos(((lat1 + lat2) / 2) * PI / 180) / 180;
		y = (lat2 - lat1) * PI * R / 180;
		distance = Math.hypot(x, y);
 
		return distance;
	}
四、根据gps计算两点之间的距离
/** 参数说明:
     * 基于googleMap中的算法得到两经纬度之间的距离,
     * 计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下 
     * @param lon1 第一点的经度 
     * @param lat1 第一点的纬度 
     * @param lon2 第二点的经度 
     * @param lat3 第二点的纬度 
     * @return 返回的距离,单位m 
     * */ 
public class GPSHelper {
	// 圆周率
	public static final double PI = 3.14159265358979324;
	// 赤道半径(单位m)  
	private static final  double EARTH_RADIUS = 6378137;
    
    /** 
     * 转化为弧度(rad) 
     * */  
    private static double rad(double d) {  
       return d * Math.PI / 180.0;  
    }  
    public static double GetDistance(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_RADIUS;  
       //s = Math.round(s * 10000) / 10000;  
       return s;  
    }
}

测试:

public double getDistance(double lat1, double lon1, double lat2, double lon2) {
    float[] results=new float[1];
    Location.distanceBetween(lat1, lon1, lat2, lon2, results);
    return results[0];
}

标签:return,经纬度,double,点到点,距离,jiaodu,Double,public,Math
来源: https://blog.51cto.com/u_15078339/2869823