0%

中国城市之间的球面距离计算


经纬度数据

很明显,要就算城市之间的球面距离,那就需要确定各个城市在地球上所处的位置,也就是经纬度。

这里最简单的方式就是去百度地图开放平台里面去下载一份百度地图城市名称-中心点经纬度(cityCenter)关系对照文本

http://lbsyun.baidu.com/index.php?title=open/dev-res

这里面应该包含了中国绝大部分城市的经纬度数据,格式如下:

1
2
3
4
5
6
7
8
9
{municipalities:[{n:"北京",g:"116.395645,39.929986|12"},
{n:"上海",g:"121.487899,31.249162|12"},
{n:"天津",g:"117.210813,39.14393|12"},
{n:"重庆",g:"106.530635,29.544606|12"}],
provinces:[{n:"安徽",g:"117.216005,31.859252|8",
cities:[{n:"合肥",g:"117.282699,31.866942|12"},
{n:"安庆",g:"117.058739,30.537898|13"},
{n:"蚌埠",g:"117.35708,32.929499|13"},
...

长得跟json差不多,但是又不是json,因为这里所有键值都没有加上引号",为了方便解析, 可以直接使用文本编辑器来把这些键值替换为带有引号的形式。

解析后,将每个所有城市的经纬度解析出来,重新格式化为json,得到如下文件:


城市间距离计算

球面距离有很多种计算方法,这里就不考虑地球实际是个椭圆体的问题了,直接使用Haversine算法比较简单。

这里也是参考网上别人写的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"math"
)

// Haversine 算法:通过两地经纬度计算两地的球面距离(正球体,非椭圆)

const EarthRadius float64 = 6371.0 //km 地球半径 平均值,千米

func DegToRadians(degrees float64) float64 {
return (degrees * math.Pi) / 180
}

func GetDistanceFromLatLonInKm(lat1, lon1, lat2, lon2 float64) float64 {
var dLat = DegToRadians(lat2-lat1)
var dLon = DegToRadians(lon2-lon1)
var a = math.Sin(dLat/2) * math.Sin(dLat/2) + math.Cos(DegToRadians(lat1)) * math.Cos(DegToRadians(lat2)) *
math.Sin(dLon/2) * math.Sin(dLon/2)

var c = math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
var d = 2 * EarthRadius * c
return d
}

这样简单的两两计算,就可以得到中国各个城市之间的距离:

在实际使用的情况中,如果不想浪费内存,可以考虑使用坐标实时计算,浪费点CPU。