计算经纬度距离方位角

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算经纬度距离方位角相关的知识,希望对你有一定的参考价值。

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

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

  1 package com.zhs.util;
  2 
  3 /**
  4  * 
  5  * 计算经纬度、距离、方位角
  6  * 
  7  * @author lillian.he
  8  * @time 2016-06-02
  9  * */
 10 public class CalculationLogLatDistance {
 11     /**
 12      * 地球赤道半径(km)
 13      * */
 14     public final static double EARTH_RADIUS = 6378.137;
 15     /**
 16      * 地球每度的弧长(km)
 17      * */
 18     public final static double EARTH_ARC = 111.199;
 19 
 20     /**
 21      * 转化为弧度(rad)
 22      * */
 23     public static double rad(double d) {
 24         return d * Math.PI / 180.0;
 25     }
 26 
 27     /**
 28      * 求两经纬度距离
 29      * 
 30      * @param lon1
 31      *            第一点的经度
 32      * @param lat1
 33      *            第一点的纬度
 34      * @param lon2
 35      *            第二点的经度
 36      * @param lat2
 37      *            第二点的纬度
 38      * @return 两点距离,单位km
 39      * */
 40     public static double GetDistanceOne(double lon1, double lat1, double lon2,
 41             double lat2) {
 42         double r1 = rad(lat1);
 43         double r2 = rad(lon1);
 44         double a = rad(lat2);
 45         double b = rad(lon2);
 46         double s = Math.acos(Math.cos(r1) * Math.cos(a) * Math.cos(r2 - b)
 47                 + Math.sin(r1) * Math.sin(a))
 48                 * EARTH_RADIUS;
 49         return s;
 50     }
 51 
 52     /**
 53      * 求两经纬度距离(google maps源码中)
 54      * 
 55      * @param lon1
 56      *            第一点的经度
 57      * @param lat1
 58      *            第一点的纬度
 59      * @param lon2
 60      *            第二点的经度
 61      * @param lat2
 62      *            第二点的纬度
 63      * @return 两点距离,单位km
 64      * */
 65     public static double GetDistanceTwo(double lon1, double lat1, double lon2,
 66             double lat2) {
 67         double radLat1 = rad(lat1);
 68         double radLat2 = rad(lat2);
 69         double a = radLat1 - radLat2;
 70         double b = rad(lon1) - rad(lon2);
 71         double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
 72                 + Math.cos(radLat1) * Math.cos(radLat2)
 73                 * Math.pow(Math.sin(b / 2), 2)));
 74         s = s * EARTH_RADIUS;
 75         return s;
 76     }
 77 
 78     /**
 79      * 求两经纬度距离
 80      * 
 81      * @param lon1
 82      *            第一点的经度
 83      * @param lat1
 84      *            第一点的纬度
 85      * @param lon2
 86      *            第二点的经度
 87      * @param lat2
 88      *            第二点的纬度
 89      * @return 两点距离,单位km
 90      * */
 91     public static double GetDistanceThree(double lon1, double lat1,
 92             double lon2, double lat2) {
 93         double radLat1 = rad(lat1);
 94         double radLat2 = rad(lat2);
 95         double radLon1 = rad(lon1);
 96         double radLon2 = rad(lon2);
 97         if (radLat1 < 0)
 98             radLat1 = Math.PI / 2 + Math.abs(radLat1);// south
 99         if (radLat1 > 0)
100             radLat1 = Math.PI / 2 - Math.abs(radLat1);// north
101         if (radLon1 < 0)
102             radLon1 = Math.PI * 2 - Math.abs(radLon1);// west
103         if (radLat2 < 0)
104             radLat2 = Math.PI / 2 + Math.abs(radLat2);// south
105         if (radLat2 > 0)
106             radLat2 = Math.PI / 2 - Math.abs(radLat2);// north
107         if (radLon2 < 0)
108             radLon2 = Math.PI * 2 - Math.abs(radLon2);// west
109         double x1 = Math.cos(radLon1) * Math.sin(radLat1);
110         double y1 = Math.sin(radLon1) * Math.sin(radLat1);
111         double z1 = Math.cos(radLat1);
112 
113         double x2 = Math.cos(radLon2) * Math.sin(radLat2);
114         double y2 = Math.sin(radLon2) * Math.sin(radLat2);
115         double z2 = Math.cos(radLat2);
116 
117         double d = Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)
118                 + Math.pow((z1 - z2), 2);
119         // // 余弦定理求夹角
120         // double theta = Math.acos((2 - d) / 2);
121 
122         d = Math.pow(EARTH_RADIUS, 2) * d;
123         // //余弦定理求夹角
124         double theta = Math.acos((2 * Math.pow(EARTH_RADIUS, 2) - d)
125                 / (2 * Math.pow(EARTH_RADIUS, 2)));
126 
127         double dist = theta * EARTH_RADIUS;
128         return dist;
129     }
130 
131     /**
132      * 求两经纬度方向角
133      * 
134      * @param lon1
135      *            第一点的经度
136      * @param lat1
137      *            第一点的纬度
138      * @param lon2
139      *            第二点的经度
140      * @param lat2
141      *            第二点的纬度
142      * @return 方位角,角度(单位:°)
143      * */
144     public static double GetAzimuth(double lon1, double lat1, double lon2,
145             double lat2) {
146         lat1 = rad(lat1);
147         lat2 = rad(lat2);
148         lon1 = rad(lon1);
149         lon2 = rad(lon2);
150         double azimuth = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1)
151                 * Math.cos(lat2) * Math.cos(lon2 - lon1);
152         azimuth = Math.sqrt(1 - azimuth * azimuth);
153         azimuth = Math.cos(lat2) * Math.sin(lon2 - lon1) / azimuth;
154         azimuth = Math.asin(azimuth) * 180 / Math.PI;
155         if (Double.isNaN(azimuth)) {
156             if (lon1 < lon2) {
157                 azimuth = 90.0;
158             } else {
159                 azimuth = 270.0;
160             }
161         }
162         return azimuth;
163     }
164 
165     /**
166      * 已知一点经纬度A,和与另一点B的距离和方位角,求B的经纬度(计算结果有误)
167      * 
168      * @param lon1
169      *            A的经度
170      * @param lat1
171      *            A的纬度
172      * @param distance
173      *            AB距离(单位:米)
174      * @param azimuth
175      *            AB方位角
176      * @return B的经纬度
177      * */
178     public static String GetOtherPoint(double lon1, double lat1,
179             double distance, double azimuth) {
180         azimuth = rad(azimuth);
181         double ab = distance / EARTH_ARC;// AB间弧线长
182         ab = rad(ab);
183         double Lat = Math.asin(Math.sin(lat1) * Math.cos(ab) + Math.cos(lat1)
184                 * Math.sin(ab) * Math.cos(azimuth));
185         double Lon = lon1
186                 + Math.asin(Math.sin(azimuth) * Math.sin(ab) / Math.cos(Lat));
187         System.out.println(Lon + "," + Lat);
188 
189         double a = Math.acos(Math.cos(90 - lon1) * Math.cos(ab)
190                 + Math.sin(90 - lon1) * Math.sin(ab) * Math.cos(azimuth));
191         double C = Math.asin(Math.sin(ab) * Math.sin(azimuth) / Math.sin(a));
192         System.out.println("c=" + C);
193         double lon2 = lon1 + C;
194         double lat2 = 90 - a;
195         return lon2 + "," + lat2;
196     }
197 
198     /**
199      * 已知一点经纬度A,和与另一点B的距离和方位角,求B的经纬度
200      * 
201      * @param lon1
202      *            A的经度
203      * @param lat1
204      *            A的纬度
205      * @param distance
206      *            AB距离(单位:米)
207      * @param azimuth
208      *            AB方位角
209      * @return B的经纬度
210      * */
211     public static String ConvertDistanceToLogLat(double lng1, double lat1,
212             double distance, double azimuth) {
213         azimuth = rad(azimuth);
214         // 将距离转换成经度的计算公式
215         double lon = lng1 + (distance * Math.sin(azimuth))
216                 / (EARTH_ARC * Math.cos(rad(lat1)));
217         // 将距离转换成纬度的计算公式
218         double lat = lat1 + (distance * Math.cos(azimuth)) / EARTH_ARC;
219         return lon + "," + lat;
220     }
221 
222     public static void main(String[] args) {
223         double lon1 = 121.469156;
224         double lat1 = 31.232307;
225         double lon2 = 121.469156;
226         double lat2 = 31.233205;
227         double distance = GetDistanceTwo(lon1, lat1, lon2, lat2);
228         double azimuth = GetAzimuth(lon1, lat1, lon2, lat2);
229         System.out.println("经纬度为(" + lon1 + "," + lat1 + ")的点与经纬度为(" + lon2
230                 + "," + lat2 + ")相距:" + distance + "千米," + "方位角:" + azimuth
231                 + "°");
232         System.out.println("距经纬度为(" + lon1 + "," + lat1 + ")的点" + distance
233                 + "千米,方位角为" + azimuth + "°的另一点经纬度为("
234                 + ConvertDistanceToLogLat(lon1, lat1, distance, azimuth) + ")");
235     }
236 }

 

以上是关于计算经纬度距离方位角的主要内容,如果未能解决你的问题,请参考以下文章

计算经纬度距离方位角

(转)根据经纬度计算方位距离

使用经纬度直接计算距离与方位角

给定(纬度,经度)点,距离和方位,如何获得新的经纬度

获取给定当前点、距离和方位的纬度/经度

已知球面经纬度求方位角和反方位角(awk一行代码实现)