zoukankan      html  css  js  c++  java
  • 经纬度和距离之间的计算

    不是我写的, 也看不太懂, 备忘

    package com.iwhere.easy.travel.tool;
    
    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));
            }
        }
    
        /**
         * 
         * ---------------------------------------------------------------------------
         * 点
         * ---------------------------------------------------------------------------
         * <strong>copyright</strong>: ©版权所有 成都都在哪网讯科技有限公司<br>
         * ----------------------------------------------------------------------------
         * 
         * @author: hewei
         * @time:2016年10月28日 下午6:29:22
         *                   ---------------------------------------------------------------------------
         */
        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;
            }
        }
    }

    角度计算: 

    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);
        }
    }

    参考: http://blog.csdn.net/koryako/article/details/51864161

  • 相关阅读:
    unity ab包打包和加载的简单学习示例
    项目整理回顾1,关于单例使用
    关于lua闭包导致引用无法释放内存泄露
    unity lua require dofile loadfile 区别
    unity editor模式下读取文件夹资源
    unity texture 占用内存大小对比
    关于unity贴图压缩
    内聚,耦合,解耦和,依赖倒置
    lua type 获取 类型
    Unity+NGUI多分辨率适配方案
  • 原文地址:https://www.cnblogs.com/wenbronk/p/7221325.html
Copyright © 2011-2022 走看看