zoukankan      html  css  js  c++  java
  • (转)根据经纬度计算方位距离

    (原文地址:http://www.cnblogs.com/leejuan/p/5552460.html)

    1.根据两点经纬度计算其间距离,发现有3种公式,结果区别不是很大。

    2.根据一点的经纬度与到另外一点的距离、方位角,计算另一点的经纬度,误差不是很大。

      1 /** 
      2  *  
      3  * 计算经纬度、距离、方位角 
      4  *  
      5  * */  
      6 public class CalculationLogLatDistance {  
      7     /** 
      8      * 地球赤道半径(km) 
      9      * */  
     10     public final static double EARTH_RADIUS = 6378.137;  
     11     /** 
     12      * 地球每度的弧长(km) 
     13      * */  
     14     public final static double EARTH_ARC = 111.199;  
     15   
     16     /** 
     17      * 转化为弧度(rad) 
     18      * */  
     19     public static double rad(double d) {  
     20         return d * Math.PI / 180.0;  
     21     }  
     22   
     23     /** 
     24      * 求两经纬度距离 
     25      *  
     26      * @param lon1 
     27      *            第一点的经度 
     28      * @param lat1 
     29      *            第一点的纬度 
     30      * @param lon2 
     31      *            第二点的经度 
     32      * @param lat2 
     33      *            第二点的纬度 
     34      * @return 两点距离,单位km 
     35      * */  
     36     public static double GetDistanceOne(double lon1, double lat1, double lon2,  
     37             double lat2) {  
     38         double r1 = rad(lat1);  
     39         double r2 = rad(lon1);  
     40         double a = rad(lat2);  
     41         double b = rad(lon2);  
     42         double s = Math.acos(Math.cos(r1) * Math.cos(a) * Math.cos(r2 - b)  
     43                 + Math.sin(r1) * Math.sin(a))  
     44                 * EARTH_RADIUS;  
     45         return s;  
     46     }  
     47   
     48     /** 
     49      * 求两经纬度距离(google maps源码中) 
     50      *  
     51      * @param lon1 
     52      *            第一点的经度 
     53      * @param lat1 
     54      *            第一点的纬度 
     55      * @param lon2 
     56      *            第二点的经度 
     57      * @param lat2 
     58      *            第二点的纬度 
     59      * @return 两点距离,单位km 
     60      * */  
     61     public static double GetDistanceTwo(double lon1, double lat1, double lon2,  
     62             double lat2) {  
     63         double radLat1 = rad(lat1);  
     64         double radLat2 = rad(lat2);  
     65         double a = radLat1 - radLat2;  
     66         double b = rad(lon1) - rad(lon2);  
     67         double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)  
     68                 + Math.cos(radLat1) * Math.cos(radLat2)  
     69                 * Math.pow(Math.sin(b / 2), 2)));  
     70         s = s * EARTH_RADIUS;  
     71         return s;  
     72     }  
     73   
     74     /** 
     75      * 求两经纬度距离 
     76      *  
     77      * @param lon1 
     78      *            第一点的经度 
     79      * @param lat1 
     80      *            第一点的纬度 
     81      * @param lon2 
     82      *            第二点的经度 
     83      * @param lat2 
     84      *            第二点的纬度 
     85      * @return 两点距离,单位km 
     86      * */  
     87     public static double GetDistanceThree(double lon1, double lat1,  
     88             double lon2, double lat2) {  
     89         double radLat1 = rad(lat1);  
     90         double radLat2 = rad(lat2);  
     91         double radLon1 = rad(lon1);  
     92         double radLon2 = rad(lon2);  
     93         if (radLat1 < 0)  
     94             radLat1 = Math.PI / 2 + Math.abs(radLat1);// south  
     95         if (radLat1 > 0)  
     96             radLat1 = Math.PI / 2 - Math.abs(radLat1);// north  
     97         if (radLon1 < 0)  
     98             radLon1 = Math.PI * 2 - Math.abs(radLon1);// west  
     99         if (radLat2 < 0)  
    100             radLat2 = Math.PI / 2 + Math.abs(radLat2);// south  
    101         if (radLat2 > 0)  
    102             radLat2 = Math.PI / 2 - Math.abs(radLat2);// north  
    103         if (radLon2 < 0)  
    104             radLon2 = Math.PI * 2 - Math.abs(radLon2);// west  
    105         double x1 = Math.cos(radLon1) * Math.sin(radLat1);  
    106         double y1 = Math.sin(radLon1) * Math.sin(radLat1);  
    107         double z1 = Math.cos(radLat1);  
    108   
    109         double x2 = Math.cos(radLon2) * Math.sin(radLat2);  
    110         double y2 = Math.sin(radLon2) * Math.sin(radLat2);  
    111         double z2 = Math.cos(radLat2);  
    112   
    113         double d = Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)  
    114                 + Math.pow((z1 - z2), 2);  
    115         // // 余弦定理求夹角  
    116         // double theta = Math.acos((2 - d) / 2);  
    117   
    118         d = Math.pow(EARTH_RADIUS, 2) * d;  
    119         // //余弦定理求夹角  
    120         double theta = Math.acos((2 * Math.pow(EARTH_RADIUS, 2) - d)  
    121                 / (2 * Math.pow(EARTH_RADIUS, 2)));  
    122   
    123         double dist = theta * EARTH_RADIUS;  
    124         return dist;  
    125     }  
    126   
    127     /** 
    128      * 求两经纬度方向角 
    129      *  
    130      * @param lon1 
    131      *            第一点的经度 
    132      * @param lat1 
    133      *            第一点的纬度 
    134      * @param lon2 
    135      *            第二点的经度 
    136      * @param lat2 
    137      *            第二点的纬度 
    138      * @return 方位角,角度(单位:°) 
    139      * */  
    140     public static double GetAzimuth(double lon1, double lat1, double lon2,  
    141             double lat2) {  
    142         lat1 = rad(lat1);  
    143         lat2 = rad(lat2);  
    144         lon1 = rad(lon1);  
    145         lon2 = rad(lon2);  
    146         double azimuth = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1)  
    147                 * Math.cos(lat2) * Math.cos(lon2 - lon1);  
    148         azimuth = Math.sqrt(1 - azimuth * azimuth);  
    149         azimuth = Math.cos(lat2) * Math.sin(lon2 - lon1) / azimuth;  
    150         azimuth = Math.asin(azimuth) * 180 / Math.PI;  
    151         if (Double.isNaN(azimuth)) {  
    152             if (lon1 < lon2) {  
    153                 azimuth = 90.0;  
    154             } else {  
    155                 azimuth = 270.0;  
    156             }  
    157         }  
    158         return azimuth;  
    159     }  
    160   
    161     /** 
    162      * 已知一点经纬度A,和与另一点B的距离和方位角,求B的经纬度(计算结果有误) 
    163      *  
    164      * @param lon1 
    165      *            A的经度 
    166      * @param lat1 
    167      *            A的纬度 
    168      * @param distance 
    169      *            AB距离(单位:米) 
    170      * @param azimuth 
    171      *            AB方位角 
    172      * @return B的经纬度 
    173      * */  
    174     public static String GetOtherPoint(double lon1, double lat1,  
    175             double distance, double azimuth) {  
    176         azimuth = rad(azimuth);  
    177         double ab = distance / EARTH_ARC;// AB间弧线长  
    178         ab = rad(ab);  
    179         double Lat = Math.asin(Math.sin(lat1) * Math.cos(ab) + Math.cos(lat1)  
    180                 * Math.sin(ab) * Math.cos(azimuth));  
    181         double Lon = lon1  
    182                 + Math.asin(Math.sin(azimuth) * Math.sin(ab) / Math.cos(Lat));  
    183         System.out.println(Lon + ”,” + Lat);  
    184   
    185         double a = Math.acos(Math.cos(90 - lon1) * Math.cos(ab)  
    186                 + Math.sin(90 - lon1) * Math.sin(ab) * Math.cos(azimuth));  
    187         double C = Math.asin(Math.sin(ab) * Math.sin(azimuth) / Math.sin(a));  
    188         System.out.println(”c=” + C);  
    189         double lon2 = lon1 + C;  
    190         double lat2 = 90 - a;  
    191         return lon2 + “,” + lat2;  
    192     }  
    193   
    194     /** 
    195      * 已知一点经纬度A,和与另一点B的距离和方位角,求B的经纬度 
    196      *  
    197      * @param lon1 
    198      *            A的经度 
    199      * @param lat1 
    200      *            A的纬度 
    201      * @param distance 
    202      *            AB距离(单位:米) 
    203      * @param azimuth 
    204      *            AB方位角 
    205      * @return B的经纬度 
    206      * */  
    207     public static String ConvertDistanceToLogLat(double lng1, double lat1,  
    208             double distance, double azimuth) {  
    209         azimuth = rad(azimuth);  
    210         // 将距离转换成经度的计算公式  
    211         double lon = lng1 + (distance * Math.sin(azimuth))  
    212                 / (EARTH_ARC * Math.cos(rad(lat1)));  
    213         // 将距离转换成纬度的计算公式  
    214         double lat = lat1 + (distance * Math.cos(azimuth)) / EARTH_ARC;  
    215         return lon + “,” + lat;  
    216     }  
    217   
    218     public static void main(String[] args) {  
    219         double lon1 = 121.469156;  
    220         double lat1 = 31.232307;  
    221         double lon2 = 121.469156;  
    222         double lat2 = 31.233205;  
    223         double distance = GetDistanceTwo(lon1, lat1, lon2, lat2);  
    224         double azimuth = GetAzimuth(lon1, lat1, lon2, lat2);  
    225         System.out.println(”经纬度为(“ + lon1 + “,” + lat1 + “)的点与经纬度为(“ + lon2  
    226                 + ”,” + lat2 + “)相距:” + distance + “千米,” + “方位角:” + azimuth  
    227                 + ”°”);  
    228         System.out.println(”距经纬度为(“ + lon1 + “,” + lat1 + “)的点” + distance  
    229                 + ”千米,方位角为” + azimuth + “°的另一点经纬度为(“  
    230                 + ConvertDistanceToLogLat(lon1, lat1, distance, azimuth) + ”)”);  
    231     }  
    232 }  
    233 [java] view plain copy
    234 
    235  
    236 /** 
    237  *  
    238  * 计算经纬度、距离、方位角 
    239  *  
    240  * */  
    241 public class CalculationLogLatDistance {  
    242     /** 
    243      * 地球赤道半径(km) 
    244      * */  
    245     public final static double EARTH_RADIUS = 6378.137;  
    246     /** 
    247      * 地球每度的弧长(km) 
    248      * */  
    249     public final static double EARTH_ARC = 111.199;  
    250   
    251     /** 
    252      * 转化为弧度(rad) 
    253      * */  
    254     public static double rad(double d) {  
    255         return d * Math.PI / 180.0;  
    256     }  
    257   
    258     /** 
    259      * 求两经纬度距离 
    260      *  
    261      * @param lon1 
    262      *            第一点的经度 
    263      * @param lat1 
    264      *            第一点的纬度 
    265      * @param lon2 
    266      *            第二点的经度 
    267      * @param lat2 
    268      *            第二点的纬度 
    269      * @return 两点距离,单位km 
    270      * */  
    271     public static double GetDistanceOne(double lon1, double lat1, double lon2,  
    272             double lat2) {  
    273         double r1 = rad(lat1);  
    274         double r2 = rad(lon1);  
    275         double a = rad(lat2);  
    276         double b = rad(lon2);  
    277         double s = Math.acos(Math.cos(r1) * Math.cos(a) * Math.cos(r2 - b)  
    278                 + Math.sin(r1) * Math.sin(a))  
    279                 * EARTH_RADIUS;  
    280         return s;  
    281     }  
    282   
    283     /** 
    284      * 求两经纬度距离(google maps源码中) 
    285      *  
    286      * @param lon1 
    287      *            第一点的经度 
    288      * @param lat1 
    289      *            第一点的纬度 
    290      * @param lon2 
    291      *            第二点的经度 
    292      * @param lat2 
    293      *            第二点的纬度 
    294      * @return 两点距离,单位km 
    295      * */  
    296     public static double GetDistanceTwo(double lon1, double lat1, double lon2,  
    297             double lat2) {  
    298         double radLat1 = rad(lat1);  
    299         double radLat2 = rad(lat2);  
    300         double a = radLat1 - radLat2;  
    301         double b = rad(lon1) - rad(lon2);  
    302         double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)  
    303                 + Math.cos(radLat1) * Math.cos(radLat2)  
    304                 * Math.pow(Math.sin(b / 2), 2)));  
    305         s = s * EARTH_RADIUS;  
    306         return s;  
    307     }  
    308   
    309     /** 
    310      * 求两经纬度距离 
    311      *  
    312      * @param lon1 
    313      *            第一点的经度 
    314      * @param lat1 
    315      *            第一点的纬度 
    316      * @param lon2 
    317      *            第二点的经度 
    318      * @param lat2 
    319      *            第二点的纬度 
    320      * @return 两点距离,单位km 
    321      * */  
    322     public static double GetDistanceThree(double lon1, double lat1,  
    323             double lon2, double lat2) {  
    324         double radLat1 = rad(lat1);  
    325         double radLat2 = rad(lat2);  
    326         double radLon1 = rad(lon1);  
    327         double radLon2 = rad(lon2);  
    328         if (radLat1 < 0)  
    329             radLat1 = Math.PI / 2 + Math.abs(radLat1);// south  
    330         if (radLat1 > 0)  
    331             radLat1 = Math.PI / 2 - Math.abs(radLat1);// north  
    332         if (radLon1 < 0)  
    333             radLon1 = Math.PI * 2 - Math.abs(radLon1);// west  
    334         if (radLat2 < 0)  
    335             radLat2 = Math.PI / 2 + Math.abs(radLat2);// south  
    336         if (radLat2 > 0)  
    337             radLat2 = Math.PI / 2 - Math.abs(radLat2);// north  
    338         if (radLon2 < 0)  
    339             radLon2 = Math.PI * 2 - Math.abs(radLon2);// west  
    340         double x1 = Math.cos(radLon1) * Math.sin(radLat1);  
    341         double y1 = Math.sin(radLon1) * Math.sin(radLat1);  
    342         double z1 = Math.cos(radLat1);  
    343   
    344         double x2 = Math.cos(radLon2) * Math.sin(radLat2);  
    345         double y2 = Math.sin(radLon2) * Math.sin(radLat2);  
    346         double z2 = Math.cos(radLat2);  
    347   
    348         double d = Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)  
    349                 + Math.pow((z1 - z2), 2);  
    350         // // 余弦定理求夹角  
    351         // double theta = Math.acos((2 - d) / 2);  
    352   
    353         d = Math.pow(EARTH_RADIUS, 2) * d;  
    354         // //余弦定理求夹角  
    355         double theta = Math.acos((2 * Math.pow(EARTH_RADIUS, 2) - d)  
    356                 / (2 * Math.pow(EARTH_RADIUS, 2)));  
    357   
    358         double dist = theta * EARTH_RADIUS;  
    359         return dist;  
    360     }  
    361   
    362     /** 
    363      * 求两经纬度方向角 
    364      *  
    365      * @param lon1 
    366      *            第一点的经度 
    367      * @param lat1 
    368      *            第一点的纬度 
    369      * @param lon2 
    370      *            第二点的经度 
    371      * @param lat2 
    372      *            第二点的纬度 
    373      * @return 方位角,角度(单位:°) 
    374      * */  
    375     public static double GetAzimuth(double lon1, double lat1, double lon2,  
    376             double lat2) {  
    377         lat1 = rad(lat1);  
    378         lat2 = rad(lat2);  
    379         lon1 = rad(lon1);  
    380         lon2 = rad(lon2);  
    381         double azimuth = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1)  
    382                 * Math.cos(lat2) * Math.cos(lon2 - lon1);  
    383         azimuth = Math.sqrt(1 - azimuth * azimuth);  
    384         azimuth = Math.cos(lat2) * Math.sin(lon2 - lon1) / azimuth;  
    385         azimuth = Math.asin(azimuth) * 180 / Math.PI;  
    386         if (Double.isNaN(azimuth)) {  
    387             if (lon1 < lon2) {  
    388                 azimuth = 90.0;  
    389             } else {  
    390                 azimuth = 270.0;  
    391             }  
    392         }  
    393         return azimuth;  
    394     }  
    395   
    396     /** 
    397      * 已知一点经纬度A,和与另一点B的距离和方位角,求B的经纬度(计算结果有误) 
    398      *  
    399      * @param lon1 
    400      *            A的经度 
    401      * @param lat1 
    402      *            A的纬度 
    403      * @param distance 
    404      *            AB距离(单位:米) 
    405      * @param azimuth 
    406      *            AB方位角 
    407      * @return B的经纬度 
    408      * */  
    409     public static String GetOtherPoint(double lon1, double lat1,  
    410             double distance, double azimuth) {  
    411         azimuth = rad(azimuth);  
    412         double ab = distance / EARTH_ARC;// AB间弧线长  
    413         ab = rad(ab);  
    414         double Lat = Math.asin(Math.sin(lat1) * Math.cos(ab) + Math.cos(lat1)  
    415                 * Math.sin(ab) * Math.cos(azimuth));  
    416         double Lon = lon1  
    417                 + Math.asin(Math.sin(azimuth) * Math.sin(ab) / Math.cos(Lat));  
    418         System.out.println(Lon + "," + Lat);  
    419   
    420         double a = Math.acos(Math.cos(90 - lon1) * Math.cos(ab)  
    421                 + Math.sin(90 - lon1) * Math.sin(ab) * Math.cos(azimuth));  
    422         double C = Math.asin(Math.sin(ab) * Math.sin(azimuth) / Math.sin(a));  
    423         System.out.println("c=" + C);  
    424         double lon2 = lon1 + C;  
    425         double lat2 = 90 - a;  
    426         return lon2 + "," + lat2;  
    427     }  
    428   
    429     /** 
    430      * 已知一点经纬度A,和与另一点B的距离和方位角,求B的经纬度 
    431      *  
    432      * @param lon1 
    433      *            A的经度 
    434      * @param lat1 
    435      *            A的纬度 
    436      * @param distance 
    437      *            AB距离(单位:米) 
    438      * @param azimuth 
    439      *            AB方位角 
    440      * @return B的经纬度 
    441      * */  
    442     public static String ConvertDistanceToLogLat(double lng1, double lat1,  
    443             double distance, double azimuth) {  
    444         azimuth = rad(azimuth);  
    445         // 将距离转换成经度的计算公式  
    446         double lon = lng1 + (distance * Math.sin(azimuth))  
    447                 / (EARTH_ARC * Math.cos(rad(lat1)));  
    448         // 将距离转换成纬度的计算公式  
    449         double lat = lat1 + (distance * Math.cos(azimuth)) / EARTH_ARC;  
    450         return lon + "," + lat;  
    451     }  
    452   
    453     public static void main(String[] args) {  
    454         double lon1 = 121.469156;  
    455         double lat1 = 31.232307;  
    456         double lon2 = 121.469156;  
    457         double lat2 = 31.233205;  
    458         double distance = GetDistanceTwo(lon1, lat1, lon2, lat2);  
    459         double azimuth = GetAzimuth(lon1, lat1, lon2, lat2);  
    460         System.out.println("经纬度为(" + lon1 + "," + lat1 + ")的点与经纬度为(" + lon2  
    461                 + "," + lat2 + ")相距:" + distance + "千米," + "方位角:" + azimuth  
    462                 + "°");  
    463         System.out.println("距经纬度为(" + lon1 + "," + lat1 + ")的点" + distance  
    464                 + "千米,方位角为" + azimuth + "°的另一点经纬度为("  
    465                 + ConvertDistanceToLogLat(lon1, lat1, distance, azimuth) + ")");  
    466     }  
    467 }  
  • 相关阅读:
    centos 7.5搭建oracle DG
    oracle 11g修改归档日志目录及大小
    oracle修改数据文件路径
    oracle 11g调优常用语句
    MySQL MHA安装配置
    mysql中的数据库操作
    mysql 中用户与权限的操作
    percona server安装
    mysql配置文件相关
    条件判断中的真假
  • 原文地址:https://www.cnblogs.com/luckyQi/p/6545576.html
Copyright © 2011-2022 走看看