• geo-经纬度计算


    经纬度计算, 本质上是球面三角函数的应用, 将数学公式转换为代码的过程, 

    站在前人的肩膀上, 自己又补充了一点: 

    package com.iwhere.easy.travel.tool;
    
    public class GeoTools {
        
        public static String getScopeByGeoLevel(Integer geolevel) {
            return ((16 - geolevel) * 5) + "公里";
        }
    
        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 "";
        }
    
        /**
         * 获取方位角描述
         * 前一个点
         * 参照点
         * 目标点
         * @author wenbronk
         */
        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 "";
        }
        
        /**
         * 判断是否在后方
         * @author wenbronk
         */
        public static Boolean isBehine(double preLng, double preLat, double referLng, double referLat, 
                double poiLng, double poiLat) {
            double x1 = referLng - preLng;
            double y1 = referLat - preLat;
            double x2 = poiLng - referLng;
            double y2 = poiLat - referLat;
            
            // 求 (x1, y1), (x2, y2) 向量的夹角的cos值
            double cos = (x1 * x2 + y1 * y2) / 
                    (Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2)) + Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2)));
            if (cos >= 0) {
                return false;
            }
            return true;
        }
        
        public static void main(String[] args) {
            String str = getDirection(0, 0, -40, -34);
            System.out.println(str);
        }
    }
  • 相关阅读:
    Cocos2d-x 3.0 屏幕触摸及消息分发机制
    stretchableImageWithLeftCapWidth气泡拉伸
    海量数据插入数据库效率对照測试 ---ADO.NET下SqlBulkCopy()对照LINQ 下InsertAllOnSubmit()
    银联+移动+三星PK微信、余额宝
    热力学三大定律与熵
    热力学三大定律与熵
    OpenGL(六) gluLookAt和gluPerspective函数解析
    特殊字符
    特殊字符
    函数的功能
  • 原文地址:https://www.cnblogs.com/wenbronk/p/7273871.html
Copyright © 2020-2023  润新知