综合php项目,高速跑动距离对比?

wen PHP项目 1

PHP项目中的“高速跑动距离对比”实现方案

我理解你的需求是:在一个PHP项目中,实现“高速跑动距离”的对比功能(比如运动员/车辆在不同时段、不同对象间的高速跑动距离对比),由于需求比较简短,我先澄清可能的方向,再给出完整可落地的方案。

综合php项目,高速跑动距离对比?


需求澄清(请确认属于哪种)

场景 说明 数据来源
A. 运动员GPS数据 足球/跑步中,速度超过阈值(如≥20km/h)的累计距离,多人/多场对比 GPS轨迹点(csv/接口)
B. 车辆轨迹 高速行驶路段距离对比 车载GPS/北斗
C. 模拟/演示数据 后台管理系统里的统计对比图表 数据库表

下面以 A/B 通用 的方式给出方案(轨迹点 → 计算高速段距离 → 对比展示),可直接套用。


核心算法:高速跑动距离计算

思路:把轨迹按时间排序,逐段计算相邻两点的距离与速度,速度 ≥ 阈值 的段累加距离。

<?php
/**
 * 高速跑动距离计算
 * @param array $points 轨迹点 [['lat'=>..,'lng'=>..,'ts'=>..], ...]
 * @param float $thresholdKmh 高速阈值(km/h),如 20
 * @return array ['total'=>总距离km, 'high'=>高速距离km, 'ratio'=>占比]
 */
function calcHighSpeedDistance(array $points, float $thresholdKmh = 20.0): array
{
    // 按时间排序
    usort($points, fn($a, $b) => $a['ts'] <=> $b['ts']);
    $total = 0.0;
    $high  = 0.0;
    for ($i = 1, $n = count($points); $i < $n; $i++) {
        $p1 = $points[$i - 1];
        $p2 = $points[$i];
        $distKm = haversineKm($p1['lat'], $p1['lng'], $p2['lat'], $p2['lng']);
        $dtSec  = $p2['ts'] - $p1['ts'];
        if ($dtSec <= 0) continue; // 防脏数据
        $speedKmh = ($distKm / $dtSec) * 3600;
        $total += $distKm;
        if ($speedKmh >= $thresholdKmh) {
            $high += $distKm;
        }
    }
    return [
        'total' => round($total, 3),
        'high'  => round($high, 3),
        'ratio' => $total > 0 ? round($high / $total * 100, 2) : 0,
    ];
}
/** Haversine 球面距离(km) */
function haversineKm(float $lat1, float $lng1, float $lat2, float $lng2): float
{
    $R = 6371.0;
    $dLat = deg2rad($lat2 - $lat1);
    $dLng = deg2rad($lng2 - $lng1);
    $a = sin($dLat/2)**2
       + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLng/2)**2;
    return 2 * $R * asin(min(1, sqrt($a)));
}

⚠️ 注意:GPS 抖动会造成“假高速”,生产中建议:

  • 过滤速度 > 40km/h 的异常点(或按运动类型调阈值)
  • 用滑动窗口平滑(如 3 点平均)
  • 丢弃相邻点时间间隔 > N 秒(如 10s)的段

数据库设计

-- 对象表(运动员/车辆)
CREATE TABLE subjects (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
  type VARCHAR(20)  -- athlete / vehicle
);
-- 轨迹点表
CREATE TABLE track_points (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  subject_id INT,
  lat DECIMAL(10,7),
  lng DECIMAL(10,7),
  ts BIGINT,          -- unix 时间戳
  INDEX idx_subject_ts (subject_id, ts)
);
-- 结果缓存表(避免每次实时算)
CREATE TABLE distance_stats (
  id INT PRIMARY KEY AUTO_INCREMENT,
  subject_id INT,
  session_id VARCHAR(40),   -- 场次/行程
  threshold_kmh DECIMAL(4,1),
  total_km DECIMAL(8,3),
  high_km DECIMAL(8,3),
  ratio DECIMAL(5,2),
  created_at DATETIME
);

对比查询与展示

多对象对比(PHP 层)

$pdo = new PDO('mysql:host=localhost;dbname=sport', 'root', '');
$stmt = $pdo->prepare("SELECT * FROM track_points WHERE subject_id = ? ORDER BY ts");
$subjects = $pdo->query("SELECT id, name FROM subjects")->fetchAll();
$result = [];
foreach ($subjects as $s) {
    $stmt->execute([$s['id']]);
    $points = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $stat = calcHighSpeedDistance($points, 20.0);
    $result[] = array_merge($s, $stat);
}
// 按高速距离降序
usort($result, fn($a, $b) => $b['high'] <=> $a['high']);

前端对比图表(ECharts 示例)

<div id="chart" style="width:800px;height:400px;"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
<script>
const data = <?= json_encode($result, JSON_UNESCAPED_UNICODE) ?>;
const chart = echarts.init(document.getElementById('chart'));
chart.setOption({ { text: '高速跑动距离对比 (≥20km/h)' },
  tooltip: { trigger: 'axis' },
  legend: { data: ['总距离', '高速距离'] },
  xAxis: { type: 'category', data: data.map(d => d.name) },
  yAxis: { type: 'value', name: 'km' },
  series: [
    { name: '总距离', type: 'bar', data: data.map(d => d.total) },
    { name: '高速距离', type: 'bar', data: data.map(d => d.high),
      label: { show:true, formatter: p => p.value + 'km' } }
  ]
});
</script>

性能优化建议

  1. 预计算 + 缓存:轨迹入库时异步计算 distance_stats,查询时直接读表。
  2. 只算增量:新点入库时只需与上一点比较,累加即可(O(1) 更新)。
  3. 大量数据用空间索引:MySQL 8 的 POINT + SPATIAL INDEX,或 Redis GEO。
  4. 阈值可配置:不同运动类型(足球 20km/h、马拉松 15km/h、车辆 80km/h)存 threshold_kmh 字段。

需要你进一步明确的信息

为了给你更精准的代码,请补充:

  1. 数据来源:CSV 文件?GPS 设备接口?数据库已有表?
  2. 对比维度:人与人对 比?同一人不同场次对比?多队伍对比?
  3. "高速"阈值:固定值还是按运动类型?
  4. 展示形式:后台表格、图表、导出 Excel?
  5. 数据规模:单次多少点(几百 / 几万 / 百万级)?

告诉我这些,我可以直接给出贴合你项目的完整代码(含路由、控制器、视图)。

上一篇根据赛后php项目,边路攻防谁更占优?

下一篇当前分类已是最新一篇

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

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝