
在处理地理空间数据时,我们经常需要计算两点间的实际驾驶距离。这通常通过调用第三方地图服务的api来实现。以下是一个使用osrm(open source routing machine)公共api计算驾驶距离的python函数示例。osrm提供了一个开放且高性能的路由服务,非常适合此类任务。
import requests
import json
import pandas as pd
from contextlib import contextmanager
from time import sleep
import http.client # For HTTPStatus
def get_driving_distance(lat1, lon1, lat2, lon2):
"""
通过OSRM API计算两点间的驾驶距离。
参数:
lat1 (float): 起点纬度
lon1 (float): 起点经度
lat2 (float): 终点纬度
lon2 (float): 终点经度
返回:
float: 驾驶距离(英里),如果请求失败则返回None
"""
try:
# OSRM API的URL结构:/route/v1/car/{lon1},{lat1};{lon2},{lat2}
url = f"http://router.project-osrm.org/route/v1/car/{lon1},{lat1};{lon2},{lat2}?overview=false"
response = requests.get(url)
# 检查HTTP响应状态码,如果不是2xx则抛出异常
response.raise_for_status()
data = json.loads(response.content)
# 检查API响应中是否有路由信息
if data.get("routes") and len(data["routes"]) > 0:
driving_distance_meters = data["routes"][0]['distance']
# 将米转换为英里 (1 英里 = 1609.34 米)
driving_distance_miles = driving_distance_meters / 1609.34
return driving_distance_miles
else:
print(f"API响应未包含有效路由信息: {data}")
return None
except requests.exceptions.RequestException as e:
print(f"API请求失败: {e}")
return None
except json.JSONDecodeError as e:
print(f"JSON解析失败: {e}")
return None
except KeyError as e:
print(f"API响应结构异常,缺少键: {e}")
return None
注意事项:
当需要进行大量API调用时,为了避免对API服务器造成过大压力或触及API服务提供商的调用限制,实现请求限流(Rate Limiting)至关重要。我们可以利用Python的上下文管理器(contextlib.contextmanager)来优雅地实现这一功能。
# 定义一个全局变量来跟踪API调用次数
api_calls = 0
@contextmanager
def rate_limited(limit=500, delay=5):
"""
一个上下文管理器,用于限制API调用频率。
当API调用次数达到指定限制时,暂停指定时间。
参数:
limit (int): 在暂停前允许的最大API调用次数。
delay (int): 暂停的秒数。
"""
global api_calls
# 检查是否即将超过限制
if api_calls + 1 >= limit:
print(f"达到 {limit} 次API调用限制,暂停 {delay} 秒...")
sleep(delay)
# 暂停后,重置计数器(或减去已处理的批次)
api_calls = 0 # 简单重置,也可以 api_calls -= limit
api_calls += 1
yield # 执行被包装的代码
# 上下文退出时,无需额外操作
# 更新 get_driving_distance 函数以集成限流
def get_driving_distance_with_rate_limit(lat1, lon1, lat2, lon2):
"""
通过OSRM API计算两点间的驾驶距离,并集成请求限流。
"""
with rate_limited(): # 在这里应用限流
return get_driving_distance(lat1, lon1, lat2, lon2)
工作原理:
最终目标是将原始的地理坐标数据与计算出的驾驶距离整合到一个结构化的Pandas DataFrame中,方便后续的数据分析和可视化。
立即学习“Python免费学习笔记(深入)”;
假设我们有四组列表数据:起点纬度、起点经度、终点纬度、终点经度。
# 示例数据
location_latitudes = [51.5074, 40.7128, 34.0522]
location_longitudes = [-0.1278, -74.0060, -118.2437]
station_latitudes = [51.5154, 40.7580, 34.0522]
station_longitudes = [-0.0920, -73.9855, -118.2437]
# 存储计算出的距离
driving_distances = []
# 遍历数据并计算距离
for i in range(len(location_latitudes)):
lat1 = location_latitudes[i]
lon1 = location_longitudes[i]
lat2 = station_latitudes[i]
lon2 = station_longitudes[i]
distance = get_driving_distance_with_rate_limit(lat1, lon1, lat2, lon2)
driving_distances.append(distance)
# 打印进度(可选)
print(f"处理第 {i+1} 对坐标: ({lat1},{lon1}) -> ({lat2},{lon2}), 距离: {distance:.2f} 英里")
# 创建DataFrame
data = {
'Location_Lat': location_latitudes,
'Location_Lon': location_longitudes,
'Station_Lat': station_latitudes,
'Station_Lon': station_longitudes,
'Driving_Distance_Miles': driving_distances
}
df = pd.DataFrame(data)
print("\n最终生成的DataFrame:")
print(df)
代码说明:
本教程展示了如何结合Python的 requests 库、上下文管理器以及Pandas库,高效且稳定地处理地理距离计算任务。以下是一些额外的最佳实践和考虑事项:
通过遵循这些指导原则,您可以构建出稳定、高效且符合规范的地理空间数据处理应用程序。
以上就是Python中通过API获取地理距离:请求限流与数据整合实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号