intminds / gps
用于解析 .gpx 文件和操作 GPS 轨迹的库。
Requires
- php: ~7.2
- ext-libxml: *
- ext-simplexml: *
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-20 23:49:09 UTC
README
用于解析 .gpx 文件和操作 GPS 轨迹的库。
该库的主要目标是可扩展性。几乎所有算法都实现为策略,可以替换(距离计算、海拔计算、平滑过滤器等)
要求
PHP 7.2+(已在 7.2 和 7.3 上测试)。
安装
composer require intminds/gps:"dev-master@dev"
稳定版本即将推出...
功能
- 解析来自 .gpx 文件的轨迹(
<trk>标签)。 - 支持一个 gpx 文件中的多个轨迹。
- 展平(将多个具有多个段的多条轨迹转换为具有多个段的一条轨迹)。
- 支持轨迹标题和段标题(段标题 - 在 GPS Track Editor 格式,因为原始规范中没有段标题 (https://www.topografix.com/gpx.asp))。
- 轨迹和段的开头和结束点。
- 计算轨迹的边界矩形。
- 距离计算(提供 1 种算法,您可以编写自己的)。
- 海拔计算(提供 2 种算法,您可以编写自己的)。
- 支持“处理器”,可以将属性分配给轨迹点(如距离、方向、速度),从轨迹中添加和删除点。现在已实现
DistanceProcessor将“距离”属性分配给每个轨迹点(从起点开始的距离)。ThinOutProcessor删除彼此太近的点(用于在不丢失重要信息的情况下减少轨迹大小)。TriangularElevationFilterProcessor使用三角形窗口过滤器平滑点的海拔。- 您可以自己编写更多的处理器。
- 轨迹、段、点和点类实现了 \Traversable,可以用于轻松转换为 JSON 兼容格式。
- 100% 测试覆盖率。
未实现
- ❌ 支持 .gpx 轨迹和航点(
<rte>和<wpt>标签)。 - ❌ 从 GPXFile、轨迹、段等创建 .gpx 文件。
- ❌ 平滑 lat/lng 以更好地计算距离。
- 统计计算(距离、海拔等)只能应用于轨迹和段/点级别。如果 GPX 轨迹包含多个轨迹,则没有整个 GPX 轨迹的统计信息。尽管如此,您可以展平轨迹(使用 GPXFile::flatten() 将所有轨迹转换为具有多个段的一条轨迹),并计算结果轨迹的统计信息。
如果您需要上述任何功能,我们建议使用 https://github.com/Sibyx/phpGPX。尽管如此,如果需要实现自己的数学计算,phpGPX 库看起来对我们的扩展性更小。
基本使用示例
运行 php examples/basic.php
declare(strict_types=1); namespace Intminds\GPS; require_once "../vendor/autoload.php"; $file = GPXFile::createFromFile(dirname(__FILE__) . "/run.gpx"); $track = $file->flatten(); echo "Title: {$track->getTitle()}\n\n"; // Title: Evening Run echo "Distance: {$track->calcDistance()} m\n\n"; // Distance: 5897.7224760213 m echo "Number of segments: " . sizeof($track->getSegments()) . "\n"; echo "Number of points: " . sizeof($track->getSegments()[0]->getPoints()) . "\n\n"; // Number of segments: 1 // Number of points: 1484 $ele = $track->calcElevation(); echo "Elevation gain: {$ele->elevationGain} m, loss: {$ele->elevationLoss} m\n\n"; $borders = $track->calcBorders(); // Elevation gain: 324.1 m, loss: 325.9 m echo "Track bounding rect:\n"; echo "- latitude in [{$borders->minLat}, {$borders->maxLat}]\n"; echo "- longitude in [{$borders->minLng}, {$borders->maxLng}]\n\n"; // Track bounding rect: // - latitude in [55.935543, 55.951048] // - longitude in [-3.17725, -3.158218] echo "Start point: ({$track->getStart()->lat}, {$track->getStart()->lng})\n"; echo "- altitude = {$track->getStart()->alt} m\n"; echo "- time = " . date("Y-m-d H:i:s", $track->getStart()->time) . "\n\n"; // Start point: (55.935731, -3.169383) // - altitude = 72.8 m // - time = 2017-04-28 18:36:32 $movement = Defaults::getMovementCalc()->getDistance($track->getStart(), $track->getFinish()); echo "How far the finish point is from the start point: {$movement} m\n\n"; // How far the finish point is from the start point: 21.724416911272 m
海拔计算
有一种简单的方法用于海拔增益计算。您可以比较每个点的海拔与上一个点的海拔,如果差异大于零,则将其添加到总海拔增益中。
这种方法不太有效。如果您沿着平坦的表面行走/跑步/骑行,小的非重要海拔变化会累积成大的海拔增益和损失。
我们的实验表明,这是一种不错的海拔计算算法,可以使用我们的库实现(运行 php examples/elevation.php)
declare(strict_types=1); namespace Intminds\GPS; use Intminds\GPS\Elevation\ElementaryElevationCalc; use Intminds\GPS\Elevation\ThresholdElevationCalc; use Intminds\GPS\Processors\DistanceProcessor; use Intminds\GPS\Processors\TriangularElevationFilterProcessor; require_once "../vendor/autoload.php"; $file = GPXFile::createFromFile(dirname(__FILE__) . "/run.gpx"); $track = $file->flatten(); // NAIVE APPROACH $ele = $track->calcElevation(new ElementaryElevationCalc()); echo "Elevation gain (naive approach): {$ele->elevationGain} m, loss: {$ele->elevationLoss} m\n"; // Elevation gain (naive approach): 324.1 m, loss: 325.9 m // ADVANCED APPROACH // Assigning a distance from the start to each point. // This is required by TriangularElevationFilterProcessor. // If it's not done, MissingPropException is raised. $proc1 = new DistanceProcessor(); $track->applyProcessor($proc1); // Smoothing data with triangular window filter (triangle base length is 60m) $proc2 = new TriangularElevationFilterProcessor($windowSize = 60.0); $track->applyProcessor($proc2); // Applying a special elevation calculator which omits any altitude variations which are less than $minimalChange. $ele = $track->calcElevation(new ThresholdElevationCalc($minimalChange = 2.0)); echo "Elevation gain (advanced approach): {$ele->elevationGain} m, loss: {$ele->elevationLoss} m\n"; // Elevation gain (advanced approach): 245.37668979092 m, loss: 247.98170342056 m
算法适用性检查
对于 examples/run.gpx 文件,流行的应用程序 Strava 提供的爬升高度为 229 米。这比我们上面得到的值略低(245 米)。您可以尝试调整参数,但根据我们的意见,Strava 进行了过于激进的平滑处理,这减少了总爬升高度。值 $windowSize = 60.0 和 $minimalChange = 2.0 是基于将 5 条不同轨迹的爬升高度与 Strava 进行比较,以及对某些轨迹进行手动爬升高度计算的结果。