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


    一、计算经纬度距离

    根据坐标点经纬度计算两点间距离。(单位: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];
    }
    
  • 相关阅读:
    数据库02
    MySQL1
    GIL 死锁 递归锁 event 信号量 线程Queue
    小脚本 暴力删除文件 刷屏
    常见web攻击 及基础 回顾(杂记)
    接口中的简单异步 async
    python协程 示例
    python 利用jinja2模板生成html
    python 调用webservices 接口
    python 进程 进程池 进程间通信
  • 原文地址:https://www.cnblogs.com/aixing/p/13327376.html
Copyright © 2020-2023  润新知