使用高德计算访客距离[建站笔记]
使用开源的纯真 IP 库可以定位到访客的地理位置,但是看到有些站点能计算出距离,于是我查询了下,那么实现方式之一可以使用高德 api 计算访客朋友和你的距离。
注册高德开放中心
首先去高德开放中心注册账号。高德开放平台 | 高德地图 API
然后新建应用,再添加一个 Key。
这里选择 Web 服务,因为主要使用其中的 IP定位API
. 然后就会得到一个 KEY.
点击上面的 IP定位API
就会跳转到对应的文档 IP 定位-基础 API 文档-开发指南-Web 服务 API | 高德地图 API
灰常的简单,只需要一次 Http 请求即可。
!!! 不支持国外的 IP
你就会得到类似这样的结果。
{
"status": "1",
"info": "OK",
"infocode": "10000",
"province": "北京市",
"city": "北京市",
"adcode": "110000",
"rectangle": "116.0119343,39.66127144;116.7829835,40.2164962"
}
那么首先你需要根据用户的请求得到当前用户的客户端 IP.
根据客户端 IP 调用 api 得到上面结果中的 rectangle
. 也就是 IP 所在位置的大概经纬坐标。
计算客户端经纬度
你可以用前两个经纬度坐标,或者你可以算个中心点:
要计算两个地理坐标点的中心位置,我们可以使用中点公式。中点公式对于两个点 和 是:
在地理坐标中,xx 代表经度,yy 代表纬度。给定的坐标是:
和
因此,中心位置大约 是:
然后给自己定个位置,比如我在北京天安门附近。你可以去坐标拾取器 | 高德地图 API 获取位置的经纬度。
比如:
计算坐标之间的距离
然后就需要计算下这两个位置的距离了。
咨询 GPT,假设我使用 java 语言:
在 Java 中,根据经纬度计算两点之间的距离,通常会使用 Haversine 公式,这个公式考虑了地球的曲率。以下是使用 Haversine 公式的 Java 方法示例:
public class GeoDistanceCalculator {
private static final double EARTH_RADIUS_KM = 6371.0;
public static void main(String[] args) {
double[] coord1 = {116.0119343, 39.66127144};
double[] coord2 = {116.7829835, 40.2164962};
double distance = calculateDistance(coord1, coord2);
System.out.println("两点之间的距离: " + distance + " 公里");
}
public static double calculateDistance(double[] coord1, double[] coord2) {
double lon1 = Math.toRadians(coord1[0]);
double lat1 = Math.toRadians(coord1[1]);
double lon2 = Math.toRadians(coord2[0]);
double lat2 = Math.toRadians(coord2[1]);
double deltaLat = lat2 - lat1;
double deltaLon = lon2 - lon1;
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
+ Math.cos(lat1) * Math.cos(lat2)
* Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return EARTH_RADIUS_KM * c;
}
}
这个程序定义了一个calculateDistance
方法,它接受两个坐标数组作为参数,并返回两点之间的距离(单位:公里)。方法内部,首先将经纬度从度转换为弧度,然后应用 Haversine 公式计算距离。
其中,Δlat
和 Δlon
分别是两点间纬度和经度的差值,R
是地球的平均半径(单位:公里),d
是两点间的距离。
请注意,这个计算假设地球是一个完美的球体,实际应用中,这个假设对于大多数用途来说已经足够准确。但是对于更高精度的要求,可能需要考虑地球的椭球体形状。
最终效果
那么就完成了。效果:
需要注意:高德开放平台认证为个人开发者后,该 api 有免费额度。但是不多~,可以说是很少~