设为首页收藏本站
开启辅助访问
切换到宽版

创星网络[分享知识 传递快乐]

 找回密码
 立即注册

QQ登录

只需一步,快速开始

用新浪微博登录

只需一步,快速搞定

搜索
查看: 3914|回复: 0
打印 上一主题 下一主题

经纬度计算大地距离算法

[复制链接]

我玩的应用:

跳转到指定楼层
楼主
发表于 2012-12-12 22:15:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基本假设和概念:

地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为6356.755千米,平均半径6371.004千米。该算法中假设地球为一个完美的球体,半径为6371004。

纬度:
纬度是指某点与地球球心的连线和地球赤道面所成的线面角,其数值在0至90度之间。位于赤道以北的点的纬度叫北纬,记为N,位于赤道以南的点的纬度称南纬,记为S。

经度:
经度,地理学名词,一般指球面坐标系的纵坐标,具体来说就是地球上一个地点离一根被称为本初子午线的南北方向走线以东或以西的度数。按国际规定英国首都伦敦格林尼治天文台原址的那一条经线定为0°经线,然后向左右延伸。

  1. package earth;

  2. import junit.framework.Assert;

  3. import org.junit.Test;

  4. /**
  5. * 本算法只适用北纬和东经地理坐标直接距离的计算。
  6. * */
  7. public class DistanceComputer {

  8.         private static boolean logOn = false;

  9.         private static void log(String msg, Object obj) {
  10.                 if (logOn) {
  11.                         System.out.println(msg + " = " + obj);
  12.                 }
  13.         }

  14.         // 地球半径。单位:米。
  15.         private static double EARTH_RADIUS = 6371004;

  16.         private double sin(double a) {
  17.                 return Math.sin(a);
  18.         }

  19.         private double cos(double a) {
  20.                 return Math.cos(a);
  21.         }

  22.         private double acos(double a) {
  23.                 return Math.acos(a);
  24.         }

  25.         /**
  26.          * 转换经纬度为角度的double显示。只处理到小数点后2位(分:60进制)。
  27.          * */
  28.         private double convert2angle(double a) {
  29.                 log("a", a);
  30.                 // 转换60进制为10进制。
  31.                 double tem = (long) (a * 100) / 100;
  32.                 log("tem", tem);
  33.                 tem += (a * 100) % 100 / 60;
  34.                 log("tem", tem);
  35.                 double result = tem * Math.PI / 180.0;
  36.                 log("result", result);
  37.                 return result;
  38.         }

  39.         private double abs(double a) {
  40.                 return Math.abs(a);
  41.         }

  42.         public double computeDistance(double lat1, double lng1, double lat2,
  43.                         double lng2) {

  44.                 log("lat1", lat1);
  45.                 log("lng1", lng1);
  46.                 log("lat2", lat2);
  47.                 log("lng2", lng2);

  48.                 double OC = cos(convert2angle(lat1));
  49.                 log("OC", OC);

  50.                 double OD = cos(convert2angle(lat2));
  51.                 log("OD", OD);

  52.                 double AC = sin(convert2angle(lat1));
  53.                 log("AC", AC);

  54.                 double BD = sin(convert2angle(lat2));
  55.                 log("BD", BD);

  56.                 // AC=ED
  57.                 double BE = abs(BD - AC);
  58.                 log("BE", BE);

  59.                 double lngGap = convert2angle(lng1) - convert2angle(lng2);
  60.                 log("lngGap", lngGap);

  61.                 // AE=CD.
  62.                 double AE = Math.sqrt(OC * OC + OD * OD - 2 * OC * OD * cos(lngGap));

  63.                 log("AE", AE);

  64.                 double AB = Math.sqrt(AE * AE + BE * BE);
  65.                 log("AB", AB);

  66.                 double angle = acos((2 - AB * AB) / 2);
  67.                 log("angle", angle);

  68.                 double distance = EARTH_RADIUS * angle;
  69.                 log("distance", distance);

  70.                 return distance;
  71.         }

  72.         private double computeDistance(City cityA, City cityB) {
  73.                 return computeDistance(cityA.lat, cityA.lng, cityB.lat, cityB.lng);
  74.         }

  75.         private void testDistance(City cityA, City cityB, double expected,
  76.                         double delta) {

  77.                 System.out.println();

  78.                 System.out.println(cityA.name + " - " + cityB.name + "  ex = "
  79.                                 + expected);

  80.                 double dis = computeDistance(cityA, cityB);

  81.                 System.out.println("dis = " + dis);

  82.                 Assert.assertEquals(expected, dis, delta);
  83.         }

  84.         @Test
  85.         public void test() {

  86.                 double delta = 200000;

  87.                 // 西安钟楼--北京TAM广场 1105.7KM
  88.                 testDistance(City.BeiJing, City.XiAn, 1105700, delta);

  89.                 // 上海航空公司提供的数据,从上海到北京的飞行航程是1088公里
  90.                 testDistance(City.BeiJing, City.ShangHai, 1088000, delta);

  91.                 // 北京与拉萨直线实际距离为2550千米,在1:30000000的地图上
  92.                 testDistance(City.BeiJing, City.LaSa, 2550000, delta);

  93.                 // 西安到拉萨1764.585公里 这个数据是直线距离
  94.                 testDistance(City.XiAn, City.LaSa, 1764585, delta);

  95.                 // 理论是1200多公里
  96.                 testDistance(City.HaErBin, City.BeiJing, 1200000, delta);

  97.                 // 西安市中心到咸阳市中心30公里左右
  98.                 testDistance(City.XiAn, City.XianYang, 30000, delta);
  99.                 // ???
  100.                 // testDistance(City.HaErBin, City.LaSa, 0, delta);
  101.         }

  102.         // 北京市 北京市 北纬39.55 东经116.24
  103.         // 陕西省 西安 北纬34.17 东经108.57
  104.         // 上海市 上海市 北纬31.14 东经121.29
  105.         // 西藏自治区 拉萨 北纬29.39 东经91.08
  106.         // 黑龙江省 哈尔滨 北纬45.44 东经126.36
  107.         // 陕西省 咸阳 北纬34.20 东经108.43
  108.         private static class City {

  109.                 private static City BeiJing = new City("北京", 39.55, 116.24);

  110.                 private static City XiAn = new City("西安", 34.17, 108.57);

  111.                 private static City XianYang = new City("咸阳", 34.20, 108.43);

  112.                 private static City ShangHai = new City("上海", 31.14, 121.29);

  113.                 private static City LaSa = new City("拉萨", 29.39, 91.08);

  114.                 private static City HaErBin = new City("哈尔滨", 45.44, 126.36);

  115.                 String name;
  116.                 double lat;
  117.                 double lng;

  118.                 public City(String name, double lat, double lng) {
  119.                         this.name = name;
  120.                         this.lat = lat;
  121.                         this.lng = lng;
  122.                 }

  123.         }
  124. }
复制代码
from:http://go.cxweb.com.cn/0whh3

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|创星网络 ( 苏ICP备11027519号|网站地图  

GMT+8, 2024-9-22 07:35 , Processed in 0.089451 second(s), 26 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表