`
zhang_xzhi_xjtu
  • 浏览: 538370 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

经纬度计算大地距离算法

    博客分类:
  • GIS
 
阅读更多
基本假设和概念:

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

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

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




package earth;

import junit.framework.Assert;

import org.junit.Test;

/**
 * 本算法只适用北纬和东经地理坐标之间距离的计算。
 * */
public class DistanceComputer {

	private static boolean logOn = false;

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

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

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

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

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

	/**
	 * 转换经纬度为角度的double显示。只处理到小数点后2位(分:60进制)。
	 * */
	private double convert2angle(double a) {
		log("a", a);
		// 转换60进制为10进制。
		double tem = (long) (a * 100) / 100;
		log("tem", tem);
		tem += (a * 100) % 100 / 60;
		log("tem", tem);
		double result = tem * Math.PI / 180.0;
		log("result", result);
		return result;
	}

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

	public double computeDistance(double lat1, double lng1, double lat2,
			double lng2) {

		log("lat1", lat1);
		log("lng1", lng1);
		log("lat2", lat2);
		log("lng2", lng2);

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

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

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

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

		// AC=ED
		double BE = abs(BD - AC);
		log("BE", BE);

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

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

		log("AE", AE);

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

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

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

		return distance;
	}

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

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

		System.out.println();

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

		double dis = computeDistance(cityA, cityB);

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

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

	@Test
	public void test() {

		double delta = 200000;

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

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

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

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

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

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

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

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

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

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

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

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

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

		String name;
		double lat;
		double lng;

		public City(String name, double lat, double lng) {
			this.name = name;
			this.lat = lat;
			this.lng = lng;
		}

	}
}

  • 大小: 118.5 KB
分享到:
评论

相关推荐

    基于经纬度计算方向,距离等

    本文讨论的主题是基于经纬度计算方向和距离的问题,这是地理信息系统(GIS)、导航系统、地图制作以及许多需要位置计算的场合中常见需求。要精确地完成这一任务,涉及到地球椭球体模型上大地线(或称为测地线)的...

    经纬度计算距离公式经纬度计算距离公式

    经纬度计算距离公式是地理信息系统(GIS)和导航应用中的基础工具,用于估算两个地理位置之间的直线距离或实际地面距离。本文将深入探讨经纬度计算距离的原理、公式以及在实际应用中的计算方法。 首先,地球并非...

    经纬度转大地坐标

    4. **算法应用**:使用已知的数学公式,如高斯-克吕格反解法,将经纬度坐标转化为大地坐标。 5. **软件实现**:"最新完整版坐标转换软件Coord(含说明书)" 提供了这种转换的功能。用户只需输入经纬度坐标,选择相应...

    UTM.rar_UTM_经纬度_经纬度 UTM_经纬度转大地坐标_经纬度转大地坐标软件

    在实际应用中,这可以通过专业软件或算法实现,如描述中提到的“经纬度转大地坐标软件”。 在进行经纬度到UTM的转换时,首先需要确定目标区域所在的UTM带区,然后使用特定的转换公式,这些公式通常包括地球半径、...

    面积计算_面积计算_面积经纬_面积_经纬度面积_经纬度计算_

    6. **大地地块角点计算**:在描述中提到的“大地地块角点”,是指地块边界上的转折点,这些点的经纬度坐标可以作为输入,通过数学算法(如Green公式或Shoelace公式)来确定多边形的面积。 7. **MATLAB编程**:这两...

    delphi经纬度换算源程序

    7. **算法实现**:经纬度转换通常涉及特定的数学公式和算法,如Helmert转换、Mercator投影等。在Delphi程序中,这些转换会被封装成函数或类,输入经纬度值,输出转换后的坐标。 8. **源码学习与应用**:拥有源码...

    geodesy测算经纬度距离

    在编程中,geodesy算法常常用于计算经纬度坐标下的地理位置之间的实际距离。 `org.gavaghan.geodesy` 是一个Java库,它提供了计算地球上任意两个经纬度坐标之间距离的功能。这个库的名称暗示了它是由Michael ...

    经纬度大地坐标互相转换

    在VC环境中,可以使用数学库和自定义函数来实现这些计算,例如,利用C++标准库中的浮点运算和自定义的坐标转换算法。 反之,从大地坐标转换到经纬度则需要逆向执行上述过程,首先解投影,然后将大地椭球体参数还原...

    经纬度和方位计算小工具

    src目录下的文件很可能是程序的源代码文件,包括主程序、函数实现、头文件等,可能包含了计算经纬度、距离和方位角的具体算法。 对于开发者来说,理解和使用这个小工具,需要熟悉基础的地理坐标系统、球面和椭球面...

    C#经纬度坐标与大地坐标相互转换工具

    然而,对于精确的地理计算和分析,如测量距离或进行地图投影,我们需要使用大地坐标系统。在中国,最常用的是2000国家大地坐标系(CGCS2000),它是一种基于地球椭球体的三维直角坐标系统。在国际上,常见的有WGS84...

    WPF做的大地主题正解,根据经纬度方位角和距离计算下一个坐标点

    描述中提到,该程序能够根据已知的经纬度、方位角和前进距离,计算出新的目标坐标点。这是基于球面三角学的原理,通过给定的初始位置(经纬度),以及相对于真北的方位角(角度)和前进的距离(弧度或公里),可以...

    大地坐标与经纬度坐标转换

    4. **转换过程**:从经纬度到大地坐标的转换通常涉及椭球参数、子午线收敛角、地理坐标到大地坐标投影以及可能的带号计算。反过来,从大地坐标到经纬度需要逆过程。这通常需要用到特定的算法或软件,比如压缩包中的...

    Python中如何利用经纬度进行距离计算

    `geopy`库提供了`geodesic`类,可以计算两点间的大地距离(大圆距离),这是地球表面上两点之间最短路径。它考虑了地球的曲率,因此结果更准确。`geodesic`对象的`.m`属性可以直接给出以米为单位的距离。 4. **...

    大地坐标-经纬度 转换

    - **BLXYHelp.chm**:这可能是一个帮助文档,详细介绍了“大地坐标-经纬度”转换的算法和使用方法,可能包含具体的公式和步骤。 - **BLXY.EXE**:这可能是一个应用程序,用于实际执行坐标转换操作。用户输入坐标后,...

    matlab开发-大地距离wgs84大地水准面

    计算大地距离时,我们通常使用球面或椭球体上的大圆距离公式,因为地球表面可以近似看作一个曲面。在MATLAB中,`vdist.m`这个文件可能包含了一个函数,该函数实现了基于WGS84的Haversine公式或者Vincenty公式来计算...

    VC大地坐标转换经纬度代码

    - 通常会涉及多项式或迭代算法来求解大地纬度。 4. **大地纬度到地理纬度的转换**:由于大地纬度是基于椭球面的,需要将其转换为实际的地理纬度。 5. **大地经度到地理经度的转换**:这一步相对简单,因为大地经度...

    距离计算的软件

    用户输入两个坐标的值,软件会根据所选坐标系的规则计算出这两点之间的直线距离或大地距离(考虑到地球曲率)。 标签中包含“距离计算”,这是软件的主要功能;“坐标”表示计算基于坐标点;“GPS”暗示软件可能...

    WGS84地球椭球上的大地距离:快速计算地球椭球上坐标之间的大地距离。-matlab开发

    1975 年,Vincenty 发表了一种快速收敛算法,用于计算椭球体地球上点之间的距离。 该算法精确到几毫米以内。 从那以后,他的算法在大地测量学和工程学中得到了重要的应用。 在调整算法以在所有情况下收敛(原始在...

    雷达探测极坐标系(AER)与地球等经纬度坐标系(GEO)转换公式推导

    此步骤涉及到角度与距离的几何关系计算。 1. **计算高度\(H\)**: 假设雷达架设高度为\(h\),则探测点B的绝对高度\(H = h + r \cdot \cos(\delta)\)。 2. **计算水平位移**: - \(X = r \cdot \sin(\delta) \cdot \...

    以35省份的中心城市为例用遗传算法和模拟退火算法计算出最短距离及路线,matlab2021a仿真

    这个函数很可能是计算旅行商问题中各路径长度的模块,它会根据省会城市的经纬度坐标计算两城市之间的欧氏距离或者大地距离。 6. **genetic_algorithm.m** 和 **simulated_annealing.m**: 这两个文件分别是遗传...

Global site tag (gtag.js) - Google Analytics