PHPackages                             intminds/gps - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. intminds/gps

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

intminds/gps
============

Lib for parsing .gpx files and working with GPS tracks.

3131PHPCI failing

Since Nov 20Pushed 6y ago1 watchersCompare

[ Source](https://github.com/intminds/gps)[ Packagist](https://packagist.org/packages/intminds/gps)[ RSS](/packages/intminds-gps/feed)WikiDiscussions master Synced 4w ago

READMEChangelogDependenciesVersions (1)Used By (0)

gps
===

[](#gps)

[![Build Status](https://camo.githubusercontent.com/3e70cd8ca0b2d172726756553fd4acfacbbb5d744ffdfaab9acb2235dfbaf2e1/68747470733a2f2f7472617669732d63692e6f72672f696e746d696e64732f6770732e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/intminds/gps)[![Coverage Status](https://camo.githubusercontent.com/fc7e5f0e1c6e6c5845af11673b3a461cfa081ab68f812f924e46d3ef4f19a123/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f696e746d696e64732f6770732f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/intminds/gps?branch=master)

Lib for parsing .gpx files and working with GPS tracks.

The main goal of this library is to be extendable. Almost all algorithms are implemented as strategies and can be replaced (distance calculation, elevation calculation, smoothing filters, etc.)

Requirements
------------

[](#requirements)

PHP 7.2+ (tested on 7.2 and 7.3).

Installation
------------

[](#installation)

`composer require intminds/gps:"dev-master@dev"`

Stable version is coming soon...

Features
--------

[](#features)

- Parsing tracks (`` tags) from .gpx file.
- Support of multiple tracks in one gpx file.
- Flattening (converting multiple tracks with multiple segments into one track with multiple segments).
- Support of track titles and segment titles (segment titles - in [GPS Track Editor](http://www.gpstrackeditor.com/) format because there are no segment titles in the [original spec](https://www.topografix.com/gpx.asp)).
- Start and Finish points for tracks and segments.
- Bounding rectangle calculation for a track.
- Distance calculation (1 algorithm provided, you can write your own).
- Elevation calculation (2 algorithms provided, you can write your own).
- Support of "processors" which can assign properties to track points (like distance, direction, speed), add and delete points from a track. Now implemented:
    - `DistanceProcessor` assigns a "distance" property to each track point (distance from the start point).
    - `ThinOutProcessor` removes points which are too close to each other (used to reduce a track size without significant information loss).
    - `TriangularElevationFilterProcessor` smooths points' altitudes using a triangular window filter.
    - You can write more processors yourself.
- Track, Segment, Points and Point classes implement \\Traversable which can be used for easy conversion into JSON-compatible format.
- 100% test coverage.

### Not implemented

[](#not-implemented)

- ❌ Support of .gpx Trails and Waypoints (`` and `` tags).
- ❌ Creating .gpx file back from GPXFile, Track, Segment and so on.
- ❌ Smoothing of lat/lng for better distance calculation.
- Statistics calculation (distance, elevation, etc.) can be applied only to Track and Segment/Points levels. No statistics for the whole GPX track if it has more than 1 track. Nevertheless, you can flatten tracks (convert all tracks into one track with multiple segments using GPXFile::flatten()) and calculate stats for the resulting track.

We recommend using  if you need any of the above. Nevertheless, the phpGPX lib looks for us less extendable if you need to implement your own math.

Basic usage example
-------------------

[](#basic-usage-example)

Run `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
```

Elevation calculation
---------------------

[](#elevation-calculation)

There is a naive approach for elevation gain calculation. You can compare every point's altitude with the previous point's altitude, and if the difference is greater than zero, add it into the total elevation gain.

Such naive approach does not work well. If you go/run/ride along a flat surface, small non-important altitude changes sum up into big elevation gain and loss.

Our experiments show that this is a no-so-bad algorithm for elevation calculation which can be implemented using our library (run `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
```

Algorithm adequacy check:

For the `examples/run.gpx` file a popular app Strava gives elevation gain 229 m. It's slightly less than we received above (245 m). You can play with the parameters but in our opinion Strava does too aggressive smoothing which lessens the total elevation gain. The values `$windowSize = 60.0` and `$minimalChange = 2.0` are based on comparison of 5 different tracks' elevations with Strava and manual elevation gain calculations for some tracks.

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/24375962?v=4)[intminds](/maintainers/intminds)[@intminds](https://github.com/intminds)

---

Top Contributors

[![intminds](https://avatars.githubusercontent.com/u/24375962?v=4)](https://github.com/intminds "intminds (31 commits)")

### Embed Badge

![Health badge](/badges/intminds-gps/health.svg)

```
[![Health](https://phpackages.com/badges/intminds-gps/health.svg)](https://phpackages.com/packages/intminds-gps)
```

###  Alternatives

[mtdowling/jmespath.php

Declaratively specify how to extract elements from a JSON document

2.0k472.8M135](/packages/mtdowling-jmespathphp)[opis/closure

A library that can be used to serialize closures (anonymous functions) and arbitrary data.

2.6k230.0M282](/packages/opis-closure)[masterminds/html5

An HTML5 parser and serializer.

1.8k242.8M226](/packages/masterminds-html5)[sabberworm/php-css-parser

Parser for CSS Files written in PHP

1.8k191.2M63](/packages/sabberworm-php-css-parser)[michelf/php-markdown

PHP Markdown

3.5k52.4M343](/packages/michelf-php-markdown)[jms/metadata

Class/method/property metadata management in PHP

1.8k152.8M88](/packages/jms-metadata)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
