(转)根据经纬度计算方位距离
Posted zhd_七
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(转)根据经纬度计算方位距离相关的知识,希望对你有一定的参考价值。
(原文地址: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以上是关于(转)根据经纬度计算方位距离的主要内容,如果未能解决你的问题,请参考以下文章