本文详解如何解析 admiralty tide api 的 geojson 数据,结合 haversine 公式精确计算球面距离,并快速定位最近站点的 `id` 字段,适用于潮位查询、地理服务集成等实际场景。
在处理地理坐标数据(如潮位站、气象站或地图标记)时,一个常见需求是:给定用户当前经纬度,从远程 API 返回的大量站点中找出物理距离最近的一个,并提取其唯一标识(如 properties->Id)。原始代码存在多重嵌套循环、错误的数组遍历路径(误将整个 $locations 当作多维数组逐层 foreach),且使用欧氏距离(平面直角坐标系)计算经纬度——这在地球曲面上会产生显著误差(尤其跨纬度时)。下面提供一套健壮、可复用、符合地理精度要求的解决方案。
✅ 正确解析结构 & 遍历逻辑
Admiralty 的 /Home/GetStations 接口返回标准 GeoJSON FeatureCollection,其核心结构为:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [lng, lat] },
"properties": { "Id": "0065", "Name": "PORTSMOUTH", ... }
}
]
}
关键点:
- coordinates 是 [longitude, latitude](注意顺序!X 轴为经度,Y 轴为纬度);
- 应直接遍历 $stations->features(对象模式)或 $stations[‘features’](关联数组模式),无需深层嵌套 foreach;
- 使用 json_decode($json, false)(默认 false)返回对象,更符合 GeoJSON 规范访问习惯。
✅ 使用 Haversine 公式计算真实球面距离
地球是球体,两点间最短路径是大圆弧。以下函数封装了高精度 Haversine 计算,支持公里(km)、英里(mi)和海里(nmi)三种单位: