脚本如何统计运动时长距离

wen 实用脚本 33

本文目录导读:

脚本如何统计运动时长距离

  1. 方案一:基于手动输入(最通用,适合任何运动)
  2. 方案二:使用浏览器 Geolocation API(前端 JS,实时 GPS)
  3. 方案三:Python 处理 GPX/FIT 文件(分析运动记录)
  4. 方案四:硬件+传感器数据(最底层,如ESP32+GPS模块)
  5. 总结:哪个适合你?

针对“统计运动时长和距离”这一需求,脚本的实现方式取决于数据来源(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)可以导出 GPXFIT 文件,可以用 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 处理。

抱歉,评论功能暂时关闭!