{
"cells": [
{
"cell_type": "markdown",
"id": "1556f8d0",
"metadata": {},
"source": [
"## 使用Python计算地图中两点距离及方位角\n",
"\n",
"例如北京经纬度北纬40.1,东经116.6; 哈尔滨北纬45.7567, 东经126.6424\n",
"\n",
"\n",
"\n",
"感兴趣的童鞋也可去看问题出处 https://stackoverflow.com/questions/3932502/calculate-angle-between-two-latitude-longitude-points/51415608\n",
" \n",
" \n",
"在回答中,看到有地理信息系统Python包geographiclib,可以计算两点距离和角度。\n",
" \n",
"
\n",
"\n",
"## 安装geographiclib\n",
"\n",
"https://geographiclib.sourceforge.io/1.52/python/"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c9cc8840",
"metadata": {},
"outputs": [],
"source": [
"!pip3 install geographiclib==1.52"
]
},
{
"cell_type": "markdown",
"id": "751a6ff3",
"metadata": {},
"source": [
"
\n",
"\n",
"## 计算距离\n",
"\n",
"注意,在接下来的计算中,将北纬、东经表示为正数。将南纬、西经表示为负数。"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f23c6017",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1031617.7918885159"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def distance(beiwei1, dongjing1, beiwei2, dongjing2):\n",
" \"\"\"\n",
" beiwei1: 地点1的纬度数,如果地点在北半球,北纬为正;反之为负。\n",
" dongjing1: 地点2的经度数, 如果位于东半球,东经数为正;反之为负\n",
" beiwei2: 地点2的纬度数\n",
" dongjing2: 地点2的经度数\n",
" \"\"\"\n",
" from geographiclib.geodesic import Geodesic\n",
" geod = Geodesic.WGS84\n",
" g = geod.Inverse(beiwei1, dongjing1, beiwei2, dongjing2)\n",
" distance = g['s12']\n",
" return distance\n",
" \n",
"\n",
"#北京与哈尔滨\n",
"distance(40.1, 116.6, 45.7567, 126.6424)"
]
},
{
"cell_type": "markdown",
"id": "8d5a378e",
"metadata": {},
"source": [
"![](距离.png)\n",
"\n",
"
\n",
"\n",
"## 方位角azimuth\n",
"两个地点在地图中所处的相对位置,称之为方位角azimuth。方位角最大度数360度, \n",
"\n",
"- 0度表示正北\n",
"- 90度表示正西\n",
"- 180度表示正南\n",
"- 270度表示正西\n",
"- 360度表示正北"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "d8a3bd5e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"56.03961942267271"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def azimuth(beiwei1, dongjing1, beiwei2, dongjing2):\n",
" \"\"\"\n",
" beiwei1: 地点1的纬度数,如果地点在北半球,北纬为正;反之为负。\n",
" dongjing1: 地点2的经度数, 如果位于东半球,东经数为正;反之为负\n",
" beiwei2: 地点2的纬度数\n",
" dongjing2: 地点2的经度数\n",
" \"\"\"\n",
" from geographiclib.geodesic import Geodesic\n",
" geod = Geodesic.WGS84\n",
" l = geod.InverseLine(beiwei1, dongjing1, beiwei2, dongjing2)\n",
" s12 = distance(beiwei1, dongjing1, beiwei2, dongjing2)\n",
" g = l.Position(s12, Geodesic.STANDARD | Geodesic.LONG_UNROLL)\n",
" return g['azi2']\n",
"\n",
"#北京 哈尔滨\n",
"azimuth(40.1, 116.6, 45.7567, 126.6424)"
]
},
{
"cell_type": "markdown",
"id": "2d3baeaa",
"metadata": {},
"source": [
"按照azimuth定义,56度的解读为 哈尔滨位于北京的东北方向。\n",
"\n",
"同理可以计算西安与杭州"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "76b20cad",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"115.68482395012738"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#西安, 杭州\n",
"azimuth(34.2658, 108.9541, 30.2741, 120.1552)"
]
},
{
"cell_type": "markdown",
"id": "c186504d",
"metadata": {},
"source": [
"杭州位于西安的115度,即东南方向"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}