本文目录导读:

- 方案一:基于手动输入(最通用,适合任何运动)
- 方案二:使用浏览器
Geolocation API(前端 JS,实时 GPS) - 方案三:Python 处理 GPX/FIT 文件(分析运动记录)
- 方案四:硬件+传感器数据(最底层,如ESP32+GPS模块)
- 总结:哪个适合你?
针对“统计运动时长和距离”这一需求,脚本的实现方式取决于数据来源(GPS传感器、加速度计、手动输入或第三方API)。
以下是几种常见的脚本实现方案,涵盖前端(浏览器)、后端(Python) 以及可穿戴设备的场景。
基于手动输入(最通用,适合任何运动)
如果你的数据是用户手动输入的(比如在网页或App表单里填写开始/结束时间、跑的距离),脚本逻辑非常简单。
Python 脚本示例:
from datetime import datetime
def calculate_running_stats(start_time_str, end_time_str, distance_km):
# 输入格式: "2023-10-27 08:00:00"
start = datetime.strptime(start_time_str, "%Y-%m-%d %H:%M:%S")
end = datetime.strptime(end_time_str, "%Y-%m-%d %H:%M:%S")
duration_seconds = (end - start).total_seconds()
duration_minutes = duration_seconds / 60
duration_hours = duration_seconds / 3600
# 计算配速(分钟/公里)
if distance_km > 0:
pace = duration_minutes / distance_km
pace_str = f"{int(pace // 60)}分{int(pace % 60)}秒/公里"
else:
pace_str = "无"
speed_kmh = distance_km / duration_hours if duration_hours > 0 else 0
print(f"运动时长: {int(duration_hours)}小时{int(duration_minutes % 60)}分钟")
print(f"运动距离: {distance_km:.2f} 公里")
print(f"平均配速: {pace_str}")
print(f"平均速度: {speed_kmh:.2f} 公里/小时")
# 使用
calculate_running_stats("2023-10-27 08:00:00", "2023-10-27 09:25:00", 10.5)
使用浏览器 Geolocation API(前端 JS,实时 GPS)
这是最贴近“自动统计距离” 的方式,利用手机/电脑的 GPS 每几秒获取位置,累加两点间的距离。
HTML + JavaScript 脚本:
<!DOCTYPE html>
<html>
<body>
<button onclick="startTracking()">开始运动</button>
<button onclick="stopTracking()">结束运动</button>
<p>距离: <span id="distance">0</span> 米</p>
<p>时长: <span id="duration">0</span> 秒</p>
<script>
let watchId = null;
let startTime = null;
let totalDistance = 0; // 米
let lastPosition = null;
// 计算两点之间的距离 (Haversine公式)
function calcDistance(lat1, lon1, lat2, lon2) {
const R = 6371000; // 地球半径(米)
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
function updatePosition(position) {
if (lastPosition) {
const dist = calcDistance(
lastPosition.coords.latitude, lastPosition.coords.longitude,
position.coords.latitude, position.coords.longitude
);
// 过滤噪声 (GPS误差,小于1米的不算)
if (dist > 1) {
totalDistance += dist;
document.getElementById('distance').textContent = totalDistance.toFixed(1);
}
}
lastPosition = position;
// 更新时长
if (startTime) {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
document.getElementById('duration').textContent = elapsed;
}
}
function handleError(error) {
console.error('GPS错误:', error.message);
}
function startTracking() {
startTime = Date.now();
totalDistance = 0;
lastPosition = null;
if ("geolocation" in navigator) {
watchId = navigator.geolocation.watchPosition(updatePosition, handleError, {
enableHighAccuracy: true, // 使用GPS
maximumAge: 1000, // 缓存1秒
timeout: 5000 // 超时5秒
});
} else {
alert("您的浏览器不支持GPS");
}
}
function stopTracking() {
if (watchId) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
alert(`运动结束!总距离: ${totalDistance.toFixed(1)} 米`);
}
</script>
</body>
</html>
特点:
- 实时更新,不需要服务器。
- 注意:需要在 HTTPS 下运行,手机浏览器在后台可能暂停更新。
Python 处理 GPX/FIT 文件(分析运动记录)
很多运动手表(Garmin、Apple Watch)可以导出 GPX 或 FIT 文件,可以用 Python 解析这些文件来复盘运动。
Python 解析 GPX 文件 (使用 gpxpy 库):
pip install gpxpy
脚本:
import gpxpy
from datetime import datetime
def analyze_gpx(gpx_file_path):
with open(gpx_file_path, 'r') as f:
gpx = gpxpy.parse(f)
total_distance = 0 # 米
total_time = 0 # 秒
track = gpx.tracks[0]
segment = track.segments[0]
points = segment.points
# 总距离 (通过点与点累加)
for i in range(1, len(points)):
total_distance += points[i-1].distance_2d(points[i])
# 总时长 (第一个点和最后一个点的时间戳差)
if points[0].time and points[-1].time:
total_time = (points[-1].time - points[0].time).total_seconds()
# 计算平均配速 vs 速度
avg_speed_kmh = (total_distance / 1000) / (total_time / 3600) if total_time > 0 else 0
print(f"总距离: {total_distance / 1000:.2f} 公里")
print(f"运动时长: {total_time // 3600:.0f}小时{(total_time % 3600) // 60:.0f}分钟")
print(f"平均速度: {avg_speed_kmh:.2f} 公里/小时")
analyze_gpx("my_run.gpx")
硬件+传感器数据(最底层,如ESP32+GPS模块)
如果你是在做硬件开发(Arduino/ESP32),可以通过读取 GPS 模块(如 NEO-6M)的 NMEA 数据包来计算。
伪代码逻辑:
每1秒读取一次GPS坐标 (NMEA $GPGGA 或 $GPRMC 语句)
有fix并且位置有效:
这是第一个点:
存储为 last_lat, last_lon
否则:
计算 last_lat,last_lon 到 当前lat,lon 的距离 (Haversine)
累加 distance += 该段距离
更新 last_lat, last_lon
运动时长 = 当前时间 - 开始时间 (系统计时器)
哪个适合你?
| 场景 | 推荐方案 | 语言/工具 |
|---|---|---|
| 网页/App 实时记录 | 方案二 (Geolocation API) | JavaScript |
| 复盘手表/手机数据 | 方案三 (GPX解析) | Python + gpxpy |
| 简单手动计算 | 方案一 (手动输入) | Python / 任何语言 |
| 硬件DIY手环 | 方案四 (读取GPS模块) | C++ (Arduino) / MicroPython |
建议: 如果是做小程序或网页,直接使用 Geolocation API 是最快的,如果需要对运动效果进行大数据分析,推荐将数据导出为 GPX 后用 Python 处理。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播