ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-06-05 14:54:00  阅读:180  来源: 互联网

标签:return 经纬度 double 点到点 距离 jiaodu Double public Math


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

一、计算经纬度距离

根据坐标点经纬度计算两点间距离。(单位: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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有