├── .github
├── FUNDING.yml
└── workflows
│ ├── phpunit.yml
│ └── codesee-arch-diagram.yml
├── tests
├── UnitTests
│ └── phpGPX
│ │ ├── Parsers
│ │ ├── EmailParserTest.json
│ │ ├── LinkParserTest.json
│ │ ├── BoundsParserTest.json
│ │ ├── EmailParserTest.xml
│ │ ├── CopyrightParserTest.json
│ │ ├── BoundsParserTest.xml
│ │ ├── LinkParserTest.xml
│ │ ├── PointParserTest.xml
│ │ ├── CopyrightParserTest.xml
│ │ ├── ExtensionParserTest.json
│ │ ├── PersonParserTest.json
│ │ ├── PersonParserTest.xml
│ │ ├── PointParserTest.json
│ │ ├── SegmentParserTest.xml
│ │ ├── BoundsParserTest.php
│ │ ├── EmailParserTest.php
│ │ ├── LinkParserTest.php
│ │ ├── CopyrightParserTest.php
│ │ ├── ExtensionParserTest.xml
│ │ ├── AbstractParserTest.php
│ │ ├── PointParserTest.php
│ │ ├── PersonParserTest.php
│ │ ├── SegmentParserTest.php
│ │ ├── ExtensionParserTest.php
│ │ └── SegmentParserTest.json
│ │ └── Helpers
│ │ ├── GeoHelperTest.php
│ │ ├── DateTimeHelperTest.php
│ │ └── SerializationHelperTest.php
├── fixtures
│ ├── route.gpx
│ ├── gps-track.gpx
│ └── timezero.gpx
└── CreateWaypointTest.php
├── docs
├── _data
│ └── authors.yml
├── phpGPX-Models-Summarizable.md
├── phpGPX-Models-StatsCalculator.md
├── _config.yml
├── phpGPX-Parsers-WaypointParser.md
├── phpGPX-Helpers-GeoHelper.md
├── phpGPX-Models-Extensions.md
├── phpGPX-Parsers-EmailParser.md
├── phpGPX-Parsers-PersonParser.md
├── phpGPX-Parsers-CopyrightParser.md
├── phpGPX-Models-Email.md
├── phpGPX-Parsers-BoundsParser.md
├── phpGPX-Models-Link.md
├── phpGPX-Models-Extensions-AbstractExtension.md
├── phpGPX-Helpers-DateTimeHelper.md
├── phpGPX-Parsers-ExtensionParser.md
├── phpGPX-Models-Person.md
├── phpGPX-Models-Bounds.md
├── phpGPX-Models-Copyright.md
├── phpGPX-Parsers-SegmentParser.md
├── phpGPX-Parsers-LinkParser.md
├── phpGPX-Parsers-Extensions-TrackPointExtensionParser.md
├── phpGPX-Helpers-SerializationHelper.md
├── phpGPX-Parsers-MetadataParser.md
├── phpGPX-Models-Segment.md
├── phpGPX-Parsers-TrackParser.md
├── phpGPX-Parsers-RouteParser.md
├── phpGPX-Models-GpxFile.md
├── phpGPX-phpGPX.md
├── phpGPX-Parsers-PointParser.md
├── phpGPX-Models-Metadata.md
├── phpGPX-Models-Stats.md
├── phpGPX-Models-Collection.md
├── phpGPX-Models-Track.md
├── phpGPX-Models-Route.md
└── phpGPX-Models-Extensions-TrackPointExtension.md
├── .gitignore
├── .codeclimate.yml
├── src
└── phpGPX
│ ├── Models
│ ├── Summarizable.php
│ ├── StatsCalculator.php
│ ├── Extensions
│ │ ├── AbstractExtension.php
│ │ └── TrackPointExtension.php
│ ├── Email.php
│ ├── Extensions.php
│ ├── Link.php
│ ├── Person.php
│ ├── Copyright.php
│ ├── Bounds.php
│ ├── Collection.php
│ ├── Metadata.php
│ ├── Stats.php
│ ├── Segment.php
│ ├── Route.php
│ └── GpxFile.php
│ ├── Parsers
│ ├── WaypointParser.php
│ ├── EmailParser.php
│ ├── PersonParser.php
│ ├── CopyrightParser.php
│ ├── BoundsParser.php
│ ├── LinkParser.php
│ ├── SegmentParser.php
│ ├── ExtensionParser.php
│ ├── Extensions
│ │ └── TrackPointExtensionParser.php
│ ├── TrackParser.php
│ ├── RouteParser.php
│ └── MetadataParser.php
│ ├── Helpers
│ ├── BoundsCalculator.php
│ ├── DateTimeHelper.php
│ ├── GeoHelper.php
│ ├── SerializationHelper.php
│ ├── DistanceCalculator.php
│ └── ElevationGainLossCalculator.php
│ └── phpGPX.php
├── .php-cs-fixer.php
├── example
├── Example.php
├── waypoints_load.php
├── waypoint_test.gpx
├── output_waypoint_test.gpx
├── waypoints_create.php
└── CreateFileFromScratch.php
├── phpunit.xml
├── ISSUE_TEMPLATE.md
├── .travis.yml
├── composer.json
├── LICENSE
├── CHANGELOG.md
└── CODE_OF_CONDUCT.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: sibyx
2 | custom: ['https://www.buymeacoffee.com/Sibyx']
3 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/EmailParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "jakub.dubec",
3 | "domain": "gmail.com"
4 | }
--------------------------------------------------------------------------------
/docs/_data/authors.yml:
--------------------------------------------------------------------------------
1 | sibyx:
2 | picture: https://www.gravatar.com/avatar/c08cc3a6b17177a4bd7045566b0d772a?s=500
3 | twitter: jakubdubec
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/LinkParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "href": "https://jakubdubec.me",
3 | "text": "Portfolio",
4 | "type": "text/html"
5 | }
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/BoundsParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "maxlat": 49.090543,
3 | "maxlon": 18.886939,
4 | "minlat": 49.072489,
5 | "minlon": 18.814543
6 | }
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/EmailParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.phar
2 | composer.lock
3 | /vendor/
4 | /.idea/
5 | /phpdocs/
6 | /bin/
7 | .DS_Store?
8 | *.DS_Store
9 | /.php_cs.cache
10 | /.phpunit.result.cache
11 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/CopyrightParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Jakub Dubec",
3 | "license": "https://github.com/Sibyx/phpGPX/blob/master/LICENSE",
4 | "year": "2017"
5 | }
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/BoundsParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/LinkParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Portfolio
5 | text/html
6 |
7 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/PointParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2419
5 |
6 |
7 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/CopyrightParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2017
5 | https://github.com/Sibyx/phpGPX/blob/master/LICENSE
6 |
7 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/ExtensionParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "trackpoint": {
3 | "aTemp": 14,
4 | "wTemp": null,
5 | "depth": null,
6 | "hr": 152,
7 | "cad": null,
8 | "speed": null,
9 | "course": null,
10 | "bearing": null
11 | },
12 | "unsupported": []
13 | }
14 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/PersonParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Jakub Dubec",
3 | "email": {
4 | "id": "jakub.dubec",
5 | "domain": "gmail.com"
6 | },
7 | "links": [
8 | {
9 | "href": "https://jakubdubec.me",
10 | "text": "Portfolio",
11 | "type": "text/html"
12 | }
13 | ]
14 | }
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | engines:
2 | duplication:
3 | enabled: true
4 | config:
5 | languages:
6 | - php
7 | fixme:
8 | enabled: true
9 | phpmd:
10 | enabled: true
11 | ratings:
12 | paths:
13 | - "**.php"
14 | exclude_paths:
15 | - docs/*
16 | - example/*
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/PersonParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Jakub Dubec
5 |
6 |
7 | Portfolio
8 | text/html
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Summarizable.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | /**
10 | * Interface Summarizable
11 | * @package phpGPX\Models
12 | */
13 | interface Summarizable
14 | {
15 |
16 | /**
17 | * Serialize object to array
18 | * @return array
19 | */
20 | public function toArray();
21 | }
22 |
--------------------------------------------------------------------------------
/.php-cs-fixer.php:
--------------------------------------------------------------------------------
1 |
2 | in(__DIR__)
6 | ->ignoreDotFiles(true)
7 | ->ignoreVCS(true)
8 | ->exclude(['docs', 'vendor'])
9 | ->files()
10 | ->name('*.php')
11 | ;
12 |
13 | return PhpCsFixer\Config::create()
14 | ->setUsingCache(true)
15 | ->setFinder($finder)
16 | ->setRules([
17 | '@PSR2' => true,
18 | ])
19 | ->setIndent("\t")
20 | ;
21 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Summarizable.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Summarizable
2 | ===============
3 |
4 | Interface Summarizable
5 |
6 |
7 |
8 |
9 | * Interface name: Summarizable
10 | * Namespace: phpGPX\Models
11 | * This is an **interface**
12 |
13 |
14 |
15 |
16 |
17 |
18 | Methods
19 | -------
20 |
21 |
22 | ### toArray
23 |
24 | array phpGPX\Models\Summarizable::toArray()
25 |
26 | Serialize object to array
27 |
28 |
29 |
30 | * Visibility: **public**
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-StatsCalculator.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\StatsCalculator
2 | ===============
3 |
4 |
5 |
6 |
7 |
8 |
9 | * Interface name: StatsCalculator
10 | * Namespace: phpGPX\Models
11 | * This is an **interface**
12 |
13 |
14 |
15 |
16 |
17 |
18 | Methods
19 | -------
20 |
21 |
22 | ### recalculateStats
23 |
24 | void phpGPX\Models\StatsCalculator::recalculateStats()
25 |
26 | Recalculate stats objects.
27 |
28 |
29 |
30 | * Visibility: **public**
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/Example.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | use phpGPX\phpGPX;
8 |
9 | require_once '../vendor/autoload.php';
10 |
11 | $gpx = new phpGPX();
12 | $file = $gpx->load('endomondo.gpx');
13 |
14 | phpGPX::$PRETTY_PRINT = true;
15 | //$file->save('output_Evening_Ride.gpx', phpGPX::XML_FORMAT);
16 |
17 | foreach ($file->tracks as $track) {
18 | var_dump($track->stats->toArray());
19 | }
20 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/StatsCalculator.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | interface StatsCalculator
10 | {
11 |
12 | /**
13 | * Recalculate stats objects.
14 | * @return void
15 | */
16 | public function recalculateStats();
17 |
18 | /**
19 | * Return all points in collection.
20 | * @return Point[]
21 | */
22 | public function getPoints();
23 | }
24 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
2 | author: sibyx
3 | title: phpGPX library
4 | description: Simple library for reading and creating GPX files written in PHP.
5 | gems:
6 | - jekyll-seo-tag
7 | - jekyll-analytics
8 | - jekyll-sitemap
9 | social:
10 | name: Jakub Dubec
11 | links:
12 | - https://www.facebook.com/dubecj
13 | - https://github.com/Sibyx
14 | - https://keybase.io/jakubdubec
15 |
16 | jekyll_analytics:
17 | GoogleAnalytics:
18 | id: UA-99333937-1
19 | anonymizeIp: false
--------------------------------------------------------------------------------
/.github/workflows/phpunit.yml:
--------------------------------------------------------------------------------
1 | name: PHPUnit
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | max-parallel: 4
10 | matrix:
11 | php-version: ['7.3', '8.0', '8.1']
12 |
13 | steps:
14 | - uses: actions/checkout@v3
15 | - uses: php-actions/composer@v6
16 | name: Install dependencies
17 | with:
18 | php_version: ${{ matrix.php-version }}
19 | version: 2
20 | - name: Running PHPUnit
21 | run: php vendor/bin/phpunit --configuration phpunit.xml
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/PointParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "ageofdgpsdata": null,
3 | "cmt": null,
4 | "desc": null,
5 | "dgpsid": null,
6 | "difference": null,
7 | "distance": null,
8 | "ele": 2419,
9 | "extensions": null,
10 | "fix": null,
11 | "geoidheight": null,
12 | "hdop": null,
13 | "lat": 46.571948,
14 | "link": [],
15 | "lon": 8.414757,
16 | "magvar": null,
17 | "name": null,
18 | "pdop": null,
19 | "sat": null,
20 | "src": null,
21 | "sym": null,
22 | "time": "2017-08-13T07:10:41+00:00",
23 | "type": null,
24 | "vdop": null
25 | }
--------------------------------------------------------------------------------
/.github/workflows/codesee-arch-diagram.yml:
--------------------------------------------------------------------------------
1 | # This workflow was added by CodeSee. Learn more at https://codesee.io/
2 | # This is v2.0 of this workflow file
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request_target:
8 | types: [opened, synchronize, reopened]
9 |
10 | name: CodeSee
11 |
12 | permissions: read-all
13 |
14 | jobs:
15 | codesee:
16 | runs-on: ubuntu-latest
17 | continue-on-error: true
18 | name: Analyze the repo with CodeSee
19 | steps:
20 | - uses: Codesee-io/codesee-action@v2
21 | with:
22 | codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
23 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-WaypointParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\WaypointParser
2 | ===============
3 |
4 | Class WaypointParser
5 |
6 |
7 |
8 |
9 | * Class name: WaypointParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Methods
20 | -------
21 |
22 |
23 | ### parse
24 |
25 | array phpGPX\Parsers\WaypointParser::parse(\SimpleXMLElement $nodes)
26 |
27 |
28 |
29 |
30 |
31 | * Visibility: **public**
32 | * This method is **static**.
33 |
34 |
35 | #### Arguments
36 | * $nodes **SimpleXMLElement** - <ul>
37 | <li>a non empty list of wpt elements</li>
38 | </ul>
39 |
40 |
41 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | tests/
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Problem description
2 |
3 | 1. Library version or last commit you have
4 | 2. PHP version you use
5 | 3. Detailed problem description
6 |
7 | If you think that problem is connected with your file content, please attach it to the issue.
8 |
9 | # Code snippet you use
10 |
11 | ```php
12 |
13 | ```
14 |
15 | # Expected behaviour
16 |
17 | # Possible solution
18 |
19 | A possible solution if you have any.
20 |
21 | # Something interesting or funny
22 |
23 | Joke or interesting fact to made readers better day :) For example: Ants get drunk and act silly, causing their friend-ants to throw them in puddles of water.
24 |
25 | # Checklist
26 |
27 | Put `x` into brackets if true.
28 |
29 | [ ] PHP version I use
30 | [ ] Package version I use
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 7.0
5 | - 7.1
6 | - 7.2
7 |
8 | env:
9 | global:
10 | - CHECK_PHP_SYNTAX="no"
11 |
12 | matrix:
13 | include:
14 | php: 7.2
15 | env: CHECK_PHP_SYNTAX="yes"
16 |
17 | before_install:
18 | - phpenv config-rm xdebug.ini || echo "xdebug not available"
19 |
20 | install:
21 | - if [[ "$CHECK_PHP_SYNTAX" == "yes" ]]; then composer require --dev --no-update friendsofphp/php-cs-fixer:2.19; fi;
22 | - composer update --prefer-dist --no-interaction --no-suggest --no-progress --ansi
23 |
24 | script:
25 | - if [[ "$CHECK_PHP_SYNTAX" == "no" ]]; then ./vendor/bin/phpunit; fi;
26 | - if [[ "$CHECK_PHP_SYNTAX" == "yes" ]]; then ./vendor/bin/php-cs-fixer fix --dry-run --diff --no-interaction -v; fi;
27 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sibyx/phpgpx",
3 | "type": "library",
4 | "version": "1.3.0",
5 | "description": "A simple PHP library for GPX import/export",
6 | "minimum-stability": "stable",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Jakub Dubec",
11 | "email": "jakub.dubec@gmail.com",
12 | "homepage": "https://jakubdubec.me"
13 | }
14 | ],
15 | "require": {
16 | "php": ">=7.1",
17 | "lib-libxml": "*",
18 | "ext-simplexml": "*",
19 | "ext-dom": "*"
20 | },
21 | "require-dev": {
22 | "evert/phpdoc-md" : "~0.2.0",
23 | "phpunit/phpunit": "^9",
24 | "friendsofphp/php-cs-fixer": "^2.18"
25 | },
26 | "autoload": {
27 | "psr-4": { "phpGPX\\": "src/phpGPX/" }
28 | },
29 | "autoload-dev": {
30 | "psr-4": { "phpGPX\\Tests\\": "tests/" }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/SegmentParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2419
6 |
7 |
8 |
9 | 2418.8833883882
10 |
11 |
12 |
13 | 2419.8999900064
14 |
15 |
16 |
17 | 2422
18 |
19 |
20 |
21 | 2425
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/WaypointParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | /**
10 | * Class WaypointParser
11 | * @package phpGPX\Parsers
12 | */
13 | abstract class WaypointParser
14 | {
15 |
16 | /**
17 | * @param \SimpleXMLElement $nodes - a non empty list of wpt elements
18 | * @return array
19 | */
20 | public static function parse(\SimpleXMLElement $nodes)
21 | {
22 | $points = [];
23 |
24 | // foreach ($nodes->wpt as $item) this was incorrect, the ->wpt was already done in the caller
25 | foreach ($nodes as $item) {
26 | $point = PointParser::parse($item);
27 |
28 | if ($point) {
29 | $points[] = $point;
30 | }
31 | }
32 |
33 | return $points;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/example/waypoints_load.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | use phpGPX\phpGPX;
8 |
9 | require_once '../vendor/autoload.php';
10 |
11 | $origFile = dirname(__FILE__).'/waypoint_test.gpx';
12 | $outFile = dirname(__FILE__).'/output_waypoint_test.gpx';
13 | // $outFile2 = dirname(__FILE__).'/output_waypoint_test2.gpx';
14 |
15 | $gpx = new phpGPX();
16 | $file = $gpx->load($origFile);
17 |
18 | phpGPX::$PRETTY_PRINT = true;
19 | $file->save($outFile, phpGPX::XML_FORMAT);
20 |
21 | $retcode = 0;
22 | system("diff $origFile $outFile", $retcode);
23 | // system("diff $origFile $outFile2", $retcode);
24 |
25 | if ($retcode != 0) {
26 | throw new \Exception("wapoint file incorrect");
27 | } else {
28 | print "wapoint test successfull\n";
29 | }
30 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Extensions/AbstractExtension.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models\Extensions;
8 |
9 | use phpGPX\Models\Summarizable;
10 |
11 | abstract class AbstractExtension implements Summarizable
12 | {
13 |
14 | /**
15 | * XML namespace of extension
16 | * @var string
17 | */
18 | public $namespace;
19 |
20 | /**
21 | * Node name extension.
22 | * @var string
23 | */
24 | public $extensionName;
25 |
26 | /**
27 | * AbstractExtension constructor.
28 | * @param string $namespace
29 | * @param string $extensionName
30 | */
31 | public function __construct($namespace, $extensionName)
32 | {
33 | $this->namespace = $namespace;
34 | $this->extensionName = $extensionName;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/phpGPX-Helpers-GeoHelper.md:
--------------------------------------------------------------------------------
1 | phpGPX\Helpers\GeoHelper
2 | ===============
3 |
4 | Class GeoHelper
5 | Geolocation methods.
6 |
7 |
8 |
9 |
10 | * Class name: GeoHelper
11 | * Namespace: phpGPX\Helpers
12 | * This is an **abstract** class
13 |
14 |
15 |
16 | Constants
17 | ----------
18 |
19 |
20 | ### EARTH_RADIUS
21 |
22 | const EARTH_RADIUS = 6371000
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Methods
31 | -------
32 |
33 |
34 | ### getDistance
35 |
36 | float phpGPX\Helpers\GeoHelper::getDistance(\phpGPX\Models\Point $point1, \phpGPX\Models\Point $point2)
37 |
38 | Returns distance in meters between two Points according to GPX coordinates.
39 |
40 |
41 |
42 | * Visibility: **public**
43 | * This method is **static**.
44 |
45 |
46 | #### Arguments
47 | * $point1 **[phpGPX\Models\Point](phpGPX-Models-Point.md)**
48 | * $point2 **[phpGPX\Models\Point](phpGPX-Models-Point.md)**
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Email.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | /**
10 | * Class Email
11 | * An email address. Broken into two parts (id and domain) to help prevent email harvesting.
12 | * @package phpGPX\Models
13 | */
14 | class Email implements Summarizable
15 | {
16 |
17 | /**
18 | * Id half of email address (jakub.dubec)
19 | * @var string
20 | */
21 | public $id;
22 |
23 | /** Domain half of email address (gmail.com)
24 | * @var string
25 | */
26 | public $domain;
27 |
28 | /**
29 | * Email constructor.
30 | */
31 | public function __construct()
32 | {
33 | $this->id = null;
34 | $this->domain = null;
35 | }
36 |
37 |
38 | /**
39 | * Serialize object to array
40 | * @return array
41 | */
42 | public function toArray()
43 | {
44 | return [
45 | 'id' => (string) $this->id,
46 | 'domain' => (string) $this->domain
47 | ];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Extensions.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\SerializationHelper;
10 | use phpGPX\Models\Extensions\TrackPointExtension;
11 |
12 | /**
13 | * Class Extensions
14 | * TODO: http://www.garmin.com/xmlschemas/GpxExtensions/v3
15 | * @package phpGPX\Models
16 | */
17 | class Extensions implements Summarizable
18 | {
19 | /**
20 | * GPX Garmin TrackPointExtension v1
21 | * @see 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1'
22 | * @var TrackPointExtension
23 | */
24 | public $trackPointExtension;
25 |
26 | /**
27 | * @var []
28 | */
29 | public $unsupported = [];
30 |
31 | /**
32 | * Serialize object to array
33 | * @return array
34 | */
35 | public function toArray()
36 | {
37 | return [
38 | 'trackpoint' => SerializationHelper::serialize($this->trackPointExtension),
39 | 'unsupported' => $this->unsupported,
40 | ];
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Extensions.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Extensions
2 | ===============
3 |
4 | Class Extensions
5 | TODO: http://www.garmin.com/xmlschemas/GpxExtensions/v3
6 |
7 |
8 |
9 |
10 | * Class name: Extensions
11 | * Namespace: phpGPX\Models
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $trackPointExtension
22 |
23 | public \phpGPX\Models\Extensions\TrackPointExtension $trackPointExtension
24 |
25 | GPX Garmin TrackPointExtension v1
26 |
27 |
28 |
29 | * Visibility: **public**
30 |
31 |
32 | Methods
33 | -------
34 |
35 |
36 | ### __construct
37 |
38 | mixed phpGPX\Models\Extensions::__construct()
39 |
40 | Extensions constructor.
41 |
42 |
43 |
44 | * Visibility: **public**
45 |
46 |
47 |
48 |
49 | ### toArray
50 |
51 | array phpGPX\Models\Summarizable::toArray()
52 |
53 | Serialize object to array
54 |
55 |
56 |
57 | * Visibility: **public**
58 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/example/waypoint_test.gpx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My pretty awesome GPX file, created using phpGPX library!
5 |
6 | phpGPX Docs
7 |
8 |
9 |
10 |
11 | 0
12 |
13 |
14 |
15 | 10
16 |
17 |
18 |
19 | 42.42
20 |
21 |
22 |
23 | 12
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/output_waypoint_test.gpx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My pretty awesome GPX file, created using phpGPX library!
5 |
6 | phpGPX Docs
7 |
8 |
9 |
10 |
11 | 0
12 |
13 |
14 |
15 | 10
16 |
17 |
18 |
19 | 42.42
20 |
21 |
22 |
23 | 12
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-EmailParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\EmailParser
2 | ===============
3 |
4 | Class EmailParser
5 |
6 |
7 |
8 |
9 | * Class name: EmailParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | private mixed $tagName = 'email'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **private**
30 | * This property is **static**.
31 |
32 |
33 | Methods
34 | -------
35 |
36 |
37 | ### parse
38 |
39 | \phpGPX\Models\Email phpGPX\Parsers\EmailParser::parse(\SimpleXMLElement $node)
40 |
41 |
42 |
43 |
44 |
45 | * Visibility: **public**
46 | * This method is **static**.
47 |
48 |
49 | #### Arguments
50 | * $node **SimpleXMLElement**
51 |
52 |
53 |
54 | ### toXML
55 |
56 | \DOMElement phpGPX\Parsers\EmailParser::toXML(\phpGPX\Models\Email $email, \DOMDocument $document)
57 |
58 |
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This method is **static**.
64 |
65 |
66 | #### Arguments
67 | * $email **[phpGPX\Models\Email](phpGPX-Models-Email.md)**
68 | * $document **DOMDocument**
69 |
70 |
71 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017-2022 Jakub Dubec
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-PersonParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\PersonParser
2 | ===============
3 |
4 | Class PersonParser
5 |
6 |
7 |
8 |
9 | * Class name: PersonParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | public mixed $tagName = 'author'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **public**
30 | * This property is **static**.
31 |
32 |
33 | Methods
34 | -------
35 |
36 |
37 | ### parse
38 |
39 | \phpGPX\Models\Person phpGPX\Parsers\PersonParser::parse(\SimpleXMLElement $node)
40 |
41 |
42 |
43 |
44 |
45 | * Visibility: **public**
46 | * This method is **static**.
47 |
48 |
49 | #### Arguments
50 | * $node **SimpleXMLElement**
51 |
52 |
53 |
54 | ### toXML
55 |
56 | mixed phpGPX\Parsers\PersonParser::toXML(\phpGPX\Models\Person $person, \DOMDocument $document)
57 |
58 |
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This method is **static**.
64 |
65 |
66 | #### Arguments
67 | * $person **[phpGPX\Models\Person](phpGPX-Models-Person.md)**
68 | * $document **DOMDocument**
69 |
70 |
71 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-CopyrightParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\CopyrightParser
2 | ===============
3 |
4 | Class CopyrightParser
5 |
6 |
7 |
8 |
9 | * Class name: CopyrightParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | public mixed $tagName = 'copyright'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **public**
30 | * This property is **static**.
31 |
32 |
33 | Methods
34 | -------
35 |
36 |
37 | ### parse
38 |
39 | \phpGPX\Models\Copyright|null phpGPX\Parsers\CopyrightParser::parse(\SimpleXMLElement $node)
40 |
41 |
42 |
43 |
44 |
45 | * Visibility: **public**
46 | * This method is **static**.
47 |
48 |
49 | #### Arguments
50 | * $node **SimpleXMLElement**
51 |
52 |
53 |
54 | ### toXML
55 |
56 | \DOMElement phpGPX\Parsers\CopyrightParser::toXML(\phpGPX\Models\Copyright $copyright, \DOMDocument $document)
57 |
58 |
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This method is **static**.
64 |
65 |
66 | #### Arguments
67 | * $copyright **[phpGPX\Models\Copyright](phpGPX-Models-Copyright.md)**
68 | * $document **DOMDocument**
69 |
70 |
71 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Email.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Email
2 | ===============
3 |
4 | Class Email
5 | An email address. Broken into two parts (id and domain) to help prevent email harvesting.
6 |
7 |
8 |
9 |
10 | * Class name: Email
11 | * Namespace: phpGPX\Models
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $id
22 |
23 | public string $id
24 |
25 | Id half of email address (jakub.dubec)
26 |
27 |
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $domain
33 |
34 | public string $domain
35 |
36 | Domain half of email address (gmail.com)
37 |
38 |
39 |
40 | * Visibility: **public**
41 |
42 |
43 | Methods
44 | -------
45 |
46 |
47 | ### __construct
48 |
49 | mixed phpGPX\Models\Email::__construct()
50 |
51 | Email constructor.
52 |
53 |
54 |
55 | * Visibility: **public**
56 |
57 |
58 |
59 |
60 | ### toArray
61 |
62 | array phpGPX\Models\Summarizable::toArray()
63 |
64 | Serialize object to array
65 |
66 |
67 |
68 | * Visibility: **public**
69 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-BoundsParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\BoundsParser
2 | ===============
3 |
4 | Class BoundsParser
5 |
6 |
7 |
8 |
9 | * Class name: BoundsParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | private mixed $tagName = 'bounds'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **private**
30 | * This property is **static**.
31 |
32 |
33 | Methods
34 | -------
35 |
36 |
37 | ### parse
38 |
39 | \phpGPX\Models\Bounds|null phpGPX\Parsers\BoundsParser::parse(\SimpleXMLElement $node)
40 |
41 | Parse data from XML.
42 |
43 |
44 |
45 | * Visibility: **public**
46 | * This method is **static**.
47 |
48 |
49 | #### Arguments
50 | * $node **SimpleXMLElement**
51 |
52 |
53 |
54 | ### toXML
55 |
56 | \DOMElement phpGPX\Parsers\BoundsParser::toXML(\phpGPX\Models\Bounds $bounds, \DOMDocument $document)
57 |
58 | Create XML representation.
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This method is **static**.
64 |
65 |
66 | #### Arguments
67 | * $bounds **[phpGPX\Models\Bounds](phpGPX-Models-Bounds.md)**
68 | * $document **DOMDocument**
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Link.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | /**
10 | * Class Link according to GPX 1.1 specification.
11 | * A link to an external resource (Web page, digital photo, video clip, etc) with additional information.
12 | * @see http://www.topografix.com/GPX/1/1/#type_linkType
13 | * @package phpGPX\Models
14 | */
15 | class Link implements Summarizable
16 | {
17 |
18 | /**
19 | * URL of hyperlink.
20 | * @var string
21 | */
22 | public $href;
23 |
24 | /**
25 | * Text of hyperlink.
26 | * @var string|null
27 | */
28 | public $text;
29 |
30 | /**
31 | * Mime type of content (image/jpeg)
32 | * @var string|null
33 | */
34 | public $type;
35 |
36 | /**
37 | * Link constructor.
38 | */
39 | public function __construct()
40 | {
41 | $this->href = null;
42 | $this->text = null;
43 | $this->type = null;
44 | }
45 |
46 |
47 | /**
48 | * Serialize object to array
49 | * @return array
50 | */
51 | public function toArray()
52 | {
53 | return [
54 | 'href' => (string) $this->href,
55 | 'text' => $this->text,
56 | 'type' => $this->type
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/EmailParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Email;
10 |
11 | /**
12 | * Class EmailParser
13 | * @package phpGPX\Parsers
14 | */
15 | abstract class EmailParser
16 | {
17 | private static $tagName = 'email';
18 |
19 | /**
20 | * @param \SimpleXMLElement $node
21 | * @return Email
22 | */
23 | public static function parse(\SimpleXMLElement $node)
24 | {
25 | $email = new Email();
26 |
27 | $email->id = isset($node['id']) ? (string) $node['id'] : null;
28 | $email->domain = isset($node['domain']) ? (string) $node['domain'] : null;
29 |
30 | return $email;
31 | }
32 |
33 |
34 | /**
35 | * @param Email $email
36 | * @param \DOMDocument $document
37 | * @return \DOMElement
38 | */
39 | public static function toXML(Email $email, \DOMDocument &$document)
40 | {
41 | $node = $document->createElement(self::$tagName);
42 |
43 | if (!empty($email->id)) {
44 | $node->setAttribute('id', $email->id);
45 | }
46 |
47 | if (!empty($email->domain)) {
48 | $node->setAttribute('domain', $email->domain);
49 | }
50 |
51 | return $node;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Link.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Link
2 | ===============
3 |
4 | Class Link according to GPX 1.1 specification.
5 |
6 | A link to an external resource (Web page, digital photo, video clip, etc) with additional information.
7 |
8 |
9 | * Class name: Link
10 | * Namespace: phpGPX\Models
11 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
12 |
13 |
14 |
15 |
16 | Properties
17 | ----------
18 |
19 |
20 | ### $href
21 |
22 | public string $href
23 |
24 | URL of hyperlink.
25 |
26 |
27 |
28 | * Visibility: **public**
29 |
30 |
31 | ### $text
32 |
33 | public string $text
34 |
35 | Text of hyperlink.
36 |
37 |
38 |
39 | * Visibility: **public**
40 |
41 |
42 | ### $type
43 |
44 | public string $type
45 |
46 | Mime type of content (image/jpeg)
47 |
48 |
49 |
50 | * Visibility: **public**
51 |
52 |
53 | Methods
54 | -------
55 |
56 |
57 | ### __construct
58 |
59 | mixed phpGPX\Models\Link::__construct()
60 |
61 | Link constructor.
62 |
63 |
64 |
65 | * Visibility: **public**
66 |
67 |
68 |
69 |
70 | ### toArray
71 |
72 | array phpGPX\Models\Summarizable::toArray()
73 |
74 | Serialize object to array
75 |
76 |
77 |
78 | * Visibility: **public**
79 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Extensions-AbstractExtension.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Extensions\AbstractExtension
2 | ===============
3 |
4 |
5 |
6 |
7 |
8 |
9 | * Class name: AbstractExtension
10 | * Namespace: phpGPX\Models\Extensions
11 | * This is an **abstract** class
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $namespace
22 |
23 | public string $namespace
24 |
25 | XML namespace of extension
26 |
27 |
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $extensionName
33 |
34 | public string $extensionName
35 |
36 | Node name extension.
37 |
38 |
39 |
40 | * Visibility: **public**
41 |
42 |
43 | Methods
44 | -------
45 |
46 |
47 | ### __construct
48 |
49 | mixed phpGPX\Models\Extensions\AbstractExtension::__construct(string $namespace, string $extensionName)
50 |
51 | AbstractExtension constructor.
52 |
53 |
54 |
55 | * Visibility: **public**
56 |
57 |
58 | #### Arguments
59 | * $namespace **string**
60 | * $extensionName **string**
61 |
62 |
63 |
64 | ### toArray
65 |
66 | array phpGPX\Models\Summarizable::toArray()
67 |
68 | Serialize object to array
69 |
70 |
71 |
72 | * Visibility: **public**
73 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Person.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\SerializationHelper;
10 |
11 | /**
12 | * Class Person
13 | * A person or organisation
14 | * @package phpGPX\Models
15 | */
16 | class Person implements Summarizable
17 | {
18 |
19 | /**
20 | * Name of person or organization.
21 | * An original GPX 1.1 attribute.
22 | * @var string
23 | */
24 | public $name;
25 |
26 | /**
27 | * E-mail address.
28 | * An original GPX 1.1 attribute.
29 | * @var Email|null
30 | */
31 | public $email;
32 |
33 | /**
34 | * Link to Web site or other external information about person.
35 | * An original GPX 1.1 attribute.
36 | * @var Link[]
37 | */
38 | public $links;
39 |
40 | /**
41 | * Person constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->name = null;
46 | $this->email = null;
47 | $this->links = null;
48 | }
49 |
50 |
51 | /**
52 | * Serialize object to array
53 | * @return array
54 | */
55 | public function toArray()
56 | {
57 | return [
58 | 'name' => (string) $this->name,
59 | 'email' => SerializationHelper::serialize($this->email),
60 | 'links' => SerializationHelper::serialize($this->links)
61 | ];
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/docs/phpGPX-Helpers-DateTimeHelper.md:
--------------------------------------------------------------------------------
1 | phpGPX\Helpers\DateTimeHelper
2 | ===============
3 |
4 | Class DateTimeHelper
5 |
6 |
7 |
8 |
9 | * Class name: DateTimeHelper
10 | * Namespace: phpGPX\Helpers
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Methods
19 | -------
20 |
21 |
22 | ### comparePointsByTimestamp
23 |
24 | boolean|integer phpGPX\Helpers\DateTimeHelper::comparePointsByTimestamp(\phpGPX\Models\Point $point1, \phpGPX\Models\Point $point2)
25 |
26 |
27 |
28 |
29 |
30 | * Visibility: **public**
31 | * This method is **static**.
32 |
33 |
34 | #### Arguments
35 | * $point1 **[phpGPX\Models\Point](phpGPX-Models-Point.md)**
36 | * $point2 **[phpGPX\Models\Point](phpGPX-Models-Point.md)**
37 |
38 |
39 |
40 | ### formatDateTime
41 |
42 | null|string phpGPX\Helpers\DateTimeHelper::formatDateTime($datetime, string $format, string $timezone)
43 |
44 |
45 |
46 |
47 |
48 | * Visibility: **public**
49 | * This method is **static**.
50 |
51 |
52 | #### Arguments
53 | * $datetime **mixed**
54 | * $format **string**
55 | * $timezone **string**
56 |
57 |
58 |
59 | ### parseDateTime
60 |
61 | \DateTime phpGPX\Helpers\DateTimeHelper::parseDateTime($value, string $timezone)
62 |
63 |
64 |
65 |
66 |
67 | * Visibility: **public**
68 | * This method is **static**.
69 |
70 |
71 | #### Arguments
72 | * $value **mixed**
73 | * $timezone **string**
74 |
75 |
76 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-ExtensionParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\ExtensionParser
2 | ===============
3 |
4 | Class ExtensionParser
5 |
6 |
7 |
8 |
9 | * Class name: ExtensionParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | public mixed $tagName = 'extensions'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **public**
30 | * This property is **static**.
31 |
32 |
33 | ### $usedNamespaces
34 |
35 | public mixed $usedNamespaces = array()
36 |
37 |
38 |
39 |
40 |
41 | * Visibility: **public**
42 | * This property is **static**.
43 |
44 |
45 | Methods
46 | -------
47 |
48 |
49 | ### parse
50 |
51 | \phpGPX\Models\Extensions phpGPX\Parsers\ExtensionParser::parse(\SimpleXMLElement $nodes)
52 |
53 |
54 |
55 |
56 |
57 | * Visibility: **public**
58 | * This method is **static**.
59 |
60 |
61 | #### Arguments
62 | * $nodes **SimpleXMLElement**
63 |
64 |
65 |
66 | ### toXML
67 |
68 | \DOMElement|null phpGPX\Parsers\ExtensionParser::toXML(\phpGPX\Models\Extensions $extensions, \DOMDocument $document)
69 |
70 |
71 |
72 |
73 |
74 | * Visibility: **public**
75 | * This method is **static**.
76 |
77 |
78 | #### Arguments
79 | * $extensions **[phpGPX\Models\Extensions](phpGPX-Models-Extensions.md)**
80 | * $document **DOMDocument**
81 |
82 |
83 |
--------------------------------------------------------------------------------
/tests/fixtures/route.gpx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test file by Patrick
5 |
6 |
7 | Patrick's Route
8 |
9 | 0.0
10 | Position 1
11 |
12 |
13 | 1.0
14 | Position 2
15 |
16 |
17 | 2.0
18 | Position 3
19 |
20 |
21 | 3.0
22 | Position 4
23 |
24 |
25 |
26 | Sibyx's Route
27 |
28 | 0.0
29 | Position 4
30 |
31 |
32 | 1.0
33 | Position 3
34 |
35 |
36 | 2.0
37 | Position 2
38 |
39 |
40 | 3.0
41 | Position 1
42 |
43 |
44 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Person.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Person
2 | ===============
3 |
4 | Class Person
5 | A person or organisation
6 |
7 |
8 |
9 |
10 | * Class name: Person
11 | * Namespace: phpGPX\Models
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $name
22 |
23 | public string $name
24 |
25 | Name of person or organization.
26 |
27 | An original GPX 1.1 attribute.
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $email
33 |
34 | public \phpGPX\Models\Email $email
35 |
36 | E-mail address.
37 |
38 | An original GPX 1.1 attribute.
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $link
44 |
45 | public \phpGPX\Models\Link $link
46 |
47 | Link to Web site or other external information about person.
48 |
49 | An original GPX 1.1 attribute.
50 |
51 | * Visibility: **public**
52 |
53 |
54 | Methods
55 | -------
56 |
57 |
58 | ### __construct
59 |
60 | mixed phpGPX\Models\Person::__construct()
61 |
62 | Person constructor.
63 |
64 |
65 |
66 | * Visibility: **public**
67 |
68 |
69 |
70 |
71 | ### toArray
72 |
73 | array phpGPX\Models\Summarizable::toArray()
74 |
75 | Serialize object to array
76 |
77 |
78 |
79 | * Visibility: **public**
80 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Bounds.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Bounds
2 | ===============
3 |
4 |
5 |
6 |
7 |
8 |
9 | * Class name: Bounds
10 | * Namespace: phpGPX\Models
11 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
12 |
13 |
14 |
15 |
16 | Properties
17 | ----------
18 |
19 |
20 | ### $minLatitude
21 |
22 | public float $minLatitude
23 |
24 | Minimal latitude in file.
25 |
26 |
27 |
28 | * Visibility: **public**
29 |
30 |
31 | ### $minLongitude
32 |
33 | public float $minLongitude
34 |
35 | Minimal longitude in file.
36 |
37 |
38 |
39 | * Visibility: **public**
40 |
41 |
42 | ### $maxLatitude
43 |
44 | public float $maxLatitude
45 |
46 | Maximal latitude in file.
47 |
48 |
49 |
50 | * Visibility: **public**
51 |
52 |
53 | ### $maxLongitude
54 |
55 | public float $maxLongitude
56 |
57 | Maximal longitude in file.
58 |
59 |
60 |
61 | * Visibility: **public**
62 |
63 |
64 | Methods
65 | -------
66 |
67 |
68 | ### __construct
69 |
70 | mixed phpGPX\Models\Bounds::__construct()
71 |
72 | Bounds constructor.
73 |
74 |
75 |
76 | * Visibility: **public**
77 |
78 |
79 |
80 |
81 | ### toArray
82 |
83 | array phpGPX\Models\Summarizable::toArray()
84 |
85 | Serialize object to array
86 |
87 |
88 |
89 | * Visibility: **public**
90 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Copyright.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\SerializationHelper;
10 |
11 | /**
12 | * Class Copyright
13 | * Information about the copyright holder and any license governing use of this file.
14 | * By linking to an appropriate license, you may place your data into the public domain or grant additional usage rights.
15 | * @package phpGPX\Models
16 | */
17 | class Copyright implements Summarizable
18 | {
19 |
20 | /**
21 | * Copyright holder (TopoSoft, Inc.)
22 | * @var string
23 | */
24 | public $author;
25 |
26 | /**
27 | * Year of copyright.
28 | * @var string
29 | */
30 | public $year;
31 |
32 | /**
33 | * Link to external file containing license text.
34 | * @var string
35 | */
36 | public $license;
37 |
38 | /**
39 | * Copyright constructor.
40 | */
41 | public function __construct()
42 | {
43 | $this->author = null;
44 | $this->year = null;
45 | $this->license = null;
46 | }
47 |
48 |
49 | /**
50 | * Serialize object to array
51 | * @return array
52 | */
53 | public function toArray()
54 | {
55 | return [
56 | 'author' => $this->author,
57 | 'year' => SerializationHelper::stringOrNull($this->year),
58 | 'license' => SerializationHelper::stringOrNull($this->license)
59 | ];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Copyright.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Copyright
2 | ===============
3 |
4 | Class Copyright
5 | Information about the copyright holder and any license governing use of this file.
6 |
7 | By linking to an appropriate license, you may place your data into the public domain or grant additional usage rights.
8 |
9 |
10 | * Class name: Copyright
11 | * Namespace: phpGPX\Models
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $author
22 |
23 | public string $author
24 |
25 | Copyright holder (TopoSoft, Inc.)
26 |
27 |
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $year
33 |
34 | public string $year
35 |
36 | Year of copyright.
37 |
38 |
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $license
44 |
45 | public string $license
46 |
47 | Link to external file containing license text.
48 |
49 |
50 |
51 | * Visibility: **public**
52 |
53 |
54 | Methods
55 | -------
56 |
57 |
58 | ### __construct
59 |
60 | mixed phpGPX\Models\Copyright::__construct()
61 |
62 | Copyright constructor.
63 |
64 |
65 |
66 | * Visibility: **public**
67 |
68 |
69 |
70 |
71 | ### toArray
72 |
73 | array phpGPX\Models\Summarizable::toArray()
74 |
75 | Serialize object to array
76 |
77 |
78 |
79 | * Visibility: **public**
80 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/tests/fixtures/gps-track.gpx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | GPS-Track
5 |
6 |
7 | 2419
8 |
9 |
10 |
11 | 2418.8833883882
12 |
13 |
14 |
15 | 2419.8999900064
16 |
17 |
18 |
19 | 2422
20 |
21 |
22 |
23 | 2425
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Bounds.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | class Bounds implements Summarizable
10 | {
11 |
12 | /**
13 | * Minimal latitude in file.
14 | * @var float
15 | */
16 | public $minLatitude;
17 |
18 | /**
19 | * Minimal longitude in file.
20 | * @var float
21 | */
22 | public $minLongitude;
23 |
24 | /**
25 | * Maximal latitude in file.
26 | * @var float
27 | */
28 | public $maxLatitude;
29 |
30 | /**
31 | * Maximal longitude in file.
32 | * @var float
33 | */
34 | public $maxLongitude;
35 |
36 | /**
37 | * @param ?float $minLatitude
38 | * @param ?float $minLongitude
39 | * @param ?float $maxLatitude
40 | * @param ?float $maxLongitude
41 | */
42 | public function __construct(?float $minLatitude, ?float $minLongitude, ?float $maxLatitude, ?float $maxLongitude)
43 | {
44 | $this->minLatitude = $minLatitude;
45 | $this->minLongitude = $minLongitude;
46 | $this->maxLatitude = $maxLatitude;
47 | $this->maxLongitude = $maxLongitude;
48 | }
49 |
50 |
51 | /**
52 | * Serialize object to array
53 | * @return array
54 | */
55 | public function toArray(): array
56 | {
57 | return [
58 | 'minlat' => $this->minLatitude,
59 | 'minlon' => $this->minLongitude,
60 | 'maxlat' => $this->maxLatitude,
61 | 'maxlon' => $this->maxLongitude
62 | ];
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-SegmentParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\SegmentParser
2 | ===============
3 |
4 | Class SegmentParser
5 |
6 |
7 |
8 |
9 | * Class name: SegmentParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | public mixed $tagName = 'trkseg'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **public**
30 | * This property is **static**.
31 |
32 |
33 | Methods
34 | -------
35 |
36 |
37 | ### parse
38 |
39 | array phpGPX\Parsers\SegmentParser::parse($nodes)
40 |
41 |
42 |
43 |
44 |
45 | * Visibility: **public**
46 | * This method is **static**.
47 |
48 |
49 | #### Arguments
50 | * $nodes **mixed** - <p>\SimpleXMLElement[]</p>
51 |
52 |
53 |
54 | ### toXML
55 |
56 | \DOMElement phpGPX\Parsers\SegmentParser::toXML(\phpGPX\Models\Segment $segment, \DOMDocument $document)
57 |
58 |
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This method is **static**.
64 |
65 |
66 | #### Arguments
67 | * $segment **[phpGPX\Models\Segment](phpGPX-Models-Segment.md)**
68 | * $document **DOMDocument**
69 |
70 |
71 |
72 | ### toXMLArray
73 |
74 | array phpGPX\Parsers\SegmentParser::toXMLArray(array $segments, \DOMDocument $document)
75 |
76 |
77 |
78 |
79 |
80 | * Visibility: **public**
81 | * This method is **static**.
82 |
83 |
84 | #### Arguments
85 | * $segments **array**
86 | * $document **DOMDocument**
87 |
88 |
89 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-LinkParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\LinkParser
2 | ===============
3 |
4 |
5 |
6 |
7 |
8 |
9 | * Class name: LinkParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | private mixed $tagName = 'link'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **private**
30 | * This property is **static**.
31 |
32 |
33 | Methods
34 | -------
35 |
36 |
37 | ### parse
38 |
39 | array phpGPX\Parsers\LinkParser::parse(array $nodes)
40 |
41 |
42 |
43 |
44 |
45 | * Visibility: **public**
46 | * This method is **static**.
47 |
48 |
49 | #### Arguments
50 | * $nodes **array<mixed,\SimpleXMLElement>**
51 |
52 |
53 |
54 | ### toXMLArray
55 |
56 | array phpGPX\Parsers\LinkParser::toXMLArray(array $links, \DOMDocument $document)
57 |
58 |
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This method is **static**.
64 |
65 |
66 | #### Arguments
67 | * $links **array<mixed,\phpGPX\Models\Link>**
68 | * $document **DOMDocument**
69 |
70 |
71 |
72 | ### toXML
73 |
74 | \DOMElement phpGPX\Parsers\LinkParser::toXML(\phpGPX\Models\Link $link, \DOMDocument $document)
75 |
76 |
77 |
78 |
79 |
80 | * Visibility: **public**
81 | * This method is **static**.
82 |
83 |
84 | #### Arguments
85 | * $link **[phpGPX\Models\Link](phpGPX-Models-Link.md)**
86 | * $document **DOMDocument**
87 |
88 |
89 |
--------------------------------------------------------------------------------
/src/phpGPX/Helpers/BoundsCalculator.php:
--------------------------------------------------------------------------------
1 | longitude;
38 | $lat = $curPoint->latitude;
39 |
40 | // Update northWest and southEast points if needed
41 | if ($lat > $north) {$north = $lat;}
42 | if ($lng > $east) {$east = $lng;}
43 | if ($lat < $south) {$south = $lat;}
44 | if ($lng < $west) {$west = $lng;}
45 | }
46 |
47 | return [
48 | ["lat" => $north, "lng" => $west],
49 | ["lat" => $south, "lng" => $east]
50 | ];
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/phpGPX/Helpers/DateTimeHelper.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Helpers;
8 |
9 | use phpGPX\Models\Point;
10 |
11 | /**
12 | * Class DateTimeHelper
13 | * @package phpGPX\Helpers
14 | */
15 | class DateTimeHelper
16 | {
17 |
18 | /**
19 | * @param Point $point1
20 | * @param Point $point2
21 | * @return bool|int
22 | */
23 | public static function comparePointsByTimestamp(Point $point1, Point $point2)
24 | {
25 | if ($point1->time == $point2->time) {
26 | return 0;
27 | }
28 | return $point1->time > $point2->time;
29 | }
30 |
31 | /**
32 | * @param $datetime
33 | * @param string $format
34 | * @param string $timezone
35 | * @return null|string
36 | */
37 | public static function formatDateTime($datetime, $format = 'c', $timezone = 'UTC')
38 | {
39 | $formatted = null;
40 |
41 | if ($datetime instanceof \DateTime) {
42 | $datetime->setTimezone(new \DateTimeZone($timezone));
43 | $formatted = $datetime->format($format);
44 | }
45 |
46 | return $formatted;
47 | }
48 |
49 | /**
50 | * @param $value
51 | * @param string $timezone
52 | * @return \DateTime
53 | */
54 | public static function parseDateTime($value, $timezone = 'Europe/London')
55 | {
56 | $timezone = new \DateTimeZone($timezone);
57 | $datetime = new \DateTime($value, $timezone);
58 | $datetime->setTimezone(new \DateTimeZone(date_default_timezone_get()));
59 |
60 | return $datetime;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/BoundsParserTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Parsers;
7 |
8 | use phpGPX\Models\Bounds;
9 | use phpGPX\Parsers\BoundsParser;
10 |
11 | class BoundsParserTest extends AbstractParserTest
12 | {
13 | protected $testModelClass = Bounds::class;
14 | protected $testParserClass = BoundsParser::class;
15 |
16 | /**
17 | * @var Bounds
18 | */
19 | protected $testModelInstance;
20 |
21 | public static function createTestInstance()
22 | {
23 | return new Bounds(49.072489, 18.814543, 49.090543, 18.886939);
24 | }
25 |
26 | protected function setUp(): void
27 | {
28 | parent::setUp();
29 |
30 | $this->testModelInstance = self::createTestInstance();
31 | }
32 |
33 | public function testParse()
34 | {
35 | $bounds = BoundsParser::parse($this->testXmlFile->bounds);
36 |
37 | $this->assertNotEmpty($bounds);
38 |
39 | $this->assertEquals($this->testModelInstance->maxLatitude, $bounds->maxLatitude);
40 | $this->assertEquals($this->testModelInstance->maxLongitude, $bounds->maxLongitude);
41 | $this->assertEquals($this->testModelInstance->minLatitude, $bounds->minLatitude);
42 | $this->assertEquals($this->testModelInstance->minLongitude, $bounds->minLongitude);
43 |
44 | $this->assertEquals($this->testModelInstance->toArray(), $bounds->toArray());
45 | }
46 |
47 | protected function convertToXML(\DOMDocument $document)
48 | {
49 | return BoundsParser::toXML($this->testModelInstance, $document);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/PersonParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Person;
10 |
11 | /**
12 | * Class PersonParser
13 | * @package phpGPX\Parsers
14 | */
15 | abstract class PersonParser
16 | {
17 | public static $tagName = 'author';
18 |
19 | /**
20 | * @param \SimpleXMLElement $node
21 | * @return Person
22 | */
23 | public static function parse(\SimpleXMLElement $node)
24 | {
25 | $person = new Person();
26 |
27 | $person->name = isset($node->name) ? ((string) $node->name) : null;
28 | $person->email = isset($node->email) ? EmailParser::parse($node->email) : null;
29 | $person->links = isset($node->link) ? LinkParser::parse($node->link) : null;
30 |
31 | return $person;
32 | }
33 |
34 | public static function toXML(Person $person, \DOMDocument &$document)
35 | {
36 | $node = $document->createElement(self::$tagName);
37 |
38 | if (!empty($person->name)) {
39 | $child = $document->createElement('name', $person->name);
40 | $node->appendChild($child);
41 | }
42 |
43 | if (!empty($person->email)) {
44 | $child = EmailParser::toXML($person->email, $document);
45 | $node->appendChild($child);
46 | }
47 |
48 | # TODO: is_iterable
49 | if (!is_null($person->links)) {
50 | foreach ($person->links as $link) {
51 | $child = LinkParser::toXML($link, $document);
52 | $node->appendChild($child);
53 | }
54 | }
55 |
56 | return $node;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/EmailParserTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Parsers;
7 |
8 | use phpGPX\Models\Email;
9 | use phpGPX\Parsers\EmailParser;
10 |
11 | class EmailParserTest extends AbstractParserTest
12 | {
13 | protected $testModelClass = Email::class;
14 | protected $testParserClass = EmailParser::class;
15 |
16 | /**
17 | * @var Email
18 | */
19 | protected $testModelInstance;
20 |
21 | public static function createTestInstance()
22 | {
23 | $email = new Email();
24 |
25 | $email->id = "jakub.dubec";
26 | $email->domain = "gmail.com";
27 |
28 | return $email;
29 | }
30 |
31 | protected function setUp(): void
32 | {
33 | parent::setUp();
34 |
35 | $this->testModelInstance = self::createTestInstance();
36 | }
37 |
38 |
39 | public function testParse()
40 | {
41 | $email = EmailParser::parse($this->testXmlFile->email);
42 |
43 | $this->assertNotEmpty($email);
44 |
45 | $this->assertEquals($this->testModelInstance->id, $email->id);
46 | $this->assertEquals($this->testModelInstance->domain, $email->domain);
47 |
48 | $this->assertEquals($this->testModelInstance->toArray(), $email->toArray());
49 | }
50 |
51 | /**
52 | * Returns output of ::toXML method of tested parser.
53 | * @depends testParse
54 | * @param \DOMDocument $document
55 | * @return \DOMElement
56 | */
57 | protected function convertToXML(\DOMDocument $document)
58 | {
59 | return EmailParser::toXML($this->testModelInstance, $document);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/CopyrightParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Copyright;
10 |
11 | /**
12 | * Class CopyrightParser
13 | * @package phpGPX\Parsers
14 | */
15 | abstract class CopyrightParser
16 | {
17 | public static $tagName = 'copyright';
18 |
19 | /**
20 | * @param \SimpleXMLElement $node
21 | * @return Copyright|null
22 | */
23 | public static function parse(\SimpleXMLElement $node)
24 | {
25 | if ($node->getName() != self::$tagName) {
26 | return null;
27 | }
28 |
29 | $copyright = new Copyright();
30 |
31 | $copyright->author = isset($node['author']) ? (string) $node['author'] : null;
32 | $copyright->year = isset($node->year) ? (string) $node->year : null;
33 | $copyright->license = isset($node->license) ? (string) $node->license : null;
34 |
35 | return $copyright;
36 | }
37 |
38 | /**
39 | * @param Copyright $copyright
40 | * @param \DOMDocument $document
41 | * @return \DOMElement
42 | */
43 | public static function toXML(Copyright $copyright, \DOMDocument &$document)
44 | {
45 | $node = $document->createElement(self::$tagName);
46 |
47 | $node->setAttribute('author', $copyright->author);
48 |
49 | if (!empty($copyright->year)) {
50 | $child = $document->createElement('year', $copyright->year);
51 | $node->appendChild($child);
52 | }
53 |
54 | if (!empty($copyright->license)) {
55 | $child = $document->createElement('license', $copyright->license);
56 | $node->appendChild($child);
57 | }
58 |
59 | return $node;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/LinkParserTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Parsers;
7 |
8 | use phpGPX\Models\Link;
9 | use phpGPX\Parsers\LinkParser;
10 |
11 | class LinkParserTest extends AbstractParserTest
12 | {
13 | protected $testModelClass = Link::class;
14 | protected $testParserClass = LinkParser::class;
15 |
16 | /**
17 | * @var Link
18 | */
19 | protected $testModelInstance;
20 |
21 | /**
22 | * @return Link
23 | */
24 | public static function createTestInstance()
25 | {
26 | $link = new Link();
27 | $link->href = "https://jakubdubec.me";
28 | $link->text = "Portfolio";
29 | $link->type = "text/html";
30 |
31 | return $link;
32 | }
33 |
34 | protected function setUp(): void
35 | {
36 | parent::setUp();
37 |
38 | $this->testModelInstance = self::createTestInstance();
39 | }
40 |
41 | public function testParse()
42 | {
43 | $links = LinkParser::parse($this->testXmlFile->link);
44 |
45 | $this->assertNotEmpty($links);
46 |
47 | $link = $links[0];
48 |
49 | $this->assertEquals($this->testModelInstance->href, $link->href);
50 | $this->assertEquals($this->testModelInstance->text, $link->text);
51 | $this->assertEquals($this->testModelInstance->type, $link->type);
52 |
53 | $this->assertEquals($this->testModelInstance->toArray(), $link->toArray());
54 | }
55 |
56 |
57 | /**
58 | * Returns output of ::toXML method of tested parser.
59 | * @param \DOMDocument $document
60 | * @return \DOMElement
61 | */
62 | protected function convertToXML(\DOMDocument $document)
63 | {
64 | return LinkParser::toXML($this->testModelInstance, $document);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-Extensions-TrackPointExtensionParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\Extensions\TrackPointExtensionParser
2 | ===============
3 |
4 |
5 |
6 |
7 |
8 |
9 | * Class name: TrackPointExtensionParser
10 | * Namespace: phpGPX\Parsers\Extensions
11 |
12 |
13 |
14 |
15 |
16 | Properties
17 | ----------
18 |
19 |
20 | ### $attributeMapper
21 |
22 | private mixed $attributeMapper = array('atemp' => array('name' => 'aTemp', 'type' => 'float'), 'wtemp' => array('name' => 'wTemp', 'type' => 'float'), 'depth' => array('name' => 'depth', 'type' => 'float'), 'hr' => array('name' => 'hr', 'type' => 'float'), 'cad' => array('name' => 'cad', 'type' => 'float'), 'speed' => array('name' => 'speed', 'type' => 'float'), 'course' => array('name' => 'course', 'type' => 'int'), 'bearing' => array('name' => 'bearing', 'type' => 'int'))
23 |
24 |
25 |
26 |
27 |
28 | * Visibility: **private**
29 | * This property is **static**.
30 |
31 |
32 | Methods
33 | -------
34 |
35 |
36 | ### parse
37 |
38 | \phpGPX\Models\Extensions\TrackPointExtension phpGPX\Parsers\Extensions\TrackPointExtensionParser::parse(\SimpleXMLElement $node)
39 |
40 |
41 |
42 |
43 |
44 | * Visibility: **public**
45 | * This method is **static**.
46 |
47 |
48 | #### Arguments
49 | * $node **SimpleXMLElement**
50 |
51 |
52 |
53 | ### toXML
54 |
55 | \DOMElement phpGPX\Parsers\Extensions\TrackPointExtensionParser::toXML(\phpGPX\Models\Extensions\TrackPointExtension $extension, \DOMDocument $document)
56 |
57 |
58 |
59 |
60 |
61 | * Visibility: **public**
62 | * This method is **static**.
63 |
64 |
65 | #### Arguments
66 | * $extension **[phpGPX\Models\Extensions\TrackPointExtension](phpGPX-Models-Extensions-TrackPointExtension.md)**
67 | * $document **DOMDocument**
68 |
69 |
70 |
--------------------------------------------------------------------------------
/docs/phpGPX-Helpers-SerializationHelper.md:
--------------------------------------------------------------------------------
1 | phpGPX\Helpers\SerializationHelper
2 | ===============
3 |
4 | Class SerializationHelper
5 | Contains basic serialization helpers used in summary() methods.
6 |
7 |
8 |
9 |
10 | * Class name: SerializationHelper
11 | * Namespace: phpGPX\Helpers
12 | * This is an **abstract** class
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Methods
21 | -------
22 |
23 |
24 | ### integerOrNull
25 |
26 | integer|null phpGPX\Helpers\SerializationHelper::integerOrNull($value)
27 |
28 | Returns integer or null.
29 |
30 |
31 |
32 | * Visibility: **public**
33 | * This method is **static**.
34 |
35 |
36 | #### Arguments
37 | * $value **mixed**
38 |
39 |
40 |
41 | ### floatOrNull
42 |
43 | float|null phpGPX\Helpers\SerializationHelper::floatOrNull($value)
44 |
45 | Returns float or null.
46 |
47 |
48 |
49 | * Visibility: **public**
50 | * This method is **static**.
51 |
52 |
53 | #### Arguments
54 | * $value **mixed**
55 |
56 |
57 |
58 | ### stringOrNull
59 |
60 | null|string phpGPX\Helpers\SerializationHelper::stringOrNull($value)
61 |
62 | Returns string or null
63 |
64 |
65 |
66 | * Visibility: **public**
67 | * This method is **static**.
68 |
69 |
70 | #### Arguments
71 | * $value **mixed**
72 |
73 |
74 |
75 | ### serialize
76 |
77 | array|null phpGPX\Helpers\SerializationHelper::serialize(\phpGPX\Models\Summarizable|array $object)
78 |
79 | Recursively traverse Summarizable objects and returns their array representation according summary() method.
80 |
81 |
82 |
83 | * Visibility: **public**
84 | * This method is **static**.
85 |
86 |
87 | #### Arguments
88 | * $object **[phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)|array<mixed,\phpGPX\Models\Summarizable>**
89 |
90 |
91 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/BoundsParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Bounds;
10 |
11 | /**
12 | * Class BoundsParser
13 | * @package phpGPX\Parsers
14 | */
15 | abstract class BoundsParser
16 | {
17 | private static $tagName = 'bounds';
18 |
19 | /**
20 | * Parse data from XML.
21 | * @param \SimpleXMLElement $node
22 | * @return Bounds|null
23 | */
24 | public static function parse(\SimpleXMLElement $node)
25 | {
26 | if ($node->getName() != self::$tagName) {
27 | return null;
28 | }
29 |
30 | $bounds = new Bounds(
31 | isset($node['minlat']) ? (float) $node['minlat'] : null,
32 | isset($node['minlon']) ? (float) $node['minlon'] : null,
33 | isset($node['maxlat']) ? (float) $node['maxlat'] : null,
34 | isset($node['maxlon']) ? (float) $node['maxlon'] : null
35 | );
36 |
37 | return $bounds;
38 | }
39 |
40 | /**
41 | * Create XML representation.
42 | * @param Bounds $bounds
43 | * @param \DOMDocument $document
44 | * @return \DOMElement
45 | */
46 | public static function toXML(Bounds $bounds, \DOMDocument &$document)
47 | {
48 | $node = $document->createElement(self::$tagName);
49 |
50 | if (!is_null($bounds->minLatitude)) {
51 | $node->setAttribute('minlat', $bounds->minLatitude);
52 | }
53 |
54 | if (!is_null($bounds->minLongitude)) {
55 | $node->setAttribute('minlon', $bounds->minLongitude);
56 | }
57 |
58 | if (!is_null($bounds->maxLatitude)) {
59 | $node->setAttribute('maxlat', $bounds->maxLatitude);
60 | }
61 |
62 | if (!is_null($bounds->maxLongitude)) {
63 | $node->setAttribute('maxlon', $bounds->maxLongitude);
64 | }
65 |
66 | return $node;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/phpGPX/Helpers/GeoHelper.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Helpers;
8 |
9 | use phpGPX\Models\Point;
10 |
11 | /**
12 | * Class GeoHelper
13 | * Geolocation methods.
14 | * @package phpGPX\Helpers
15 | */
16 | abstract class GeoHelper
17 | {
18 | const EARTH_RADIUS = 6371000;
19 |
20 | /**
21 | * Returns distance in meters between two Points according to GPX coordinates.
22 | * @see Point
23 | * @param Point $point1
24 | * @param Point $point2
25 | * @return float
26 | */
27 | public static function getRawDistance(Point $point1, Point $point2)
28 | {
29 | $latFrom = deg2rad($point1->latitude);
30 | $lonFrom = deg2rad($point1->longitude);
31 | $latTo = deg2rad($point2->latitude);
32 | $lonTo = deg2rad($point2->longitude);
33 |
34 | $lonDelta = $lonTo - $lonFrom;
35 | $a = pow(cos($latTo) * sin($lonDelta), 2) + pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2);
36 | $b = sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta);
37 | $angle = atan2(sqrt($a), $b);
38 |
39 | return $angle * self::EARTH_RADIUS;
40 | }
41 |
42 | /**
43 | * Returns distance between two points including elevation gain/loss
44 | * @param Point $point1
45 | * @param Point $point2
46 | * @return float
47 | */
48 | public static function getRealDistance(Point $point1, Point $point2)
49 | {
50 | $distance = self::getRawDistance($point1, $point2);
51 |
52 | $elevation1 = $point1->elevation != null ? $point1->elevation : 0;
53 | $elevation2 = $point2->elevation != null ? $point2->elevation : 0;
54 | $elevDiff = abs($elevation1 - $elevation2);
55 |
56 | return sqrt(pow($distance, 2) + pow($elevDiff, 2));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/LinkParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Link;
10 |
11 | abstract class LinkParser
12 | {
13 | private static $tagName = 'link';
14 |
15 | /**
16 | * @param \SimpleXMLElement[] $nodes
17 | * @return Link[]
18 | */
19 | public static function parse($nodes = [])
20 | {
21 | $links = [];
22 | foreach ($nodes as $node) {
23 | $link = new Link();
24 | $link->href = isset($node['href']) ? (string) $node['href'] : null;
25 | $link->text = isset($node->text) ? (string) $node->text : null;
26 | $link->type = isset($node->type) ? (string) $node->type : null;
27 |
28 | $links[] = $link;
29 | }
30 | return $links;
31 | }
32 |
33 | /**
34 | * @param Link[] $links
35 | * @param \DOMDocument $document
36 | * @return \DOMElement[]
37 | */
38 | public static function toXMLArray(array $links, \DOMDocument &$document)
39 | {
40 | $result = [];
41 |
42 | foreach ($links as $link) {
43 | $result[] = self::toXML($link, $document);
44 | }
45 |
46 | return $result;
47 | }
48 |
49 | /**
50 | * @param Link $link
51 | * @param \DOMDocument $document
52 | * @return \DOMElement
53 | */
54 | public static function toXML(Link $link, \DOMDocument &$document)
55 | {
56 | $node = $document->createElement(self::$tagName);
57 |
58 | $node->setAttribute('href', $link->href);
59 |
60 | if (!empty($link->text)) {
61 | $child = $document->createElement('text', $link->text);
62 | $node->appendChild($child);
63 | }
64 |
65 | if (!empty($link->type)) {
66 | $child = $document->createElement('type', $link->type);
67 | $node->appendChild($child);
68 | }
69 |
70 | return $node;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/CopyrightParserTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace phpGPX\Tests\UnitTests\phpGPX\Parsers;
7 |
8 | use phpGPX\Models\Copyright;
9 | use phpGPX\Parsers\CopyrightParser;
10 | use UnitTests\phpGPX\Parsers\AbstractParserTest;
11 |
12 | class CopyrightParserTest extends AbstractParserTest
13 | {
14 | protected $testModelClass = Copyright::class;
15 | protected $testParserClass = CopyrightParser::class;
16 |
17 | /**
18 | * @var Copyright
19 | */
20 | protected $testModelInstance;
21 |
22 | public static function createTestInstance()
23 | {
24 | $copyright = new Copyright();
25 |
26 | $copyright->author = "Jakub Dubec";
27 | $copyright->license = "https://github.com/Sibyx/phpGPX/blob/master/LICENSE";
28 | $copyright->year = '2017';
29 |
30 | return $copyright;
31 | }
32 |
33 | protected function setUp(): void
34 | {
35 | parent::setUp();
36 |
37 | $this->testModelInstance = self::createTestInstance();
38 | }
39 |
40 | public function testParse()
41 | {
42 | $copyright = CopyrightParser::parse($this->testXmlFile->copyright);
43 |
44 | $this->assertNotEmpty($copyright);
45 |
46 | $this->assertEquals($this->testModelInstance->author, $copyright->author);
47 | $this->assertEquals($this->testModelInstance->license, $copyright->license);
48 | $this->assertEquals($this->testModelInstance->year, $copyright->year);
49 |
50 | $this->assertEquals($this->testModelInstance->toArray(), $copyright->toArray());
51 | }
52 |
53 | /**
54 | * Returns output of ::toXML method of tested parser.
55 | * @param \DOMDocument $document
56 | * @return \DOMElement
57 | */
58 | protected function convertToXML(\DOMDocument $document)
59 | {
60 | return CopyrightParser::toXML($this->testModelInstance, $document);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-MetadataParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\MetadataParser
2 | ===============
3 |
4 | Class MetadataParser
5 |
6 |
7 |
8 |
9 | * Class name: MetadataParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | private mixed $tagName = 'metadata'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **private**
30 | * This property is **static**.
31 |
32 |
33 | ### $attributeMapper
34 |
35 | private mixed $attributeMapper = array('name' => array('name' => 'name', 'type' => 'string'), 'desc' => array('name' => 'description', 'type' => 'string'), 'author' => array('name' => 'author', 'type' => 'object'), 'copyright' => array('name' => 'copyright', 'type' => 'object'), 'link' => array('name' => 'links', 'type' => 'array'), 'time' => array('name' => 'time', 'type' => 'object'), 'keywords' => array('name' => 'keywords', 'type' => 'string'), 'bounds' => array('name' => 'bounds', 'type' => 'object'), 'extensions' => array('name' => 'extensions', 'type' => 'object'))
36 |
37 |
38 |
39 |
40 |
41 | * Visibility: **private**
42 | * This property is **static**.
43 |
44 |
45 | Methods
46 | -------
47 |
48 |
49 | ### parse
50 |
51 | \phpGPX\Models\Metadata phpGPX\Parsers\MetadataParser::parse(\SimpleXMLElement $node)
52 |
53 |
54 |
55 |
56 |
57 | * Visibility: **public**
58 | * This method is **static**.
59 |
60 |
61 | #### Arguments
62 | * $node **SimpleXMLElement**
63 |
64 |
65 |
66 | ### toXML
67 |
68 | mixed phpGPX\Parsers\MetadataParser::toXML(\phpGPX\Models\Metadata $metadata, \DOMDocument $document)
69 |
70 |
71 |
72 |
73 |
74 | * Visibility: **public**
75 | * This method is **static**.
76 |
77 |
78 | #### Arguments
79 | * $metadata **[phpGPX\Models\Metadata](phpGPX-Models-Metadata.md)**
80 | * $document **DOMDocument**
81 |
82 |
83 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/ExtensionParserTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 14
6 | 152
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Helpers/GeoHelperTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Helpers;
7 |
8 | use phpGPX\Helpers\GeoHelper;
9 | use phpGPX\Models\Point;
10 | use PHPUnit\Framework\TestCase;
11 |
12 | class GeoHelperTest extends TestCase
13 | {
14 |
15 | /**
16 | * Tested with https://www.freemaptools.com/measure-distance.htm
17 | *
18 | * Input points:
19 | * - 48.1573923225717 17.0547121910204
20 | * - 48.1644916381763 17.0591753907502
21 | */
22 | public function testGetDistance()
23 | {
24 | $point1 = new Point(Point::WAYPOINT);
25 | $point1->latitude = 48.1573923225717;
26 | $point1->longitude = 17.0547121910204;
27 |
28 | $point2 = new Point(Point::WAYPOINT);
29 | $point2->latitude = 48.1644916381763;
30 | $point2->longitude = 17.0591753907502;
31 |
32 | $this->assertEqualsWithDelta(
33 | 856.97,
34 | GeoHelper::getRawDistance($point1, $point2),
35 | 1,
36 | "Invalid distance between two points!"
37 | );
38 | }
39 |
40 | /**
41 | * @link http://cosinekitty.com/compass.html
42 | */
43 | public function testRealDistance()
44 | {
45 | $point1 = new Point(Point::WAYPOINT);
46 | $point1->latitude = 48.1573923225717;
47 | $point1->longitude = 17.0547121910204;
48 | $point1->elevation = 100;
49 |
50 | $point2 = new Point(Point::WAYPOINT);
51 | $point2->latitude = 48.1644916381763;
52 | $point2->longitude = 17.0591753907502;
53 | $point2->elevation = 200;
54 |
55 | $this->assertEqualsWithDelta(
56 | 856.97,
57 | GeoHelper::getRawDistance($point1, $point2),
58 | 1,
59 | "Invalid distance between two points!"
60 | );
61 |
62 | $this->assertEqualsWithDelta(
63 | 862,
64 | GeoHelper::getRealDistance($point1, $point2),
65 | 1,
66 | "Invalid real distance between two points!"
67 | );
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Segment.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Segment
2 | ===============
3 |
4 | Class Segment
5 | A Track Segment holds a list of Track Points which are logically connected in order.
6 |
7 | To represent a single GPS track where GPS reception was lost, or the GPS receiver was turned off,
8 | start a new Track Segment for each continuous span of track data.
9 |
10 |
11 | * Class name: Segment
12 | * Namespace: phpGPX\Models
13 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md), [phpGPX\Models\StatsCalculator](phpGPX-Models-StatsCalculator.md)
14 |
15 |
16 |
17 |
18 | Properties
19 | ----------
20 |
21 |
22 | ### $points
23 |
24 | public array $points
25 |
26 | Array of segment points
27 |
28 |
29 |
30 | * Visibility: **public**
31 |
32 |
33 | ### $extensions
34 |
35 | public \phpGPX\Models\Extensions $extensions
36 |
37 | You can add extend GPX by adding your own elements from another schema here.
38 |
39 |
40 |
41 | * Visibility: **public**
42 |
43 |
44 | ### $stats
45 |
46 | public \phpGPX\Models\Stats $stats
47 |
48 |
49 |
50 |
51 |
52 | * Visibility: **public**
53 |
54 |
55 | Methods
56 | -------
57 |
58 |
59 | ### __construct
60 |
61 | mixed phpGPX\Models\Segment::__construct()
62 |
63 | Segment constructor.
64 |
65 |
66 |
67 | * Visibility: **public**
68 |
69 |
70 |
71 |
72 | ### toArray
73 |
74 | array phpGPX\Models\Summarizable::toArray()
75 |
76 | Serialize object to array
77 |
78 |
79 |
80 | * Visibility: **public**
81 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
82 |
83 |
84 |
85 |
86 | ### recalculateStats
87 |
88 | void phpGPX\Models\StatsCalculator::recalculateStats()
89 |
90 | Recalculate stats objects.
91 |
92 |
93 |
94 | * Visibility: **public**
95 | * This method is defined by [phpGPX\Models\StatsCalculator](phpGPX-Models-StatsCalculator.md)
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/tests/fixtures/timezero.gpx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Event 0000
6 |
7 |
8 | 10
9 | -16744448
10 |
11 |
12 |
13 |
14 | Event 0001
15 |
16 |
17 | 10
18 | -16744448
19 |
20 |
21 |
22 | Ownship
23 |
24 | 201
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Ownship
40 |
41 | 102
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/phpGPX/Helpers/SerializationHelper.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Helpers;
8 |
9 | use phpGPX\Models\Summarizable;
10 |
11 | /**
12 | * Class SerializationHelper
13 | * Contains basic serialization helpers used in summary() methods.
14 | * @package phpGPX\Helpers
15 | */
16 | abstract class SerializationHelper
17 | {
18 |
19 | /**
20 | * Returns integer or null.
21 | * @param $value
22 | * @return int|null
23 | */
24 | public static function integerOrNull($value)
25 | {
26 | return is_numeric($value) ? (integer) $value : null;
27 | }
28 |
29 | /**
30 | * Returns float or null.
31 | * @param $value
32 | * @return float|null
33 | */
34 | public static function floatOrNull($value)
35 | {
36 | return is_numeric($value) ? (float) $value : null;
37 | }
38 |
39 | /**
40 | * Returns string or null
41 | * @param $value
42 | * @return null|string
43 | */
44 | public static function stringOrNull($value)
45 | {
46 | return is_string($value) ? $value : null;
47 | }
48 |
49 | /**
50 | * Recursively traverse Summarizable objects and returns their array representation according summary() method.
51 | * @param Summarizable|Summarizable[] $object
52 | * @return array|null
53 | */
54 | public static function serialize($object)
55 | {
56 | if (is_array($object)) {
57 | $result = [];
58 | foreach ($object as $record) {
59 | $result[] = $record->toArray();
60 | $record = null;
61 | }
62 | $object = null;
63 | return $result;
64 | } else {
65 | return $object != null ? $object->toArray() : null;
66 | }
67 | }
68 |
69 | public static function filterNotNull(array $array)
70 | {
71 | foreach ($array as &$item) {
72 | if (!is_array($item)) {
73 | continue;
74 | }
75 |
76 | $item = self::filterNotNull($item);
77 | }
78 |
79 | $array = array_filter($array, function ($item) {
80 | return $item !== null && (!is_array($item) || count($item));
81 | });
82 |
83 | return $array;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/SegmentParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Segment;
10 | use phpGPX\phpGPX;
11 |
12 | /**
13 | * Class SegmentParser
14 | * @package phpGPX\Parsers
15 | */
16 | abstract class SegmentParser
17 | {
18 | public static $tagName = 'trkseg';
19 |
20 | /**
21 | * @param $nodes \SimpleXMLElement[]
22 | * @return Segment[]
23 | */
24 | public static function parse($nodes)
25 | {
26 | $segments = [];
27 |
28 | foreach ($nodes as $node) {
29 | $segment = new Segment();
30 |
31 | if (!$node->count()) {
32 | continue;
33 | }
34 |
35 | if (isset($node->trkpt)) {
36 | $segment->points = [];
37 |
38 | foreach ($node->trkpt as $point) {
39 | $segment->points[] = PointParser::parse($point);
40 | }
41 | }
42 | $segment->extensions = isset($node->extensions) ? ExtensionParser::parse($node->extensions) : null;
43 |
44 | if (phpGPX::$CALCULATE_STATS) {
45 | $segment->recalculateStats();
46 | }
47 |
48 | $segments[] = $segment;
49 | }
50 |
51 | return $segments;
52 | }
53 |
54 | /**
55 | * @param Segment $segment
56 | * @param \DOMDocument $document
57 | * @return \DOMElement
58 | */
59 | public static function toXML(Segment $segment, \DOMDocument &$document)
60 | {
61 | $node = $document->createElement(self::$tagName);
62 |
63 | foreach ($segment->points as $point) {
64 | $node->appendChild(PointParser::toXML($point, $document));
65 | }
66 |
67 | if (!empty($segment->extensions)) {
68 | $node->appendChild(ExtensionParser::toXML($segment->extensions, $document));
69 | }
70 |
71 | return $node;
72 | }
73 |
74 | /**
75 | * @param array $segments
76 | * @param \DOMDocument $document
77 | * @return \DOMElement[]
78 | */
79 | public static function toXMLArray(array $segments, \DOMDocument $document)
80 | {
81 | $result = [];
82 |
83 | foreach ($segments as $segment) {
84 | $result[] = self::toXML($segment, $document);
85 | }
86 |
87 | return $result;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Helpers/DateTimeHelperTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Helpers;
7 |
8 | use phpGPX\Helpers\DateTimeHelper;
9 | use phpGPX\Models\Point;
10 | use PHPUnit\Framework\TestCase;
11 |
12 | class DateTimeHelperTest extends TestCase
13 | {
14 | public function testComparePointsByTimestamp()
15 | {
16 | // 2017-08-12T20:16:29+00:00
17 | $point1 = new Point(Point::WAYPOINT);
18 | $time1 = new \DateTime("2017-08-12T20:16:29+00:00", new \DateTimeZone("UTC"));
19 | $point1->time = $time1;
20 |
21 | // 2017-08-12T20:15:19+00:00
22 | $point2 = new Point(Point::WAYPOINT);
23 | $time2 = new \DateTime("2017-08-12T20:15:19+00:00", new \DateTimeZone("UTC"));
24 | $point2->time = $time2;
25 |
26 | $this->assertTrue(($time1 > $time2) && DateTimeHelper::comparePointsByTimestamp($point1, $point2));
27 | }
28 |
29 | public function testFormatDateTime()
30 | {
31 | // 1. Basic test
32 | $datetime = new \DateTime("2017-08-12T20:16:29+00:00");
33 |
34 | $this->assertEquals(
35 | $datetime->format("Y-m-d H:i:s"),
36 | DateTimeHelper::formatDateTime($datetime, "Y-m-d H:i:s")
37 | );
38 |
39 | // 2. NULL value
40 | $datetime = null;
41 |
42 | $this->assertNull(DateTimeHelper::formatDateTime($datetime), "NULL input");
43 |
44 | // 3. Empty string
45 | $datetime = "";
46 |
47 | $this->assertNull(DateTimeHelper::formatDateTime($datetime), "Empty string input");
48 |
49 | // 4. Timezone
50 | $datetime = new \DateTime("2017-08-12T20:16:29+00:00");
51 |
52 | $this->assertEquals(
53 | "2017-08-12 21:16:29",
54 | DateTimeHelper::formatDateTime($datetime, "Y-m-d H:i:s", '+01:00')
55 | );
56 | }
57 |
58 | public function testParseDateTime()
59 | {
60 | // 1. Valid string
61 | $this->assertEquals(
62 | new \DateTime("2017-08-12T20:16:29+00:00"),
63 | DateTimeHelper::parseDateTime("2017-08-12T20:16:29+00:00")
64 | );
65 | }
66 |
67 | public function testParseDateTimeInvalidInput()
68 | {
69 | $this->expectException("Exception");
70 | DateTimeHelper::parseDateTime("Invalid exception");
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/AbstractParserTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Parsers;
7 |
8 | use phpGPX\Models\Summarizable;
9 | use PHPUnit\Framework\TestCase;
10 |
11 | abstract class AbstractParserTest extends TestCase
12 | {
13 | /**
14 | * @var \SimpleXMLElement
15 | */
16 | protected $testXmlFile;
17 |
18 | /**
19 | * Instance of model holding data for parser.
20 | * EXAMPLE: model phpGPX\Models\Bounds belongs to parser phpGPX\Parsers\BoundsParser
21 | * @var Summarizable
22 | */
23 | protected $testModelInstance;
24 |
25 | /**
26 | * Full name with namespace for models class.
27 | * EXAMPLE: phpGPX\Models\Bounds
28 | * @var string
29 | */
30 | protected $testModelClass;
31 |
32 | /**
33 | * Full name with namespace for parser class.
34 | * EXAMPLE: phpGPX\Parsers\BoundsParser
35 | * @var string
36 | */
37 | protected $testParserClass;
38 |
39 | protected function setUp(): void
40 | {
41 | $reflection = new \ReflectionClass($this->testParserClass);
42 |
43 | $this->testXmlFile = simplexml_load_file(sprintf("%s/%sTest.xml", __DIR__, $reflection->getShortName()));
44 | }
45 |
46 | abstract public function testParse();
47 |
48 | /**
49 | * Returns output of ::toXML method of tested parser.
50 | * @depends testParse
51 | * @param \DOMDocument $document
52 | * @return \DOMElement
53 | */
54 | abstract protected function convertToXML(\DOMDocument $document);
55 |
56 | public function testToXML()
57 | {
58 | $document = new \DOMDocument("1.0", 'UTF-8');
59 |
60 | $root = $document->createElement("document");
61 | $root->appendChild($this->convertToXML($document));
62 |
63 | $document->appendChild($root);
64 |
65 | $this->assertXmlStringEqualsXmlString($this->testXmlFile->asXML(), $document->saveXML());
66 | }
67 |
68 | public function testToJSON()
69 | {
70 | $reflection = new \ReflectionClass($this->testParserClass);
71 |
72 | $this->assertJsonStringEqualsJsonFile(
73 | sprintf("%s/%sTest.json", __DIR__, $reflection->getShortName()),
74 | json_encode($this->testModelInstance->toArray())
75 | );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/phpGPX/Helpers/DistanceCalculator.php:
--------------------------------------------------------------------------------
1 | points = $points;
30 | }
31 |
32 | public function getRawDistance()
33 | {
34 | return $this->calculate([GeoHelper::class, 'getRawDistance']);
35 | }
36 |
37 | public function getRealDistance()
38 | {
39 | return $this->calculate([GeoHelper::class, 'getRealDistance']);
40 | }
41 |
42 | /**
43 | * @param Point[]|array $points
44 | * @return float
45 | */
46 | private function calculate($strategy)
47 | {
48 | $distance = 0;
49 |
50 | $pointCount = count($this->points);
51 |
52 | $lastConsideredPoint = null;
53 |
54 | for ($p = 0; $p < $pointCount; $p++) {
55 | $curPoint = $this->points[$p];
56 |
57 | // skip the first point
58 | if ($p === 0) {
59 | $lastConsideredPoint = $curPoint;
60 | continue;
61 | }
62 |
63 | // calculate the delta from current point to last considered point
64 | $curPoint->difference = call_user_func($strategy, $lastConsideredPoint, $curPoint);
65 |
66 | // if smoothing is applied we only consider points with a delta above the threshold (e.g. 2 meters)
67 | if (phpGPX::$APPLY_DISTANCE_SMOOTHING) {
68 | $differenceFromLastConsideredPoint = call_user_func($strategy, $curPoint, $lastConsideredPoint);
69 |
70 | if ($differenceFromLastConsideredPoint > phpGPX::$DISTANCE_SMOOTHING_THRESHOLD) {
71 | $distance += $differenceFromLastConsideredPoint;
72 | $lastConsideredPoint = $curPoint;
73 | }
74 | }
75 |
76 | // if smoothing is not applied we consider every point
77 | else {
78 | $distance += $curPoint->difference;
79 | $lastConsideredPoint = $curPoint;
80 | }
81 |
82 | $curPoint->distance = $distance;
83 | }
84 |
85 | return $distance;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/ExtensionParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Extensions;
10 | use phpGPX\Models\Extensions\TrackPointExtension;
11 | use phpGPX\Parsers\Extensions\TrackPointExtensionParser;
12 |
13 | /**
14 | * Class ExtensionParser
15 | * @package phpGPX\Parsers
16 | */
17 | abstract class ExtensionParser
18 | {
19 | public static $tagName = 'extensions';
20 |
21 | public static $usedNamespaces = [];
22 |
23 | /**
24 | * @param \SimpleXMLElement $nodes
25 | * @return Extensions
26 | */
27 | public static function parse($nodes)
28 | {
29 | $extensions = new Extensions();
30 |
31 | $nodeNamespaces = $nodes->getNamespaces(true);
32 |
33 | foreach ($nodeNamespaces as $key => $namespace) {
34 | switch ($namespace) {
35 | case TrackPointExtension::EXTENSION_NAMESPACE:
36 | case TrackPointExtension::EXTENSION_V1_NAMESPACE:
37 | $node = $nodes->children($namespace)->{TrackPointExtension::EXTENSION_NAME};
38 | if (!empty($node)) {
39 | $extensions->trackPointExtension = TrackPointExtensionParser::parse($node);
40 | }
41 | break;
42 | default:
43 | foreach ($nodes->children($namespace) as $child_key => $value) {
44 | $extensions->unsupported[$key ? "$key:$child_key" : "$child_key"] = (string) $value;
45 | }
46 | }
47 | }
48 |
49 | return $extensions;
50 | }
51 |
52 |
53 | /**
54 | * @param Extensions $extensions
55 | * @param \DOMDocument $document
56 | * @return \DOMElement|null
57 | */
58 | public static function toXML(Extensions $extensions, \DOMDocument &$document)
59 | {
60 | $node = $document->createElement(self::$tagName);
61 |
62 | if (null !== $extensions->trackPointExtension) {
63 | $child = TrackPointExtensionParser::toXML($extensions->trackPointExtension, $document);
64 | $node->appendChild($child);
65 | }
66 |
67 | if (!empty($extensions->unsupported)) {
68 | foreach ($extensions->unsupported as $key => $value) {
69 | $child = $document->createElement($key, $value);
70 | $node->appendChild($child);
71 | }
72 | }
73 |
74 | return $node;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-TrackParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\TrackParser
2 | ===============
3 |
4 | Class TrackParser
5 |
6 |
7 |
8 |
9 | * Class name: TrackParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | public mixed $tagName = 'trk'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **public**
30 | * This property is **static**.
31 |
32 |
33 | ### $attributeMapper
34 |
35 | private mixed $attributeMapper = array('name' => array('name' => 'name', 'type' => 'string'), 'cmt' => array('name' => 'comment', 'type' => 'string'), 'desc' => array('name' => 'description', 'type' => 'string'), 'src' => array('name' => 'source', 'type' => 'string'), 'link' => array('name' => 'links', 'type' => 'array'), 'number' => array('name' => 'number', 'type' => 'integer'), 'type' => array('name' => 'type', 'type' => 'string'), 'extensions' => array('name' => 'extensions', 'type' => 'object'), 'trkseg' => array('name' => 'segments', 'type' => 'array'))
36 |
37 |
38 |
39 |
40 |
41 | * Visibility: **private**
42 | * This property is **static**.
43 |
44 |
45 | Methods
46 | -------
47 |
48 |
49 | ### parse
50 |
51 | array phpGPX\Parsers\TrackParser::parse(\SimpleXMLElement $nodes)
52 |
53 |
54 |
55 |
56 |
57 | * Visibility: **public**
58 | * This method is **static**.
59 |
60 |
61 | #### Arguments
62 | * $nodes **SimpleXMLElement**
63 |
64 |
65 |
66 | ### toXML
67 |
68 | \DOMElement phpGPX\Parsers\TrackParser::toXML(\phpGPX\Models\Track $track, \DOMDocument $document)
69 |
70 |
71 |
72 |
73 |
74 | * Visibility: **public**
75 | * This method is **static**.
76 |
77 |
78 | #### Arguments
79 | * $track **[phpGPX\Models\Track](phpGPX-Models-Track.md)**
80 | * $document **DOMDocument**
81 |
82 |
83 |
84 | ### toXMLArray
85 |
86 | array phpGPX\Parsers\TrackParser::toXMLArray(array $tracks, \DOMDocument $document)
87 |
88 |
89 |
90 |
91 |
92 | * Visibility: **public**
93 | * This method is **static**.
94 |
95 |
96 | #### Arguments
97 | * $tracks **array**
98 | * $document **DOMDocument**
99 |
100 |
101 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-RouteParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\RouteParser
2 | ===============
3 |
4 | Class RouteParser
5 |
6 |
7 |
8 |
9 | * Class name: RouteParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $tagName
22 |
23 | public mixed $tagName = 'rte'
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **public**
30 | * This property is **static**.
31 |
32 |
33 | ### $attributeMapper
34 |
35 | private mixed $attributeMapper = array('name' => array('name' => 'name', 'type' => 'string'), 'cmt' => array('name' => 'comment', 'type' => 'string'), 'desc' => array('name' => 'description', 'type' => 'string'), 'src' => array('name' => 'source', 'type' => 'string'), 'link' => array('name' => 'links', 'type' => 'array'), 'number' => array('name' => 'number', 'type' => 'integer'), 'type' => array('name' => 'type', 'type' => 'string'), 'extensions' => array('name' => 'extensions', 'type' => 'object'), 'rtep' => array('name' => 'points', 'type' => 'array'))
36 |
37 |
38 |
39 |
40 |
41 | * Visibility: **private**
42 | * This property is **static**.
43 |
44 |
45 | Methods
46 | -------
47 |
48 |
49 | ### parse
50 |
51 | array phpGPX\Parsers\RouteParser::parse(array $nodes)
52 |
53 |
54 |
55 |
56 |
57 | * Visibility: **public**
58 | * This method is **static**.
59 |
60 |
61 | #### Arguments
62 | * $nodes **array<mixed,\SimpleXMLElement>**
63 |
64 |
65 |
66 | ### toXML
67 |
68 | \DOMElement phpGPX\Parsers\RouteParser::toXML(\phpGPX\Models\Route $route, \DOMDocument $document)
69 |
70 |
71 |
72 |
73 |
74 | * Visibility: **public**
75 | * This method is **static**.
76 |
77 |
78 | #### Arguments
79 | * $route **[phpGPX\Models\Route](phpGPX-Models-Route.md)**
80 | * $document **DOMDocument**
81 |
82 |
83 |
84 | ### toXMLArray
85 |
86 | array phpGPX\Parsers\RouteParser::toXMLArray(array $routes, \DOMDocument $document)
87 |
88 |
89 |
90 |
91 |
92 | * Visibility: **public**
93 | * This method is **static**.
94 |
95 |
96 | #### Arguments
97 | * $routes **array**
98 | * $document **DOMDocument**
99 |
100 |
101 |
--------------------------------------------------------------------------------
/src/phpGPX/Helpers/ElevationGainLossCalculator.php:
--------------------------------------------------------------------------------
1 | elevation;
31 |
32 | // skip points with empty elevation
33 | if ($curElevation === null) {
34 | continue;
35 | }
36 |
37 | // skip points with 0 elevation if configuration allows
38 | if (phpGPX::$IGNORE_ELEVATION_0 && $curElevation == 0) {
39 | continue;
40 | }
41 |
42 | // skip the first point
43 | if ($p === 0) {
44 | $lastConsideredElevation = $curElevation;
45 | continue;
46 | }
47 |
48 | // calculate the delta from current point to last considered point
49 | $elevationDelta = $curElevation - $lastConsideredElevation;
50 |
51 | // if smoothing is applied we only consider points with a delta above the threshold (e.g. 2 meters)
52 | if (phpGPX::$APPLY_ELEVATION_SMOOTHING &&
53 | abs($elevationDelta) > phpGPX::$ELEVATION_SMOOTHING_THRESHOLD &&
54 | (phpGPX::$ELEVATION_SMOOTHING_SPIKES_THRESHOLD === null || abs($elevationDelta) < phpGPX::$ELEVATION_SMOOTHING_SPIKES_THRESHOLD)) {
55 | $cumulativeElevationGain += ($elevationDelta > 0) ? $elevationDelta : 0;
56 | $cumulativeElevationLoss += ($elevationDelta < 0) ? abs($elevationDelta) : 0;
57 |
58 | $lastConsideredElevation = $curElevation;
59 | }
60 |
61 | // if smoothing is not applied we consider every point
62 | if (!phpGPX::$APPLY_ELEVATION_SMOOTHING) {
63 | $cumulativeElevationGain += ($elevationDelta > 0) ? $elevationDelta : 0;
64 | $cumulativeElevationLoss += ($elevationDelta < 0) ? abs($elevationDelta) : 0;
65 |
66 | $lastConsideredElevation = $curElevation;
67 | }
68 | }
69 |
70 | return [$cumulativeElevationGain, $cumulativeElevationLoss];
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/PointParserTest.php:
--------------------------------------------------------------------------------
1 | latitude = 46.571948;
29 | $point->longitude = 8.414757;
30 | $point->elevation = 2419;
31 | $point->time = DateTimeHelper::parseDateTime("2017-08-13T07:10:41.000Z");
32 |
33 | return $point;
34 | }
35 |
36 | public static function createTestInstanceWithValues(
37 | float $latitude,
38 | float $longitude,
39 | float $elevation,
40 | string $timeAsString) : Point
41 | {
42 | $point = new Point(Point::TRACKPOINT);
43 | $point->latitude = $latitude;
44 | $point->longitude = $longitude;
45 | $point->elevation = $elevation;
46 | $point->time = DateTimeHelper::parseDateTime($timeAsString);
47 |
48 | return $point;
49 | }
50 |
51 | protected function setUp(): void
52 | {
53 | parent::setUp();
54 |
55 | $this->testModelInstance = self::createTestInstance();
56 | }
57 |
58 | public function testParse()
59 | {
60 | $point = PointParser::parse($this->testXmlFile->trkpt);
61 |
62 | $this->assertNotEmpty($point);
63 |
64 | // Primitive attributes
65 | $this->assertEquals($this->testModelInstance->latitude, $point->latitude);
66 | $this->assertEquals($this->testModelInstance->longitude, $point->longitude);
67 | $this->assertEquals($this->testModelInstance->elevation, $point->elevation);
68 | $this->assertEquals($this->testModelInstance->time, $point->time);
69 | }
70 |
71 | /**
72 | * Returns output of ::toXML method of tested parser.
73 | * @depends testParse
74 | * @param \DOMDocument $document
75 | * @return \DOMElement
76 | */
77 | protected function convertToXML(\DOMDocument $document)
78 | {
79 | return PointParser::toXML($this->testModelInstance, $document);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Collection.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | /**
10 | * Class Collection
11 | * @package phpGPX\Models
12 | */
13 | abstract class Collection implements Summarizable, StatsCalculator
14 | {
15 |
16 | /**
17 | * GPS name of route / track.
18 | * An original GPX 1.1 attribute.
19 | * @var string|null
20 | */
21 | public $name;
22 |
23 | /**
24 | * GPS comment for route.
25 | * An original GPX 1.1 attribute.
26 | * @var string|null
27 | */
28 | public $comment;
29 |
30 | /**
31 | * Text description of route/track for user. Not sent to GPS.
32 | * An original GPX 1.1 attribute.
33 | * @var string|null
34 | */
35 | public $description;
36 |
37 | /**
38 | * Source of data. Included to give user some idea of reliability and accuracy of data.
39 | * An original GPX 1.1 attribute.
40 | * @var string|null
41 | */
42 | public $source;
43 |
44 | /**
45 | * Links to external information about the route/track.
46 | * An original GPX 1.1 attribute.
47 | * @var Link[]
48 | */
49 | public $links;
50 |
51 | /**
52 | * GPS route/track number.
53 | * An original GPX 1.1 attribute.
54 | * @var int|null
55 | */
56 | public $number;
57 |
58 | /**
59 | * Type (classification) of route/track.
60 | * An original GPX 1.1 attribute.
61 | * @var string|null
62 | */
63 | public $type;
64 |
65 | /**
66 | * You can add extend GPX by adding your own elements from another schema here.
67 | * An original GPX 1.1 attribute.
68 | * @var Extensions|null
69 | */
70 | public $extensions;
71 |
72 | /**
73 | * Objects contains calculated statistics for collection.
74 | * @var Stats|null
75 | */
76 | public $stats;
77 |
78 | /**
79 | * Collection constructor.
80 | */
81 | public function __construct()
82 | {
83 | $this->name = null;
84 | $this->comment = null;
85 | $this->description = null;
86 | $this->source = null;
87 | $this->links = [];
88 | $this->number = null;
89 | $this->type = null;
90 | $this->extensions = null;
91 | }
92 |
93 |
94 | /**
95 | * Return all points in collection.
96 | * @return Point[]
97 | */
98 | abstract public function getPoints(): array;
99 | }
100 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-GpxFile.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\GpxFile
2 | ===============
3 |
4 | Class GpxFile
5 | Representation of GPX file.
6 |
7 |
8 |
9 |
10 | * Class name: GpxFile
11 | * Namespace: phpGPX\Models
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $waypoints
22 |
23 | public array $waypoints
24 |
25 | A list of waypoints.
26 |
27 |
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $routes
33 |
34 | public array $routes
35 |
36 | A list of routes.
37 |
38 |
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $tracks
44 |
45 | public array $tracks
46 |
47 | A list of tracks.
48 |
49 |
50 |
51 | * Visibility: **public**
52 |
53 |
54 | ### $metadata
55 |
56 | public \phpGPX\Models\Metadata $metadata
57 |
58 | Metadata about the file.
59 |
60 | The original GPX 1.1 attribute.
61 |
62 | * Visibility: **public**
63 |
64 |
65 | ### $extensions
66 |
67 | public \phpGPX\Models\Extensions $extensions
68 |
69 |
70 |
71 |
72 |
73 | * Visibility: **public**
74 |
75 |
76 | ### $creator
77 |
78 | public string $creator
79 |
80 | Creator of GPX file.
81 |
82 |
83 |
84 | * Visibility: **public**
85 |
86 |
87 | Methods
88 | -------
89 |
90 |
91 | ### __construct
92 |
93 | mixed phpGPX\Models\GpxFile::__construct()
94 |
95 | GpxFile constructor.
96 |
97 |
98 |
99 | * Visibility: **public**
100 |
101 |
102 |
103 |
104 | ### toArray
105 |
106 | array phpGPX\Models\Summarizable::toArray()
107 |
108 | Serialize object to array
109 |
110 |
111 |
112 | * Visibility: **public**
113 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
114 |
115 |
116 |
117 |
118 | ### toJSON
119 |
120 | string phpGPX\Models\GpxFile::toJSON()
121 |
122 | Return JSON representation of GPX file with statistics.
123 |
124 |
125 |
126 | * Visibility: **public**
127 |
128 |
129 |
130 |
131 | ### toXML
132 |
133 | \DOMDocument phpGPX\Models\GpxFile::toXML()
134 |
135 | Create XML representation of GPX file.
136 |
137 |
138 |
139 | * Visibility: **public**
140 |
141 |
142 |
143 |
144 | ### save
145 |
146 | mixed phpGPX\Models\GpxFile::save(string $path, string $format)
147 |
148 | Save data to file according to selected format.
149 |
150 |
151 |
152 | * Visibility: **public**
153 |
154 |
155 | #### Arguments
156 | * $path **string**
157 | * $format **string**
158 |
159 |
160 |
--------------------------------------------------------------------------------
/docs/phpGPX-phpGPX.md:
--------------------------------------------------------------------------------
1 | phpGPX\phpGPX
2 | ===============
3 |
4 | Class phpGPX
5 |
6 |
7 |
8 |
9 | * Class name: phpGPX
10 | * Namespace: phpGPX
11 |
12 |
13 |
14 | Constants
15 | ----------
16 |
17 |
18 | ### JSON_FORMAT
19 |
20 | const JSON_FORMAT = 'json'
21 |
22 |
23 |
24 |
25 |
26 | ### XML_FORMAT
27 |
28 | const XML_FORMAT = 'xml'
29 |
30 |
31 |
32 |
33 |
34 | ### PACKAGE_NAME
35 |
36 | const PACKAGE_NAME = 'phpGPX'
37 |
38 |
39 |
40 |
41 |
42 | ### VERSION
43 |
44 | const VERSION = '1.0'
45 |
46 |
47 |
48 |
49 |
50 | Properties
51 | ----------
52 |
53 |
54 | ### $CALCULATE_STATS
55 |
56 | public boolean $CALCULATE_STATS = true
57 |
58 | Create Stats object for each track, segment and route
59 |
60 |
61 |
62 | * Visibility: **public**
63 | * This property is **static**.
64 |
65 |
66 | ### $SORT_BY_TIMESTAMP
67 |
68 | public boolean $SORT_BY_TIMESTAMP = false
69 |
70 | Additional sort based on timestamp in Routes & Tracks on XML read.
71 |
72 | Disabled by default, data should be already sorted.
73 |
74 | * Visibility: **public**
75 | * This property is **static**.
76 |
77 |
78 | ### $DATETIME_FORMAT
79 |
80 | public string $DATETIME_FORMAT = 'c'
81 |
82 | Default DateTime output format in JSON serialization.
83 |
84 |
85 |
86 | * Visibility: **public**
87 | * This property is **static**.
88 |
89 |
90 | ### $DATETIME_TIMEZONE_OUTPUT
91 |
92 | public string $DATETIME_TIMEZONE_OUTPUT = 'UTC'
93 |
94 | Default timezone for display.
95 |
96 | Data are always stored in UTC timezone.
97 |
98 | * Visibility: **public**
99 | * This property is **static**.
100 |
101 |
102 | ### $PRETTY_PRINT
103 |
104 | public boolean $PRETTY_PRINT = true
105 |
106 | Pretty print.
107 |
108 |
109 |
110 | * Visibility: **public**
111 | * This property is **static**.
112 |
113 |
114 | Methods
115 | -------
116 |
117 |
118 | ### load
119 |
120 | \phpGPX\Models\GpxFile phpGPX\phpGPX::load($path)
121 |
122 | Load GPX file.
123 |
124 |
125 |
126 | * Visibility: **public**
127 | * This method is **static**.
128 |
129 |
130 | #### Arguments
131 | * $path **mixed**
132 |
133 |
134 |
135 | ### parse
136 |
137 | \phpGPX\Models\GpxFile phpGPX\phpGPX::parse($xml)
138 |
139 | Parse GPX data string.
140 |
141 |
142 |
143 | * Visibility: **public**
144 | * This method is **static**.
145 |
146 |
147 | #### Arguments
148 | * $xml **mixed**
149 |
150 |
151 |
152 | ### getSignature
153 |
154 | string phpGPX\phpGPX::getSignature()
155 |
156 | Create library signature from name and version.
157 |
158 |
159 |
160 | * Visibility: **public**
161 | * This method is **static**.
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/PersonParserTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Parsers;
7 |
8 | use phpGPX\Models\GpxFile;
9 | use phpGPX\Models\Metadata;
10 | use phpGPX\Models\Person;
11 | use phpGPX\Parsers\PersonParser;
12 |
13 | class PersonParserTest extends AbstractParserTest
14 | {
15 | protected $testModelClass = Person::class;
16 | protected $testParserClass = PersonParser::class;
17 |
18 | /**
19 | * @var Person
20 | */
21 | protected $testModelInstance;
22 |
23 | public static function createTestInstance()
24 | {
25 | $person = new Person();
26 | $person->name = "Jakub Dubec";
27 | $person->email = EmailParserTest::createTestInstance();
28 | $person->links[] = LinkParserTest::createTestInstance();
29 | $person->name = 'Jakub Dubec';
30 |
31 | return $person;
32 | }
33 |
34 | protected function setUp(): void
35 | {
36 | parent::setUp();
37 |
38 | $this->testModelInstance = self::createTestInstance();
39 | }
40 |
41 | public function testParse()
42 | {
43 | $person = PersonParser::parse($this->testXmlFile->author);
44 |
45 | $this->assertNotEmpty($person);
46 |
47 | // Primitive attributes
48 | $this->assertEquals($this->testModelInstance->name, $person->name);
49 |
50 | // Email
51 | $this->assertEquals($this->testModelInstance->email->id, $person->email->id);
52 | $this->assertEquals($this->testModelInstance->email->domain, $person->email->domain);
53 |
54 | // Link
55 | $this->assertEquals($this->testModelInstance->links[0]->type, $person->links[0]->type);
56 | $this->assertEquals($this->testModelInstance->links[0]->text, $person->links[0]->text);
57 | $this->assertEquals($this->testModelInstance->links[0]->href, $person->links[0]->href);
58 |
59 | // toArray functions
60 | $this->assertEquals($this->testModelInstance->toArray(), $person->toArray());
61 | $this->assertEquals($this->testModelInstance->email->toArray(), $person->email->toArray());
62 | $this->assertEquals($this->testModelInstance->links[0]->toArray(), $person->links[0]->toArray());
63 | }
64 |
65 | /**
66 | * Returns output of ::toXML method of tested parser.
67 | * @depends testParse
68 | * @param \DOMDocument $document
69 | * @return \DOMElement
70 | */
71 | protected function convertToXML(\DOMDocument $document)
72 | {
73 | return PersonParser::toXML($this->testModelInstance, $document);
74 | }
75 |
76 | /**
77 | * @url https://github.com/Sibyx/phpGPX/issues/48
78 | */
79 | public function testEmptyLinks()
80 | {
81 | $gpx_file = new GpxFile();
82 |
83 | $gpx_file->metadata = new Metadata();
84 | $gpx_file->metadata->author = new Person();
85 | $gpx_file->metadata->author->name = "Arthur Dent";
86 |
87 | $this->assertNotNull($gpx_file->toXML()->saveXML());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/SegmentParserTest.php:
--------------------------------------------------------------------------------
1 | points = [
28 | PointParserTest::createTestInstanceWithValues(46.571948, 8.414757, 2419, "2017-08-13T07:10:41.000Z"),
29 | PointParserTest::createTestInstanceWithValues(46.572016, 8.414866, 2418.8833883882, "2017-08-13T07:10:54.000Z"),
30 | PointParserTest::createTestInstanceWithValues(46.572088, 8.414911, 2419.8999900064, "2017-08-13T07:11:56.000Z"),
31 | PointParserTest::createTestInstanceWithValues(46.572069, 8.414912, 2422, "2017-08-13T07:12:15.000Z"),
32 | PointParserTest::createTestInstanceWithValues(46.572054, 8.414888, 2425, "2017-08-13T07:12:18.000Z")
33 | ];
34 | $segment->recalculateStats();
35 |
36 | return $segment;
37 | }
38 |
39 | protected function setUp(): void
40 | {
41 | parent::setUp();
42 |
43 | $this->testModelInstance = self::createTestInstance();
44 | }
45 |
46 | public function testParse()
47 | {
48 | $segment = SegmentParser::parse($this->testXmlFile->trkseg);
49 |
50 | $this->assertNotEmpty($segment);
51 |
52 | // Test second point
53 | $point = $segment[0]->points[1];
54 | $this->assertEquals($this->testModelInstance->points[1]->latitude, $point->latitude);
55 | $this->assertEquals($this->testModelInstance->points[1]->longitude, $point->longitude);
56 | $this->assertEquals($this->testModelInstance->points[1]->elevation, $point->elevation);
57 | $this->assertEquals($this->testModelInstance->points[1]->time, $point->time);
58 |
59 | // Stats
60 | $this->assertNotEmpty($this->testModelInstance->stats);
61 |
62 | // Check the boundaries
63 | $nw = $this->testModelInstance->stats->bounds[0];
64 | $se = $this->testModelInstance->stats->bounds[1];
65 | $this->assertEquals(46.572088, $nw["lat"]);
66 | $this->assertEquals(8.414757, $nw["lng"]);
67 | $this->assertEquals(46.571948, $se["lat"]);
68 | $this->assertEquals(8.414912, $se["lng"]);
69 | }
70 |
71 | /**
72 | * Returns output of ::toXML method of tested parser.
73 | * @depends testParse
74 | * @param \DOMDocument $document
75 | * @return \DOMElement
76 | */
77 | protected function convertToXML(\DOMDocument $document)
78 | {
79 | return SegmentParser::toXML($this->testModelInstance, $document);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/example/waypoints_create.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | use phpGPX\Models\GpxFile;
7 | use phpGPX\Models\Link;
8 | use phpGPX\Models\Metadata;
9 | use phpGPX\Models\Point;
10 | use phpGPX\Models\Segment;
11 | use phpGPX\Models\Track;
12 |
13 | require_once '../vendor/autoload.php';
14 |
15 | $sample_data = [
16 | [
17 | 'longitude' => 9.860624216140083,
18 | 'latitude' => 54.9328621088893,
19 | 'elevation' => 0,
20 | 'time' => new \DateTime("+ 1 MINUTE")
21 | ],
22 | [
23 | 'latitude' => 54.83293237320851,
24 | 'longitude' => 9.76092208681491,
25 | 'elevation' => 10.0,
26 | 'time' => new \DateTime("+ 2 MINUTE")
27 | ],
28 | [
29 | 'latitude' => 54.73327743521187,
30 | 'longitude' => 9.66187816543752,
31 | 'elevation' => 42.42,
32 | 'time' => new \DateTime("+ 3 MINUTE")
33 | ],
34 | [
35 | 'latitude' => 54.63342326167919,
36 | 'longitude' => 9.562439849679859,
37 | 'elevation' => 12,
38 | 'time' => new \DateTime("+ 4 MINUTE")
39 | ]
40 | ];
41 |
42 | // Creating sample link object for metadata
43 | $link = new Link();
44 | $link->href = "https://sibyx.github.io/phpgpx";
45 | $link->text = 'phpGPX Docs';
46 |
47 | // GpxFile contains data and handles serialization of objects
48 | $gpx_file = new GpxFile();
49 |
50 | // Creating sample Metadata object
51 | $gpx_file->metadata = new Metadata();
52 |
53 | // Time attribute is always \DateTime object!
54 | $gpx_file->metadata->time = new \DateTime();
55 |
56 | // Description of GPX file
57 | $gpx_file->metadata->description = "My pretty awesome GPX file, created using phpGPX library!";
58 |
59 | // Adding link created before to links array of metadata
60 | // Metadata of GPX file can contain more than one link
61 | $gpx_file->metadata->links[] = $link;
62 |
63 | // Creating track
64 | $track = new Track();
65 |
66 | // Name of track
67 | $track->name = sprintf("Some random points in logical order. Input array should be already ordered!");
68 |
69 | // Type of data stored in track
70 | $track->type = 'RUN';
71 |
72 | // Source of GPS coordinates
73 | $track->source = sprintf("MySpecificGarminDevice");
74 |
75 | $wp = [];
76 | foreach ($sample_data as $sample_point) {
77 | // Creating trackpoint
78 | $point = new Point(Point::WAYPOINT);
79 | $point->latitude = $sample_point['latitude'];
80 | $point->longitude = $sample_point['longitude'];
81 | $point->elevation = $sample_point['elevation'];
82 | $point->time = $sample_point['time'];
83 |
84 | $wp[] = $point;
85 | }
86 |
87 | $gpx_file->waypoints = $wp;
88 |
89 | // // Add segment to segment array of track
90 | // $track->segments[] = $segment;
91 |
92 | // // Add track to file
93 | // $gpx_file->tracks[] = $track;
94 |
95 | // GPX output
96 | $gpx_file->save('waypoint_test.gpx', \phpGPX\phpGPX::XML_FORMAT);
97 |
--------------------------------------------------------------------------------
/docs/phpGPX-Parsers-PointParser.md:
--------------------------------------------------------------------------------
1 | phpGPX\Parsers\PointParser
2 | ===============
3 |
4 |
5 |
6 |
7 |
8 |
9 | * Class name: PointParser
10 | * Namespace: phpGPX\Parsers
11 | * This is an **abstract** class
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $attributeMapper
22 |
23 | private mixed $attributeMapper = array('ele' => array('name' => 'elevation', 'type' => 'float'), 'time' => array('name' => 'time', 'type' => 'object'), 'magvar' => array('name' => 'magVar', 'type' => 'float'), 'geoidheight' => array('name' => 'geoidHeight', 'type' => 'float'), 'name' => array('name' => 'name', 'type' => 'string'), 'cmt' => array('name' => 'comment', 'type' => 'string'), 'desc' => array('name' => 'description', 'type' => 'string'), 'src' => array('name' => 'source', 'type' => 'string'), 'link' => array('name' => 'links', 'type' => 'object'), 'sym' => array('name' => 'symbol', 'type' => 'string'), 'type' => array('name' => 'type', 'type' => 'string'), 'fix' => array('name' => 'fix', 'type' => 'string'), 'sat' => array('name' => 'satellitesNumber', 'type' => 'integer'), 'hdop' => array('name' => 'hdop', 'type' => 'float'), 'vdop' => array('name' => 'vdop', 'type' => 'float'), 'pdop' => array('name' => 'pdop', 'type' => 'float'), 'ageofdgpsdata' => array('name' => 'ageOfGpsData', 'type' => 'float'), 'dgpsid' => array('name' => 'dgpsid', 'type' => 'integer'), 'extensions' => array('name' => 'extensions', 'type' => 'object'))
24 |
25 |
26 |
27 |
28 |
29 | * Visibility: **private**
30 | * This property is **static**.
31 |
32 |
33 | ### $typeMapper
34 |
35 | private mixed $typeMapper = array('trkpt' => \phpGPX\Models\Point::TRACKPOINT, 'wpt' => \phpGPX\Models\Point::WAYPOINT, 'rtp' => \phpGPX\Models\Point::ROUTEPOINT)
36 |
37 |
38 |
39 |
40 |
41 | * Visibility: **private**
42 | * This property is **static**.
43 |
44 |
45 | Methods
46 | -------
47 |
48 |
49 | ### parse
50 |
51 | mixed phpGPX\Parsers\PointParser::parse(\SimpleXMLElement $node)
52 |
53 |
54 |
55 |
56 |
57 | * Visibility: **public**
58 | * This method is **static**.
59 |
60 |
61 | #### Arguments
62 | * $node **SimpleXMLElement**
63 |
64 |
65 |
66 | ### toXML
67 |
68 | \DOMElement phpGPX\Parsers\PointParser::toXML(\phpGPX\Models\Point $point, \DOMDocument $document)
69 |
70 |
71 |
72 |
73 |
74 | * Visibility: **public**
75 | * This method is **static**.
76 |
77 |
78 | #### Arguments
79 | * $point **[phpGPX\Models\Point](phpGPX-Models-Point.md)**
80 | * $document **DOMDocument**
81 |
82 |
83 |
84 | ### toXMLArray
85 |
86 | array phpGPX\Parsers\PointParser::toXMLArray(array $points, \DOMDocument $document)
87 |
88 |
89 |
90 |
91 |
92 | * Visibility: **public**
93 | * This method is **static**.
94 |
95 |
96 | #### Arguments
97 | * $points **array**
98 | * $document **DOMDocument**
99 |
100 |
101 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Metadata.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Metadata
2 | ===============
3 |
4 | Class Metadata
5 | Information about the GPX file, author, and copyright restrictions goes in the metadata section.
6 |
7 | Providing rich, meaningful information about your GPX files allows others to search for and use your GPS data.
8 |
9 |
10 | * Class name: Metadata
11 | * Namespace: phpGPX\Models
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $name
22 |
23 | public string $name
24 |
25 | The name of the GPX file.
26 |
27 | Original GPX 1.1 attribute.
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $description
33 |
34 | public string $description
35 |
36 | A description of the contents of the GPX file.
37 |
38 | Original GPX 1.1 attribute.
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $author
44 |
45 | public \phpGPX\Models\Person $author
46 |
47 | The person or organization who created the GPX file.
48 |
49 | An original GPX 1.1 attribute.
50 |
51 | * Visibility: **public**
52 |
53 |
54 | ### $copyright
55 |
56 | public \phpGPX\Models\Copyright $copyright
57 |
58 | Copyright and license information governing use of the file.
59 |
60 | Original GPX 1.1 attribute.
61 |
62 | * Visibility: **public**
63 |
64 |
65 | ### $links
66 |
67 | public array $links
68 |
69 | Original GPX 1.1 attribute.
70 |
71 |
72 |
73 | * Visibility: **public**
74 |
75 |
76 | ### $time
77 |
78 | public \DateTime $time
79 |
80 | Date of GPX creation
81 |
82 |
83 |
84 | * Visibility: **public**
85 |
86 |
87 | ### $keywords
88 |
89 | public string $keywords
90 |
91 | Keywords associated with the file. Search engines or databases can use this information to classify the data.
92 |
93 |
94 |
95 | * Visibility: **public**
96 |
97 |
98 | ### $bounds
99 |
100 | public \phpGPX\Models\Bounds $bounds
101 |
102 | Minimum and maximum coordinates which describe the extent of the coordinates in the file.
103 |
104 | Original GPX 1.1 attribute.
105 |
106 | * Visibility: **public**
107 |
108 |
109 | ### $extensions
110 |
111 | public \phpGPX\Models\Extensions $extensions
112 |
113 | Extensions.
114 |
115 |
116 |
117 | * Visibility: **public**
118 |
119 |
120 | Methods
121 | -------
122 |
123 |
124 | ### __construct
125 |
126 | mixed phpGPX\Models\Metadata::__construct()
127 |
128 | Metadata constructor.
129 |
130 |
131 |
132 | * Visibility: **public**
133 |
134 |
135 |
136 |
137 | ### toArray
138 |
139 | array phpGPX\Models\Summarizable::toArray()
140 |
141 | Serialize object to array
142 |
143 |
144 |
145 | * Visibility: **public**
146 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Helpers/SerializationHelperTest.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace UnitTests\phpGPX\Helpers;
7 |
8 | use phpGPX\Helpers\SerializationHelper;
9 | use PHPUnit\Framework\TestCase;
10 |
11 | class SerializationHelperTest extends TestCase
12 | {
13 | public function testIntegerOrNull()
14 | {
15 | $this->assertNull(SerializationHelper::integerOrNull(""));
16 | $this->assertNull(SerializationHelper::integerOrNull(null));
17 | $this->assertNull(SerializationHelper::integerOrNull("BLA"));
18 | $this->assertIsInt(SerializationHelper::integerOrNull(5));
19 | $this->assertIsInt(SerializationHelper::integerOrNull("5"));
20 | }
21 |
22 | public function testFloatOrNull()
23 | {
24 | $this->assertNull(SerializationHelper::floatOrNull(""));
25 | $this->assertNull(SerializationHelper::floatOrNull(null));
26 | $this->assertNull(SerializationHelper::floatOrNull("BLA"));
27 | $this->assertIsFloat(SerializationHelper::floatOrNull(5.6));
28 | $this->assertIsFloat(SerializationHelper::floatOrNull(5));
29 | $this->assertIsFloat(SerializationHelper::floatOrNull("5.6"));
30 | $this->assertIsFloat(SerializationHelper::floatOrNull("5"));
31 | }
32 |
33 | public function testStringOrNull()
34 | {
35 | $this->assertNull(SerializationHelper::stringOrNull(null));
36 | $this->assertIsString(SerializationHelper::stringOrNull(""));
37 | $this->assertIsString(SerializationHelper::stringOrNull("Bla bla"));
38 | }
39 |
40 | /**
41 | * @dataProvider dataProviderFilterNotNull
42 | */
43 | public function testFilterNotNull($expected, $actual)
44 | {
45 | $this->assertEquals($expected, SerializationHelper::filterNotNull($actual));
46 | }
47 |
48 | public function dataProviderFilterNotNull()
49 | {
50 | return [
51 | 'numeric 1' => [
52 | [],
53 | [null],
54 | ],
55 | 'numeric 2' => [
56 | [],
57 | [null, [null]],
58 | ],
59 | 'numeric 3' => [
60 | [1 => 1],
61 | [null, 1],
62 | ],
63 | 'numeric 4' => [
64 | [1 => 1, 3 => 2],
65 | [null, 1, null, 2, null],
66 | ],
67 | 'numeric 5' => [
68 | [1 => 1, 3 => 2, 5 => [0 => 3, 2 => 4], 6 => 5],
69 | [null, 1, null, 2, null, [3, null, 4], 5, null],
70 | ],
71 | 'associative 1' => [
72 | [],
73 | ["foo" => null],
74 | ],
75 | 'associative 2' => [
76 | [],
77 | ["foo" => null, ["bar" => null]],
78 | ],
79 | 'associative 3' => [
80 | ["bar" => 1],
81 | ["foo" => null, "bar" => 1],
82 | ],
83 | 'associative 4' => [
84 | ["bar" => 1, "caw" => 2],
85 | ["foo" => null, "bar" => 1, "baz" => null, "caw" => 2, "doo" => null],
86 | ],
87 | 'associative 5' => [
88 | ["bar" => 1, "caw" => 2, "ere" => ["foo" => 3, "baz" => 4], "moo" => 5],
89 | ["foo" => null, "bar" => 1, "baz" => null, "caw" => 2, "doo" => null, "ere" => ["foo" => 3, "bar" => null, "baz" => 4], "moo" => 5, "boo" => null],
90 | ],
91 | ];
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/Extensions/TrackPointExtensionParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers\Extensions;
8 |
9 | use phpGPX\Models\Extensions\TrackPointExtension;
10 | use phpGPX\Parsers\ExtensionParser;
11 |
12 | class TrackPointExtensionParser
13 | {
14 | private static $attributeMapper = [
15 | 'atemp' => [
16 | 'name' => 'aTemp',
17 | 'type' => 'float'
18 | ],
19 | 'wtemp' => [
20 | 'name' => 'wTemp',
21 | 'type' => 'float'
22 | ],
23 | 'depth' => [
24 | 'name' => 'depth',
25 | 'type' => 'float'
26 | ],
27 | 'hr' => [
28 | 'name' => 'hr',
29 | 'type' => 'float'
30 | ],
31 | 'cad' => [
32 | 'name' => 'cad',
33 | 'type' => 'float'
34 | ],
35 | 'speed' => [
36 | 'name' => 'speed',
37 | 'type' => 'float'
38 | ],
39 | 'course' => [
40 | 'name' => 'course',
41 | 'type' => 'int'
42 | ],
43 | 'bearing' => [
44 | 'name' => 'bearing',
45 | 'type' => 'int'
46 | ]
47 | ];
48 |
49 | /**
50 | * @param \SimpleXMLElement $node
51 | * @return TrackPointExtension
52 | */
53 | public static function parse($node)
54 | {
55 | $extension = new TrackPointExtension();
56 |
57 | foreach (self::$attributeMapper as $key => $attribute) {
58 | $extension->{$attribute['name']} = isset($node->$key) ? $node->$key : null;
59 | if (!is_null($extension->{$attribute['name']})) {
60 | settype($extension->{$attribute['name']}, $attribute['type']);
61 | }
62 |
63 | // Remove in v1.0
64 | if ($key == 'hr') {
65 | $extension->heartRate = $extension->hr;
66 | }
67 |
68 | // Remove in v1.0
69 | if ($key == 'cad') {
70 | $extension->cadence = $extension->cad;
71 | }
72 |
73 | // Remove in v1.0
74 | if ($key == 'atemp') {
75 | $extension->avgTemperature = $extension->aTemp;
76 | }
77 | }
78 |
79 | return $extension;
80 | }
81 |
82 | /**
83 | * @param TrackPointExtension $extension
84 | * @param \DOMDocument $document
85 | * @return \DOMElement
86 | */
87 | public static function toXML(TrackPointExtension $extension, \DOMDocument &$document)
88 | {
89 | $node = $document->createElement("gpxtpx:TrackPointExtension");
90 |
91 | ExtensionParser::$usedNamespaces[TrackPointExtension::EXTENSION_NAME] = [
92 | 'namespace' => TrackPointExtension::EXTENSION_NAMESPACE,
93 | 'xsd' => TrackPointExtension::EXTENSION_NAMESPACE_XSD,
94 | 'name' => TrackPointExtension::EXTENSION_NAME,
95 | 'prefix' => TrackPointExtension::EXTENSION_NAMESPACE_PREFIX
96 | ];
97 |
98 | foreach (self::$attributeMapper as $key => $attribute) {
99 | if (!is_null($extension->{$attribute['name']})) {
100 | $child = $document->createElement(
101 | sprintf("%s:%s", TrackPointExtension::EXTENSION_NAMESPACE_PREFIX, $key),
102 | $extension->{$attribute['name']}
103 | );
104 | $node->appendChild($child);
105 | }
106 | }
107 |
108 | return $node;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Metadata.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\DateTimeHelper;
10 | use phpGPX\Helpers\SerializationHelper;
11 |
12 | /**
13 | * Class Metadata
14 | * Information about the GPX file, author, and copyright restrictions goes in the metadata section.
15 | * Providing rich, meaningful information about your GPX files allows others to search for and use your GPS data.
16 | * @package phpGPX\Models
17 | */
18 | class Metadata implements Summarizable
19 | {
20 |
21 | /**
22 | * The name of the GPX file.
23 | * Original GPX 1.1 attribute.
24 | * @var string|null
25 | */
26 | public $name;
27 |
28 | /**
29 | * A description of the contents of the GPX file.
30 | * Original GPX 1.1 attribute.
31 | * @var string|null
32 | */
33 | public $description;
34 |
35 | /**
36 | * The person or organization who created the GPX file.
37 | * An original GPX 1.1 attribute.
38 | * @var Person|null
39 | */
40 | public $author;
41 |
42 | /**
43 | * Copyright and license information governing use of the file.
44 | * Original GPX 1.1 attribute.
45 | * @var Copyright|null
46 | */
47 | public $copyright;
48 |
49 | /**
50 | * Original GPX 1.1 attribute.
51 | * @var Link[]|null
52 | */
53 | public $links;
54 |
55 | /**
56 | * Date of GPX creation
57 | * @var \DateTime
58 | */
59 | public $time;
60 |
61 | /**
62 | * Keywords associated with the file. Search engines or databases can use this information to classify the data.
63 | * @var string|null
64 | */
65 | public $keywords;
66 |
67 | /**
68 | * Minimum and maximum coordinates which describe the extent of the coordinates in the file.
69 | * Original GPX 1.1 attribute.
70 | * @var Bounds|null
71 | */
72 | public $bounds;
73 |
74 | /**
75 | * Extensions.
76 | * @var Extensions|null
77 | */
78 | public $extensions;
79 |
80 | /**
81 | * Metadata constructor.
82 | */
83 | public function __construct()
84 | {
85 | $this->name = null;
86 | $this->description = null;
87 | $this->author = null;
88 | $this->copyright = null;
89 | $this->links = [];
90 | $this->time = null;
91 | $this->keywords = null;
92 | $this->bounds = null;
93 | $this->extensions = null;
94 | }
95 |
96 |
97 | /**
98 | * Serialize object to array
99 | * @return array
100 | */
101 | public function toArray()
102 | {
103 | return [
104 | 'name' => SerializationHelper::stringOrNull($this->name),
105 | 'desc' => SerializationHelper::stringOrNull($this->description),
106 | 'author' => SerializationHelper::serialize($this->author),
107 | 'copyright' => SerializationHelper::serialize($this->copyright),
108 | 'links' => SerializationHelper::serialize($this->links),
109 | 'time' => DateTimeHelper::formatDateTime($this->time),
110 | 'keywords' => SerializationHelper::stringOrNull($this->keywords),
111 | 'bounds' => SerializationHelper::serialize($this->bounds),
112 | 'extensions' => SerializationHelper::serialize($this->extensions)
113 | ];
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.3.0 : 2023-07-19
4 |
5 | Changed minimal PHP version to `^7.1` in `composer.json`. Library still should work with PHP5.5+, if you have troubles
6 | while installing check the `--ignore-platform-reqs` attribute of [compose](https://getcomposer.org/doc/03-cli.md).
7 |
8 | - **Added**: [Coordinates for remarqued statistic points](https://github.com/Sibyx/phpGPX/pull/64) (minAltitude, maxAltitude, startedAt, finishedAt)
9 |
10 | ## 1.2.1 : 2022-07-30
11 |
12 | - **Fixed**: Fixed `VERSION` string in `phpGPX.php`
13 |
14 | ## 1.2.0 : 2022-07-30
15 |
16 | - **Changed**: [Real distance calculation #37](https://github.com/Sibyx/phpGPX/issues/37) (DistanceCalculator refactor)
17 |
18 | ## 1.1.3 : 2021-07-29
19 |
20 | - **Fixed**: [Fix negative duration #58](https://github.com/Sibyx/phpGPX/pull/58) by [@neronmoon](https://github.com/neronmoon)
21 |
22 | ## 1.1.2 : 2021-02-28
23 |
24 | - **Fixed**: [do SORT_BY_TIMESTAMP only for tracks with timestamps #52](https://github.com/Sibyx/phpGPX/pull/52)
25 |
26 | ## 1.1.1 : 2021-02-15
27 |
28 | - **Fixed**: Fixed `VERSION` string in `phpGPX.php`
29 |
30 | ## 1.1.0 : 2021-02-05
31 |
32 | - **Added**: [Limiting maximum elevation difference to protect from spikes](https://github.com/Sibyx/phpGPX/pull/49)
33 |
34 | ## 1.0.1
35 |
36 | - **Fixed**: Fixed PersonParser::toXML() if there are no links provided
37 | [Error when $person->links is null #48](https://github.com/Sibyx/phpGPX/issues/48)
38 |
39 | ## 1.0
40 |
41 | I am not very proud of idea having a major release in such terrible state. This release is just freeze from 2017
42 | compatible API and behaviour with some bugfixies. It looks like some people use the library and I want to perform some
43 | radical refactoring. See you in `2.x`.
44 |
45 | - **Fixed**: Do not return extra `:` while parsing unsupported extensions if there is no namespace for child element
46 | - **Fixed**: Fixed Copyright test
47 |
48 | ## 1.0-RC5
49 |
50 | - **Changed:** Moved PHPUnit to development dependencies.
51 |
52 | ## 1.0-RC4
53 |
54 | - **Changed:** [Change the way to deal with extensions ](https://github.com/Sibyx/phpGPX/pull/19)
55 | - **Fixed:** [RoutePoints and TripExtensions WIP](https://github.com/Sibyx/phpGPX/issues/22)
56 | - **Fixed:** [Route point rtep versus rtept](https://github.com/Sibyx/phpGPX/issues/21)
57 | - **Fixed:** [Empty array on load route](https://github.com/Sibyx/phpGPX/issues/20)
58 | - **Fixed:** Do not load zero altitude in statistics as NULL
59 |
60 | ## 1.0-RC3
61 |
62 | - **Added:** [Cumulative Elevation in stats](https://github.com/Sibyx/phpGPX/pull/12) with pull request #12 by @Shaydu
63 | - **Fixed:** [Fix for unterminated entity references](https://github.com/Sibyx/phpGPX/pull/13) with #13 by @benlumley
64 | - **Fixed:** [split loading and parsing in separate methods so a string may be loaded as gpx data](https://github.com/Sibyx/phpGPX/pull/9) with #9 by @lommes
65 | - **Fixed:** HeartRate [typo that lead to error](https://github.com/Sibyx/phpGPX/issues/14)
66 | - **Fixed:** Skipping RC2 in packagist [Missing version in packagist](https://github.com/Sibyx/phpGPX/issues/10)
67 |
68 | ## 1.0-RC2
69 |
70 | - **Fixed:** [waypoints not loaded correctly - they are ignored](https://github.com/Sibyx/phpGPX/issues/6)
71 | - Init of unit tests
72 |
73 | ## 1.0-RC1
74 |
75 | Initial release
76 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jakub.dubec@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Stats.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Stats
2 | ===============
3 |
4 | Class Stats
5 |
6 |
7 |
8 |
9 | * Class name: Stats
10 | * Namespace: phpGPX\Models
11 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
12 |
13 |
14 |
15 |
16 | Properties
17 | ----------
18 |
19 |
20 | ### $distance
21 |
22 | public float $distance
23 |
24 | Distance in meters (m)
25 |
26 |
27 |
28 | * Visibility: **public**
29 |
30 |
31 | ### $averageSpeed
32 |
33 | public float $averageSpeed = null
34 |
35 | Average speed in meters per second (m/s)
36 |
37 |
38 |
39 | * Visibility: **public**
40 |
41 |
42 | ### $averagePace
43 |
44 | public float $averagePace = null
45 |
46 | Average pace in seconds per kilometer (s/km)
47 |
48 |
49 |
50 | * Visibility: **public**
51 |
52 |
53 | ### $minAltitude
54 |
55 | public integer $minAltitude = null
56 |
57 | Minimal altitude in meters (m)
58 |
59 |
60 |
61 | * Visibility: **public**
62 |
63 | ### $minAltitudeCoords
64 |
65 | public [float,float] $minAltitudeCoords = null
66 |
67 | Minimal altitude coordinates in associative array with keys: "lat" for latitude & "lng" for longitude
68 |
69 |
70 |
71 | * Visibility: **public**
72 |
73 |
74 | ### $maxAltitude
75 |
76 | public integer $maxAltitude = null
77 |
78 | Maximal altitude in meters (m)
79 |
80 |
81 |
82 | * Visibility: **public**
83 |
84 | ### $maxAltitudeCoords
85 |
86 | public [float,float] $maxAltitudeCoords = null
87 |
88 | Maximal altitude coordinates in associative array with keys: "lat" for latitude & "lng" for longitude
89 |
90 |
91 |
92 | * Visibility: **public**
93 |
94 |
95 | ### $cumulativeElevationGain
96 |
97 | public integer $cumulativeElevationGain = null
98 |
99 | Cumulative elevation gain in meters (m)
100 |
101 |
102 |
103 | * Visibility: **public**
104 |
105 |
106 | ### $startedAt
107 |
108 | public \DateTime $startedAt = null
109 |
110 | Started time
111 |
112 |
113 |
114 | * Visibility: **public**
115 |
116 | ### $startedAtCoords
117 |
118 | public [float,float] $startedAtCoords = null
119 |
120 | Started coordinates in associative array with keys: "lat" for latitude & "lng" for longitude
121 |
122 |
123 |
124 | * Visibility: **public**
125 |
126 |
127 | ### $finishedAt
128 |
129 | public \DateTime $finishedAt = null
130 |
131 | Ending time
132 |
133 |
134 |
135 | * Visibility: **public**
136 |
137 | ### $finishedAtCoords
138 |
139 | public [float,float] $finishedAtCoords = null
140 |
141 | Ending coordinates in associative array with keys: "lat" for latitude & "lng" for longitude
142 |
143 |
144 |
145 | * Visibility: **public**
146 |
147 |
148 | ### $duration
149 |
150 | public integer $duration = null
151 |
152 | Duration is seconds
153 |
154 |
155 |
156 | * Visibility: **public**
157 |
158 |
159 | Methods
160 | -------
161 |
162 |
163 | ### reset
164 |
165 | mixed phpGPX\Models\Stats::reset()
166 |
167 | Reset all stats
168 |
169 |
170 |
171 | * Visibility: **public**
172 |
173 |
174 |
175 |
176 | ### toArray
177 |
178 | array phpGPX\Models\Summarizable::toArray()
179 |
180 | Serialize object to array
181 |
182 |
183 |
184 | * Visibility: **public**
185 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
186 |
187 |
188 |
189 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Collection.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Collection
2 | ===============
3 |
4 | Class Collection
5 |
6 |
7 |
8 |
9 | * Class name: Collection
10 | * Namespace: phpGPX\Models
11 | * This is an **abstract** class
12 | * This class implements: [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md), [phpGPX\Models\StatsCalculator](phpGPX-Models-StatsCalculator.md)
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $name
22 |
23 | public string $name
24 |
25 | GPS name of route / track.
26 |
27 | An original GPX 1.1 attribute.
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $comment
33 |
34 | public string $comment
35 |
36 | GPS comment for route.
37 |
38 | An original GPX 1.1 attribute.
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $description
44 |
45 | public string $description
46 |
47 | Text description of route/track for user. Not sent to GPS.
48 |
49 | An original GPX 1.1 attribute.
50 |
51 | * Visibility: **public**
52 |
53 |
54 | ### $source
55 |
56 | public string $source
57 |
58 | Source of data. Included to give user some idea of reliability and accuracy of data.
59 |
60 | An original GPX 1.1 attribute.
61 |
62 | * Visibility: **public**
63 |
64 |
65 | ### $links
66 |
67 | public array $links
68 |
69 | Links to external information about the route/track.
70 |
71 | An original GPX 1.1 attribute.
72 |
73 | * Visibility: **public**
74 |
75 |
76 | ### $number
77 |
78 | public integer $number
79 |
80 | GPS route/track number.
81 |
82 | An original GPX 1.1 attribute.
83 |
84 | * Visibility: **public**
85 |
86 |
87 | ### $type
88 |
89 | public string $type
90 |
91 | Type (classification) of route/track.
92 |
93 | An original GPX 1.1 attribute.
94 |
95 | * Visibility: **public**
96 |
97 |
98 | ### $extensions
99 |
100 | public \phpGPX\Models\Extensions $extensions
101 |
102 | You can add extend GPX by adding your own elements from another schema here.
103 |
104 | An original GPX 1.1 attribute.
105 |
106 | * Visibility: **public**
107 |
108 |
109 | ### $stats
110 |
111 | public \phpGPX\Models\Stats $stats
112 |
113 | Objects contains calculated statistics for collection.
114 |
115 |
116 |
117 | * Visibility: **public**
118 |
119 |
120 | Methods
121 | -------
122 |
123 |
124 | ### __construct
125 |
126 | mixed phpGPX\Models\Collection::__construct()
127 |
128 | Collection constructor.
129 |
130 |
131 |
132 | * Visibility: **public**
133 |
134 |
135 |
136 |
137 | ### getPoints
138 |
139 | array phpGPX\Models\Collection::getPoints()
140 |
141 | Return all points in collection.
142 |
143 |
144 |
145 | * Visibility: **public**
146 | * This method is **abstract**.
147 |
148 |
149 |
150 |
151 | ### toArray
152 |
153 | array phpGPX\Models\Summarizable::toArray()
154 |
155 | Serialize object to array
156 |
157 |
158 |
159 | * Visibility: **public**
160 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
161 |
162 |
163 |
164 |
165 | ### recalculateStats
166 |
167 | void phpGPX\Models\StatsCalculator::recalculateStats()
168 |
169 | Recalculate stats objects.
170 |
171 |
172 |
173 | * Visibility: **public**
174 | * This method is defined by [phpGPX\Models\StatsCalculator](phpGPX-Models-StatsCalculator.md)
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Track.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Track
2 | ===============
3 |
4 | Class Track
5 |
6 |
7 |
8 |
9 | * Class name: Track
10 | * Namespace: phpGPX\Models
11 | * Parent class: [phpGPX\Models\Collection](phpGPX-Models-Collection.md)
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $segments
22 |
23 | public array $segments
24 |
25 | Array of Track segments
26 |
27 |
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $name
33 |
34 | public string $name
35 |
36 | GPS name of route / track.
37 |
38 | An original GPX 1.1 attribute.
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $comment
44 |
45 | public string $comment
46 |
47 | GPS comment for route.
48 |
49 | An original GPX 1.1 attribute.
50 |
51 | * Visibility: **public**
52 |
53 |
54 | ### $description
55 |
56 | public string $description
57 |
58 | Text description of route/track for user. Not sent to GPS.
59 |
60 | An original GPX 1.1 attribute.
61 |
62 | * Visibility: **public**
63 |
64 |
65 | ### $source
66 |
67 | public string $source
68 |
69 | Source of data. Included to give user some idea of reliability and accuracy of data.
70 |
71 | An original GPX 1.1 attribute.
72 |
73 | * Visibility: **public**
74 |
75 |
76 | ### $links
77 |
78 | public array $links
79 |
80 | Links to external information about the route/track.
81 |
82 | An original GPX 1.1 attribute.
83 |
84 | * Visibility: **public**
85 |
86 |
87 | ### $number
88 |
89 | public integer $number
90 |
91 | GPS route/track number.
92 |
93 | An original GPX 1.1 attribute.
94 |
95 | * Visibility: **public**
96 |
97 |
98 | ### $type
99 |
100 | public string $type
101 |
102 | Type (classification) of route/track.
103 |
104 | An original GPX 1.1 attribute.
105 |
106 | * Visibility: **public**
107 |
108 |
109 | ### $extensions
110 |
111 | public \phpGPX\Models\Extensions $extensions
112 |
113 | You can add extend GPX by adding your own elements from another schema here.
114 |
115 | An original GPX 1.1 attribute.
116 |
117 | * Visibility: **public**
118 |
119 |
120 | ### $stats
121 |
122 | public \phpGPX\Models\Stats $stats
123 |
124 | Objects contains calculated statistics for collection.
125 |
126 |
127 |
128 | * Visibility: **public**
129 |
130 |
131 | Methods
132 | -------
133 |
134 |
135 | ### __construct
136 |
137 | mixed phpGPX\Models\Collection::__construct()
138 |
139 | Collection constructor.
140 |
141 |
142 |
143 | * Visibility: **public**
144 | * This method is defined by [phpGPX\Models\Collection](phpGPX-Models-Collection.md)
145 |
146 |
147 |
148 |
149 | ### getPoints
150 |
151 | array phpGPX\Models\Collection::getPoints()
152 |
153 | Return all points in collection.
154 |
155 |
156 |
157 | * Visibility: **public**
158 | * This method is **abstract**.
159 | * This method is defined by [phpGPX\Models\Collection](phpGPX-Models-Collection.md)
160 |
161 |
162 |
163 |
164 | ### toArray
165 |
166 | array phpGPX\Models\Summarizable::toArray()
167 |
168 | Serialize object to array
169 |
170 |
171 |
172 | * Visibility: **public**
173 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
174 |
175 |
176 |
177 |
178 | ### recalculateStats
179 |
180 | void phpGPX\Models\StatsCalculator::recalculateStats()
181 |
182 | Recalculate stats objects.
183 |
184 |
185 |
186 | * Visibility: **public**
187 | * This method is defined by [phpGPX\Models\StatsCalculator](phpGPX-Models-StatsCalculator.md)
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Route.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Route
2 | ===============
3 |
4 | Class Route
5 |
6 |
7 |
8 |
9 | * Class name: Route
10 | * Namespace: phpGPX\Models
11 | * Parent class: [phpGPX\Models\Collection](phpGPX-Models-Collection.md)
12 |
13 |
14 |
15 |
16 |
17 | Properties
18 | ----------
19 |
20 |
21 | ### $points
22 |
23 | public array $points
24 |
25 | A list of route points.
26 |
27 | An original GPX 1.1 attribute.
28 |
29 | * Visibility: **public**
30 |
31 |
32 | ### $name
33 |
34 | public string $name
35 |
36 | GPS name of route / track.
37 |
38 | An original GPX 1.1 attribute.
39 |
40 | * Visibility: **public**
41 |
42 |
43 | ### $comment
44 |
45 | public string $comment
46 |
47 | GPS comment for route.
48 |
49 | An original GPX 1.1 attribute.
50 |
51 | * Visibility: **public**
52 |
53 |
54 | ### $description
55 |
56 | public string $description
57 |
58 | Text description of route/track for user. Not sent to GPS.
59 |
60 | An original GPX 1.1 attribute.
61 |
62 | * Visibility: **public**
63 |
64 |
65 | ### $source
66 |
67 | public string $source
68 |
69 | Source of data. Included to give user some idea of reliability and accuracy of data.
70 |
71 | An original GPX 1.1 attribute.
72 |
73 | * Visibility: **public**
74 |
75 |
76 | ### $links
77 |
78 | public array $links
79 |
80 | Links to external information about the route/track.
81 |
82 | An original GPX 1.1 attribute.
83 |
84 | * Visibility: **public**
85 |
86 |
87 | ### $number
88 |
89 | public integer $number
90 |
91 | GPS route/track number.
92 |
93 | An original GPX 1.1 attribute.
94 |
95 | * Visibility: **public**
96 |
97 |
98 | ### $type
99 |
100 | public string $type
101 |
102 | Type (classification) of route/track.
103 |
104 | An original GPX 1.1 attribute.
105 |
106 | * Visibility: **public**
107 |
108 |
109 | ### $extensions
110 |
111 | public \phpGPX\Models\Extensions $extensions
112 |
113 | You can add extend GPX by adding your own elements from another schema here.
114 |
115 | An original GPX 1.1 attribute.
116 |
117 | * Visibility: **public**
118 |
119 |
120 | ### $stats
121 |
122 | public \phpGPX\Models\Stats $stats
123 |
124 | Objects contains calculated statistics for collection.
125 |
126 |
127 |
128 | * Visibility: **public**
129 |
130 |
131 | Methods
132 | -------
133 |
134 |
135 | ### __construct
136 |
137 | mixed phpGPX\Models\Collection::__construct()
138 |
139 | Collection constructor.
140 |
141 |
142 |
143 | * Visibility: **public**
144 | * This method is defined by [phpGPX\Models\Collection](phpGPX-Models-Collection.md)
145 |
146 |
147 |
148 |
149 | ### getPoints
150 |
151 | array phpGPX\Models\Collection::getPoints()
152 |
153 | Return all points in collection.
154 |
155 |
156 |
157 | * Visibility: **public**
158 | * This method is **abstract**.
159 | * This method is defined by [phpGPX\Models\Collection](phpGPX-Models-Collection.md)
160 |
161 |
162 |
163 |
164 | ### toArray
165 |
166 | array phpGPX\Models\Summarizable::toArray()
167 |
168 | Serialize object to array
169 |
170 |
171 |
172 | * Visibility: **public**
173 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
174 |
175 |
176 |
177 |
178 | ### recalculateStats
179 |
180 | void phpGPX\Models\StatsCalculator::recalculateStats()
181 |
182 | Recalculate stats objects.
183 |
184 |
185 |
186 | * Visibility: **public**
187 | * This method is defined by [phpGPX\Models\StatsCalculator](phpGPX-Models-StatsCalculator.md)
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Extensions/TrackPointExtension.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models\Extensions;
8 |
9 | use phpGPX\Helpers\SerializationHelper;
10 |
11 | /**
12 | * Class TrackPointExtension
13 | * Extension version: v2
14 | * Based on namespace: http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd
15 | * @package phpGPX\Models\Extensions
16 | */
17 | class TrackPointExtension extends AbstractExtension
18 | {
19 | const EXTENSION_V1_NAMESPACE = 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1';
20 | const EXTENSION_V1_NAMESPACE_XSD = 'http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd';
21 |
22 | const EXTENSION_NAMESPACE = 'http://www.garmin.com/xmlschemas/TrackPointExtension/v2';
23 | const EXTENSION_NAMESPACE_XSD = 'http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd';
24 |
25 | const EXTENSION_NAME = 'TrackPointExtension';
26 | const EXTENSION_NAMESPACE_PREFIX = 'gpxtpx';
27 |
28 | /**
29 | * Average temperature value measured in degrees Celsius.
30 | * @var float
31 | */
32 | public $aTemp;
33 |
34 | /**
35 | * Average temperature value measured in degrees Celsius.
36 | * @deprecated use TrackPointExtension::$aTemp instead. Will be removed in v1.0
37 | * @see TrackPointExtension::$aTemp
38 | * @var float
39 | */
40 | public $avgTemperature;
41 |
42 | /**
43 | * @var float
44 | */
45 | public $wTemp;
46 |
47 | /**
48 | * Depth in meters.
49 | * @var float
50 | */
51 | public $depth;
52 |
53 | /**
54 | * Heart rate in beats per minute.
55 | * @deprecated since v1.0RC3, use attribute TrackPointExtension::$hr instead, will be removed in v1.0
56 | * @see TrackPointExtension::$hr
57 | * @var float
58 | */
59 | public $heartRate;
60 |
61 | /**
62 | * Heart rate in beats per minute.
63 | * @since v1.0RC3
64 | * @var float
65 | */
66 | public $hr;
67 |
68 | /**
69 | * Cadence in revolutions per minute.
70 | * @deprecated since v1.0RC3, use attribute TrackPointExtension::$cad instead, will be removed in v1.0
71 | * @see TrackPointExtension::$cad
72 | * @var float
73 | */
74 | public $cadence;
75 |
76 | /**
77 | * Cadence in revolutions per minute.
78 | * @var float
79 | */
80 | public $cad;
81 |
82 | /**
83 | * Speed in meters per second.
84 | * @var float
85 | */
86 | public $speed;
87 |
88 | /**
89 | * Course. This type contains an angle measured in degrees in a clockwise direction from the true north line.
90 | * @var int
91 | */
92 | public $course;
93 |
94 | /**
95 | * Bearing. This type contains an angle measured in degrees in a clockwise direction from the true north line.
96 | * @var int
97 | */
98 | public $bearing;
99 |
100 | /**
101 | * TrackPointExtension constructor.
102 | */
103 | public function __construct()
104 | {
105 | parent::__construct(self::EXTENSION_NAMESPACE, self::EXTENSION_NAME);
106 | }
107 |
108 | /**
109 | * Serialize object to array
110 | * @return array
111 | */
112 | public function toArray()
113 | {
114 | return [
115 | 'aTemp' => SerializationHelper::floatOrNull($this->aTemp),
116 | 'wTemp' => SerializationHelper::floatOrNull($this->wTemp),
117 | 'depth' => SerializationHelper::floatOrNull($this->depth),
118 | 'hr' => SerializationHelper::floatOrNull($this->hr),
119 | 'cad' => SerializationHelper::floatOrNull($this->cad),
120 | 'speed' => SerializationHelper::floatOrNull($this->speed),
121 | 'course' => SerializationHelper::integerOrNull($this->course),
122 | 'bearing' => SerializationHelper::integerOrNull($this->bearing)
123 | ];
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/tests/CreateWaypointTest.php:
--------------------------------------------------------------------------------
1 | 9.860624216140083,
20 | 'latitude' => 54.9328621088893,
21 | 'elevation' => 0,
22 | 'time' => new \DateTime("+ 1 MINUTE")
23 | ],
24 | [
25 | 'latitude' => 54.83293237320851,
26 | 'longitude' => 9.76092208681491,
27 | 'elevation' => 10.0,
28 | 'time' => new \DateTime("+ 2 MINUTE")
29 | ],
30 | [
31 | 'latitude' => 54.73327743521187,
32 | 'longitude' => 9.66187816543752,
33 | 'elevation' => 42.42,
34 | 'time' => new \DateTime("+ 3 MINUTE")
35 | ],
36 | [
37 | 'latitude' => 54.63342326167919,
38 | 'longitude' => 9.562439849679859,
39 | 'elevation' => 12,
40 | 'time' => new \DateTime("+ 4 MINUTE")
41 | ]
42 | ];
43 |
44 | // Creating sample link object for metadata
45 | $link = new Link();
46 | $link->href = "https://sibyx.github.io/phpgpx";
47 | $link->text = 'phpGPX Docs';
48 |
49 | // GpxFile contains data and handles serialization of objects
50 | $gpx_file = new GpxFile();
51 |
52 | // Creating sample Metadata object
53 | $gpx_file->metadata = new Metadata();
54 |
55 | // Time attribute is always \DateTime object!
56 | $gpx_file->metadata->time = new \DateTime();
57 |
58 | // Description of GPX file
59 | $gpx_file->metadata->description = "My pretty awesome GPX file, created using phpGPX library!";
60 |
61 | // Adding link created before to links array of metadata
62 | // Metadata of GPX file can contain more than one link
63 | $gpx_file->metadata->links[] = $link;
64 |
65 | // Creating track
66 | $track = new Track();
67 |
68 | // Name of track
69 | $track->name = sprintf("Some random points in logical order. Input array should be already ordered!");
70 |
71 | // Type of data stored in track
72 | $track->type = 'RUN';
73 |
74 | // Source of GPS coordinates
75 | $track->source = sprintf("MySpecificGarminDevice");
76 |
77 | $wp = [];
78 | foreach ($sample_data as $sample_point) {
79 | // Creating trackpoint
80 | $point = new Point(Point::WAYPOINT);
81 | $point->latitude = $sample_point['latitude'];
82 | $point->longitude = $sample_point['longitude'];
83 | $point->elevation = $sample_point['elevation'];
84 | $point->time = $sample_point['time'];
85 |
86 | $wp[] = $point;
87 | }
88 |
89 | $gpx_file->waypoints = $wp;
90 |
91 | $gpx_file->save($this->waypoint_created_file, \phpGPX\phpGPX::XML_FORMAT);
92 | }
93 |
94 | public function setUp(): void
95 | {
96 | $this->waypoint_created_file = dirname(__FILE__)."/waypoint_test.gpx";
97 | $this->waypoint_saved_file = dirname(__FILE__).'/output_waypoint_test.gpx';
98 | // remove any test file hanging around
99 | system("rm -f {$this->waypoint_created_file}");
100 | // now create the test file
101 | $this->createWaypointFile();
102 | }
103 | public function tearDown(): void
104 | {
105 | system("rm -f {$this->waypoint_created_file}");
106 | system("rm -f {$this->waypoint_saved_file}");
107 | }
108 | public function test_waypoints_load()
109 | {
110 | $origFile = $this->waypoint_created_file;
111 | $outFile = $this->waypoint_saved_file;
112 |
113 | $gpx = new phpGPX();
114 | $file = $gpx->load($origFile);
115 |
116 | phpGPX::$PRETTY_PRINT = true;
117 | $file->save($outFile, phpGPX::XML_FORMAT);
118 |
119 | $retcode = 0;
120 | system("diff $origFile $outFile", $retcode);
121 | // system("diff $origFile $outFile2", $retcode);
122 | $this->assertEquals($retcode, 0);
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/ExtensionParserTest.php:
--------------------------------------------------------------------------------
1 | aTemp = (float) 14;
26 | $trackpoint->avgTemperature = (float) 14;
27 | $trackpoint->hr = (float) 152;
28 | $trackpoint->heartRate = (float) 152;
29 |
30 | $extensions = new Extensions();
31 | $extensions->trackPointExtension = $trackpoint;
32 |
33 | return $extensions;
34 | }
35 |
36 | protected function setUp(): void
37 | {
38 | parent::setUp();
39 |
40 | $this->testModelInstance = self::createTestInstance();
41 | }
42 |
43 | public function testParse()
44 | {
45 | $extensions = ExtensionParser::parse($this->testXmlFile->extensions);
46 |
47 | $this->assertEquals($this->testModelInstance->unsupported, $extensions->unsupported);
48 | $this->assertEquals($this->testModelInstance->trackPointExtension, $extensions->trackPointExtension);
49 |
50 | $this->assertEquals($this->testModelInstance->toArray(), $extensions->toArray());
51 | }
52 |
53 |
54 | /**
55 | * Returns output of ::toXML method of tested parser.
56 | * @param \DOMDocument $document
57 | * @return \DOMElement
58 | */
59 | protected function convertToXML(\DOMDocument $document)
60 | {
61 | return ExtensionParser::toXML($this->testModelInstance, $document);
62 | }
63 |
64 | public function testToXML()
65 | {
66 | $document = new \DOMDocument("1.0", 'UTF-8');
67 |
68 | $root = $document->createElement("document");
69 | $root->appendChild($this->convertToXML($document));
70 |
71 | $attributes = [
72 | 'xmlns' => 'http://www.topografix.com/GPX/1/1',
73 | 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
74 | 'xsi:schemaLocation' => 'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd',
75 | 'xmlns:gpxtpx' => 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1',
76 | 'xmlns:gpxx' => 'http://www.garmin.com/xmlschemas/GpxExtensions/v3',
77 | ];
78 |
79 | foreach ($attributes as $key => $value) {
80 | $attribute = $document->createAttribute($key);
81 | $attribute->value = $value;
82 | $root->appendChild($attribute);
83 | }
84 |
85 | $document->appendChild($root);
86 |
87 | $this->assertXmlStringEqualsXmlString($this->testXmlFile->asXML(), $document->saveXML());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/phpGPX/phpGPX.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX;
8 |
9 | use phpGPX\Models\GpxFile;
10 | use phpGPX\Parsers\MetadataParser;
11 | use phpGPX\Parsers\RouteParser;
12 | use phpGPX\Parsers\TrackParser;
13 | use phpGPX\Parsers\WaypointParser;
14 |
15 | /**
16 | * Class phpGPX
17 | * @package phpGPX
18 | */
19 | class phpGPX
20 | {
21 | const JSON_FORMAT = 'json';
22 | const XML_FORMAT = 'xml';
23 |
24 | const PACKAGE_NAME = 'phpGPX';
25 | const VERSION = '1.3.0';
26 |
27 | /**
28 | * Create Stats object for each track, segment and route
29 | * @var bool
30 | */
31 | public static $CALCULATE_STATS = true;
32 |
33 | /**
34 | * Additional sort based on timestamp in Routes & Tracks on XML read.
35 | * Disabled by default, data should be already sorted.
36 | * @var bool
37 | */
38 | public static $SORT_BY_TIMESTAMP = false;
39 |
40 | /**
41 | * Default DateTime output format in JSON serialization.
42 | * @var string
43 | */
44 | public static $DATETIME_FORMAT = 'c';
45 |
46 | /**
47 | * Default timezone for display.
48 | * Data are always stored in UTC timezone.
49 | * @var string
50 | */
51 | public static $DATETIME_TIMEZONE_OUTPUT = 'UTC';
52 |
53 | /**
54 | * Pretty print.
55 | * @var bool
56 | */
57 | public static $PRETTY_PRINT = true;
58 |
59 | /**
60 | * In stats elevation calculation: ignore points with an elevation of 0
61 | * This can happen with some GPS software adding a point with 0 elevation
62 | *
63 | * @var bool
64 | */
65 | public static $IGNORE_ELEVATION_0 = true;
66 |
67 | /**
68 | * Apply elevation gain/loss smoothing? If true, the threshold in
69 | * ELEVATION_SMOOTHING_THRESHOLD and ELEVATION_SMOOTHING_SPIKES_THRESHOLD (if not null) applies
70 | * @var bool
71 | */
72 | public static $APPLY_ELEVATION_SMOOTHING = false;
73 |
74 | /**
75 | * if APPLY_ELEVATION_SMOOTHING is true
76 | * the minimum elevation difference between considered points in meters
77 | * @var int
78 | */
79 | public static $ELEVATION_SMOOTHING_THRESHOLD = 2;
80 |
81 | /**
82 | * if APPLY_ELEVATION_SMOOTHING is true
83 | * the maximum elevation difference between considered points in meters
84 | * @var int|null
85 | */
86 | public static $ELEVATION_SMOOTHING_SPIKES_THRESHOLD = null;
87 |
88 | /**
89 | * Apply distance calculation smoothing? If true, the threshold in
90 | * DISTANCE_SMOOTHING_THRESHOLD applies
91 | * @var bool
92 | */
93 | public static $APPLY_DISTANCE_SMOOTHING = false;
94 |
95 | /**
96 | * if APPLY_DISTANCE_SMOOTHING is true
97 | * the minimum distance between considered points in meters
98 | * @var int
99 | */
100 | public static $DISTANCE_SMOOTHING_THRESHOLD = 2;
101 |
102 | /**
103 | * Load GPX file.
104 | * @param $path
105 | * @return GpxFile
106 | */
107 | public static function load($path)
108 | {
109 | $xml = file_get_contents($path);
110 |
111 | return self::parse($xml);
112 | }
113 |
114 | /**
115 | * Parse GPX data string.
116 | * @param $xml
117 | * @return GpxFile
118 | */
119 | public static function parse($xml)
120 | {
121 | $xml = simplexml_load_string($xml);
122 |
123 | $gpx = new GpxFile();
124 |
125 | // Parse creator
126 | $gpx->creator = isset($xml['creator']) ? (string)$xml['creator'] : null;
127 |
128 | // Parse metadata
129 | $gpx->metadata = isset($xml->metadata) ? MetadataParser::parse($xml->metadata) : null;
130 |
131 | // Parse waypoints
132 | $gpx->waypoints = isset($xml->wpt) ? WaypointParser::parse($xml->wpt) : [];
133 |
134 | // Parse tracks
135 | $gpx->tracks = isset($xml->trk) ? TrackParser::parse($xml->trk) : [];
136 |
137 | // Parse routes
138 | $gpx->routes = isset($xml->rte) ? RouteParser::parse($xml->rte) : [];
139 |
140 | return $gpx;
141 | }
142 |
143 | /**
144 | * Create library signature from name and version.
145 | * @return string
146 | */
147 | public static function getSignature()
148 | {
149 | return sprintf("%s/%s", self::PACKAGE_NAME, self::VERSION);
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/tests/UnitTests/phpGPX/Parsers/SegmentParserTest.json:
--------------------------------------------------------------------------------
1 | {
2 | "extensions": null,
3 | "points": [
4 | {
5 | "ageofdgpsdata": null,
6 | "cmt": null,
7 | "desc": null,
8 | "dgpsid": null,
9 | "difference": null,
10 | "distance": null,
11 | "ele": 2419,
12 | "extensions": null,
13 | "fix": null,
14 | "geoidheight": null,
15 | "hdop": null,
16 | "lat": 46.571948,
17 | "link": [],
18 | "lon": 8.414757,
19 | "magvar": null,
20 | "name": null,
21 | "pdop": null,
22 | "sat": null,
23 | "src": null,
24 | "sym": null,
25 | "time": "2017-08-13T07:10:41+00:00",
26 | "type": null,
27 | "vdop": null
28 | },
29 | {
30 | "ageofdgpsdata": null,
31 | "cmt": null,
32 | "desc": null,
33 | "dgpsid": null,
34 | "difference": 11.252021780368882,
35 | "distance": 11.252021780368882,
36 | "ele": 2418.8833883882,
37 | "extensions": null,
38 | "fix": null,
39 | "geoidheight": null,
40 | "hdop": null,
41 | "lat": 46.572016,
42 | "link": [],
43 | "lon": 8.414866,
44 | "magvar": null,
45 | "name": null,
46 | "pdop": null,
47 | "sat": null,
48 | "src": null,
49 | "sym": null,
50 | "time": "2017-08-13T07:10:54+00:00",
51 | "type": null,
52 | "vdop": null
53 | },
54 | {
55 | "ageofdgpsdata": null,
56 | "cmt": null,
57 | "desc": null,
58 | "dgpsid": null,
59 | "difference": 8.772816467963736,
60 | "distance": 20.024838248332617,
61 | "ele": 2419.8999900064,
62 | "extensions": null,
63 | "fix": null,
64 | "geoidheight": null,
65 | "hdop": null,
66 | "lat": 46.572088,
67 | "link": [],
68 | "lon": 8.414911,
69 | "magvar": null,
70 | "name": null,
71 | "pdop": null,
72 | "sat": null,
73 | "src": null,
74 | "sym": null,
75 | "time": "2017-08-13T07:11:56+00:00",
76 | "type": null,
77 | "vdop": null
78 | },
79 | {
80 | "ageofdgpsdata": null,
81 | "cmt": null,
82 | "desc": null,
83 | "dgpsid": null,
84 | "difference": 2.979832475456357,
85 | "distance": 23.004670723788976,
86 | "ele": 2422,
87 | "extensions": null,
88 | "fix": null,
89 | "geoidheight": null,
90 | "hdop": null,
91 | "lat": 46.572069,
92 | "link": [],
93 | "lon": 8.414912,
94 | "magvar": null,
95 | "name": null,
96 | "pdop": null,
97 | "sat": null,
98 | "src": null,
99 | "sym": null,
100 | "time": "2017-08-13T07:12:15+00:00",
101 | "type": null,
102 | "vdop": null
103 | },
104 | {
105 | "ageofdgpsdata": null,
106 | "cmt": null,
107 | "desc": null,
108 | "dgpsid": null,
109 | "difference": 3.8919896350020755,
110 | "distance": 26.896660358791053,
111 | "ele": 2425,
112 | "extensions": null,
113 | "fix": null,
114 | "geoidheight": null,
115 | "hdop": null,
116 | "lat": 46.572054,
117 | "link": [],
118 | "lon": 8.414888,
119 | "magvar": null,
120 | "name": null,
121 | "pdop": null,
122 | "sat": null,
123 | "src": null,
124 | "sym": null,
125 | "time": "2017-08-13T07:12:18+00:00",
126 | "type": null,
127 | "vdop": null
128 | }
129 | ],
130 | "stats": {
131 | "avgPace": 3949.728409446995,
132 | "avgSpeed": 0.2531819650202255,
133 | "bounds": [
134 | {
135 | "lat": 46.572088,
136 | "lng": 8.414757
137 | },
138 | {
139 | "lat": 46.571948,
140 | "lng": 8.414912
141 | }
142 | ],
143 | "cumulativeElevationGain": 6.116611611800181,
144 | "cumulativeElevationLoss": 0.11661161180018098,
145 | "distance": 24.558650606961873,
146 | "duration": 97,
147 | "finishedAt": "2017-08-13T07:12:18+00:00",
148 | "finishedAtCoords": {
149 | "lat": 46.572054,
150 | "lng": 8.414888
151 | },
152 | "maxAltitude": 2425,
153 | "maxAltitudeCoords": {
154 | "lat": 46.572054,
155 | "lng": 8.414888
156 | },
157 | "minAltitude": 2418.8833883882,
158 | "minAltitudeCoords": {
159 | "lat": 46.572016,
160 | "lng": 8.414866
161 | },
162 | "realDistance": 26.896660358791053,
163 | "startedAt": "2017-08-13T07:10:41+00:00",
164 | "startedAtCoords": {
165 | "lat": 46.571948,
166 | "lng": 8.414757
167 | }
168 | }
169 | }
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/TrackParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Track;
10 | use phpGPX\phpGPX;
11 |
12 | /**
13 | * Class TrackParser
14 | * @package phpGPX\Parsers
15 | */
16 | abstract class TrackParser
17 | {
18 | public static $tagName = 'trk';
19 |
20 | private static $attributeMapper = [
21 | 'name' => [
22 | 'name' => 'name',
23 | 'type' => 'string'
24 | ],
25 | 'cmt' => [
26 | 'name' => 'comment',
27 | 'type' => 'string'
28 | ],
29 | 'desc' => [
30 | 'name' => 'description',
31 | 'type' => 'string'
32 | ],
33 | 'src' => [
34 | 'name' => 'source',
35 | 'type' => 'string'
36 | ],
37 | 'link' => [
38 | 'name' => 'links',
39 | 'type' => 'array'
40 | ],
41 | 'number' => [
42 | 'name' => 'number',
43 | 'type' => 'integer'
44 | ],
45 | 'type' => [
46 | 'name' => 'type',
47 | 'type' => 'string'
48 | ],
49 | 'extensions' => [
50 | 'name' => 'extensions',
51 | 'type' => 'object'
52 | ],
53 | 'trkseg' => [
54 | 'name' => 'segments',
55 | 'type' => 'array'
56 | ],
57 | ];
58 |
59 | /**
60 | * @param \SimpleXMLElement $nodes
61 | * @return Track[]
62 | */
63 | public static function parse(\SimpleXMLElement $nodes)
64 | {
65 | $tracks = [];
66 |
67 | foreach ($nodes as $node) {
68 | $track = new Track();
69 |
70 | foreach (self::$attributeMapper as $key => $attribute) {
71 | switch ($key) {
72 | case 'link':
73 | $track->links = isset($node->link) ? LinkParser::parse($node->link) : [];
74 | break;
75 | case 'extensions':
76 | $track->extensions = isset($node->extensions) ? ExtensionParser::parse($node->extensions) : null;
77 | break;
78 | case 'trkseg':
79 | $track->segments = isset($node->trkseg) ? SegmentParser::parse($node->trkseg) : [];
80 | break;
81 | default:
82 | if (!in_array($attribute['type'], ['object', 'array'])) {
83 | $track->{$attribute['name']} = isset($node->$key) ? $node->$key : null;
84 | if (!is_null($track->{$attribute['name']})) {
85 | settype($track->{$attribute['name']}, $attribute['type']);
86 | }
87 | }
88 | break;
89 | }
90 | }
91 |
92 | if (phpGPX::$CALCULATE_STATS) {
93 | $track->recalculateStats();
94 | }
95 |
96 | $tracks[] = $track;
97 | }
98 |
99 | return $tracks;
100 | }
101 |
102 | /**
103 | * @param Track $track
104 | * @param \DOMDocument $document
105 | * @return \DOMElement
106 | */
107 | public static function toXML(Track $track, \DOMDocument &$document)
108 | {
109 | $node = $document->createElement(self::$tagName);
110 |
111 | foreach (self::$attributeMapper as $key => $attribute) {
112 | if (!is_null($track->{$attribute['name']})) {
113 | switch ($key) {
114 | case 'link':
115 | $child = LinkParser::toXMLArray($track->links, $document);
116 | break;
117 | case 'extensions':
118 | $child = ExtensionParser::toXML($track->extensions, $document);
119 | break;
120 | case 'trkseg':
121 | $child = SegmentParser::toXMLArray($track->segments, $document);
122 | break;
123 | default:
124 | $child = $document->createElement($key);
125 | $elementText = $document->createTextNode((string) $track->{$attribute['name']});
126 | $child->appendChild($elementText);
127 | break;
128 | }
129 |
130 | if (is_array($child)) {
131 | foreach ($child as $item) {
132 | $node->appendChild($item);
133 | }
134 | } else {
135 | $node->appendChild($child);
136 | }
137 | }
138 | }
139 |
140 | return $node;
141 | }
142 |
143 | /**
144 | * @param array $tracks
145 | * @param \DOMDocument $document
146 | * @return \DOMElement[]
147 | */
148 | public static function toXMLArray(array $tracks, \DOMDocument &$document)
149 | {
150 | $result = [];
151 |
152 | foreach ($tracks as $track) {
153 | $result[] = self::toXML($track, $document);
154 | }
155 |
156 | return $result;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/example/CreateFileFromScratch.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | use phpGPX\Models\GpxFile;
7 | use phpGPX\Models\Link;
8 | use phpGPX\Models\Metadata;
9 | use phpGPX\Models\Point;
10 | use phpGPX\Models\Segment;
11 | use phpGPX\Models\Track;
12 | use phpGPX\Models\Extensions;
13 | use phpGPX\Models\Extensions\TrackPointExtension;
14 |
15 | require_once '../vendor/autoload.php';
16 |
17 | $sample_data = [
18 | [
19 | 'longitude' => 9.860624216140083,
20 | 'latitude' => 54.9328621088893,
21 | 'elevation' => 0,
22 | 'aTemp' => 22,
23 | 'time' => new \DateTime("+ 1 MINUTE")
24 | ],
25 | [
26 | 'latitude' => 54.83293237320851,
27 | 'longitude' => 9.76092208681491,
28 | 'elevation' => 10.0,
29 | 'aTemp' => 23,
30 | 'time' => new \DateTime("+ 2 MINUTE")
31 | ],
32 | [
33 | 'latitude' => 54.73327743521187,
34 | 'longitude' => 9.66187816543752,
35 | 'elevation' => 42.42,
36 | 'aTemp' => 24,
37 | 'time' => new \DateTime("+ 3 MINUTE")
38 | ],
39 | [
40 | 'latitude' => 54.63342326167919,
41 | 'longitude' => 9.562439849679859,
42 | 'elevation' => 12,
43 | 'aTemp' => 25,
44 | 'time' => new \DateTime("+ 4 MINUTE")
45 | ]
46 | ];
47 |
48 | // Creating sample link object for metadata
49 | $link = new Link();
50 | $link->href = "https://sibyx.github.io/phpgpx";
51 | $link->text = 'phpGPX Docs';
52 |
53 | // GpxFile contains data and handles serialization of objects
54 | $gpx_file = new GpxFile();
55 |
56 | // Creating sample Metadata object
57 | $gpx_file->metadata = new Metadata();
58 |
59 | // Time attribute is always \DateTime object!
60 | $gpx_file->metadata->time = new \DateTime();
61 |
62 | // Description of GPX file
63 | $gpx_file->metadata->description = "My pretty awesome GPX file, created using phpGPX library!";
64 |
65 | // Adding link created before to links array of metadata
66 | // Metadata of GPX file can contain more than one link
67 | $gpx_file->metadata->links[] = $link;
68 |
69 | // Creating track
70 | $track = new Track();
71 |
72 | // Name of track
73 | $track->name = sprintf("Some random points in logical order. Input array should be already ordered!");
74 |
75 | // Type of data stored in track
76 | $track->type = 'RUN';
77 |
78 | // Source of GPS coordinates
79 | $track->source = sprintf("MySpecificGarminDevice");
80 |
81 | // Creating Track segment
82 | $segment = new Segment();
83 |
84 |
85 | foreach ($sample_data as $sample_point) {
86 | // Creating trackpoint
87 | $point = new Point(Point::TRACKPOINT);
88 | $point->latitude = $sample_point['latitude'];
89 | $point->longitude = $sample_point['longitude'];
90 | $point->elevation = $sample_point['elevation'];
91 | $point->time = $sample_point['time'];
92 |
93 | // Creating trackpoint extension
94 | $point->extensions = new Extensions();
95 | $trackPointExtension = new TrackPointExtension();
96 | $trackPointExtension->aTemp = $sample_point['aTemp'];
97 | $point->extensions->trackPointExtension = $trackPointExtension;
98 |
99 | $segment->points[] = $point;
100 | }
101 |
102 | // Add segment to segment array of track
103 | $track->segments[] = $segment;
104 |
105 | // Add track to file
106 | $gpx_file->tracks[] = $track;
107 |
108 | // Create waypoint
109 | $point = new Point(Point::WAYPOINT);
110 | $point->name = 'Example Waypoint';
111 | $point->latitude = $sample_point['latitude'];
112 | $point->longitude = $sample_point['longitude'];
113 | $point->elevation = $sample_point['elevation'];
114 | $point->time = $sample_point['time'];
115 |
116 | // Add waypoint to file
117 | $gpx_file->waypoints[] = $point;
118 |
119 | // GPX output
120 | $gpx_file->save('CreateFileFromScratchExample.gpx', \phpGPX\phpGPX::XML_FORMAT);
121 |
122 | // Serialized data as JSON
123 | $gpx_file->save('CreateFileFromScratchExample.json', \phpGPX\phpGPX::JSON_FORMAT);
124 |
125 | // Direct GPX output to browser
126 |
127 | header("Content-Type: application/gpx+xml");
128 | header("Content-Disposition: attachment; filename=CreatingFileFromScratchExample.gpx");
129 |
130 | echo $gpx_file->toXML()->saveXML();
131 | exit();
132 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Stats.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\DateTimeHelper;
10 | use phpGPX\phpGPX;
11 |
12 | /**
13 | * Class Stats
14 | * @package phpGPX\Models
15 | */
16 | class Stats implements Summarizable
17 | {
18 |
19 | /**
20 | * Distance in meters (m)
21 | * @var float
22 | */
23 | public $distance = 0;
24 |
25 | /**
26 | * Distance in meters (m) including elevation loss/gain
27 | * @var float
28 | */
29 | public $realDistance = 0;
30 |
31 | /**
32 | * Average speed in meters per second (m/s)
33 | * @var float
34 | */
35 | public $averageSpeed = null;
36 |
37 | /**
38 | * Average pace in seconds per kilometer (s/km)
39 | * @var float
40 | */
41 | public $averagePace = null;
42 |
43 | /**
44 | * Minimal altitude in meters (m)
45 | * @var int
46 | */
47 | public $minAltitude = null;
48 |
49 | /**
50 | * Minimal altitude coordinate
51 | * @var [float,float]
52 | */
53 | public $minAltitudeCoords = null;
54 |
55 | /**
56 | * Maximal altitude in meters (m)
57 | * @var int
58 | */
59 | public $maxAltitude = null;
60 |
61 | /**
62 | * Maximal altitude coordinate
63 | * @var [float,float]
64 | */
65 | public $maxAltitudeCoords = null;
66 |
67 | /**
68 | * Cumulative elevation gain in meters (m)
69 | * @var int
70 | */
71 | public $cumulativeElevationGain = null;
72 |
73 | /**
74 | * Cumulative elevation loss in meters (m)
75 | * @var int
76 | */
77 | public $cumulativeElevationLoss = null;
78 |
79 | /**
80 | * Started time
81 | * @var \DateTime
82 | */
83 | public $startedAt = null;
84 |
85 | /**
86 | * startedAt coordinate
87 | * @var [float,float]
88 | */
89 | public $startedAtCoords = null;
90 |
91 | /**
92 | * Ending time
93 | * @var \DateTime
94 | */
95 | public $finishedAt = null;
96 |
97 | /**
98 | * finishedAt coordinate
99 | * @var [float,float]
100 | */
101 | public $finishedAtCoords = null;
102 |
103 | /**
104 | * Duration is seconds
105 | * @var int
106 | */
107 | public $duration = null;
108 |
109 | /**
110 | * An array of two points representing
111 | * the most northwestern and the most
112 | * southeastern points of a segment
113 | * @var array
114 | */
115 | public $bounds = array();
116 |
117 | /**
118 | * Reset all stats
119 | */
120 | public function reset()
121 | {
122 | $this->distance = null;
123 | $this->realDistance = null;
124 | $this->averageSpeed = null;
125 | $this->averagePace = null;
126 | $this->minAltitude = null;
127 | $this->maxAltitude = null;
128 | $this->minAltitudeCoords = null;
129 | $this->maxAltitudeCoords = null;
130 | $this->cumulativeElevationGain = null;
131 | $this->cumulativeElevationLoss = null;
132 | $this->startedAt = null;
133 | $this->startedAtCoords = null;
134 | $this->finishedAt = null;
135 | $this->finishedAtCoords = null;
136 | $this->bounds = null;
137 | }
138 |
139 | /**
140 | * Serialize object to array
141 | * @return array
142 | */
143 | public function toArray()
144 | {
145 | return [
146 | 'distance' => (float)$this->distance,
147 | 'realDistance' => (float)$this->realDistance,
148 | 'avgSpeed' => (float)$this->averageSpeed,
149 | 'avgPace' => (float)$this->averagePace,
150 | 'minAltitude' => (float)$this->minAltitude,
151 | 'minAltitudeCoords' => $this->minAltitudeCoords,
152 | 'maxAltitude' => (float)$this->maxAltitude,
153 | 'maxAltitudeCoords' => $this->maxAltitudeCoords,
154 | 'cumulativeElevationGain' => (float)$this->cumulativeElevationGain,
155 | 'cumulativeElevationLoss' => (float)$this->cumulativeElevationLoss,
156 | 'startedAt' => DateTimeHelper::formatDateTime($this->startedAt, phpGPX::$DATETIME_FORMAT, phpGPX::$DATETIME_TIMEZONE_OUTPUT),
157 | 'startedAtCoords' => $this->startedAtCoords,
158 | 'finishedAt' => DateTimeHelper::formatDateTime($this->finishedAt, phpGPX::$DATETIME_FORMAT, phpGPX::$DATETIME_TIMEZONE_OUTPUT),
159 | 'finishedAtCoords' => $this->finishedAtCoords,
160 | 'duration' => (float)$this->duration,
161 | 'bounds' => $this->bounds
162 | ];
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/RouteParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Models\Route;
10 | use phpGPX\phpGPX;
11 |
12 | /**
13 | * Class RouteParser
14 | * @package phpGPX\Parsers
15 | */
16 | abstract class RouteParser
17 | {
18 | public static $tagName = 'rte';
19 |
20 | private static $attributeMapper = [
21 | 'name' => [
22 | 'name' => 'name',
23 | 'type' => 'string'
24 | ],
25 | 'cmt' => [
26 | 'name' => 'comment',
27 | 'type' => 'string'
28 | ],
29 | 'desc' => [
30 | 'name' => 'description',
31 | 'type' => 'string'
32 | ],
33 | 'src' => [
34 | 'name' => 'source',
35 | 'type' => 'string'
36 | ],
37 | 'links' => [
38 | 'name' => 'links',
39 | 'type' => 'array'
40 | ],
41 | 'number' => [
42 | 'name' => 'number',
43 | 'type' => 'integer'
44 | ],
45 | 'type' => [
46 | 'name' => 'type',
47 | 'type' => 'string'
48 | ],
49 | 'extensions' => [
50 | 'name' => 'extensions',
51 | 'type' => 'object'
52 | ],
53 | 'rtept' => [
54 | 'name' => 'points',
55 | 'type' => 'array'
56 | ],
57 | ];
58 |
59 | /**
60 | * @param \SimpleXMLElement[] $nodes
61 | * @return Route[]
62 | */
63 | public static function parse($nodes)
64 | {
65 | $routes = [];
66 |
67 | foreach ($nodes as $node) {
68 | $route = new Route();
69 |
70 | foreach (self::$attributeMapper as $key => $attribute) {
71 | switch ($key) {
72 | case 'link':
73 | $route->links = isset($node->link) ? LinkParser::parse($node->link) : [];
74 | break;
75 | case 'extensions':
76 | $route->extensions = isset($node->extensions) ? ExtensionParser::parse($node->extensions) : null;
77 | break;
78 | case 'rtept':
79 | $route->points = [];
80 |
81 | if (isset($node->rtept)) {
82 | foreach ($node->rtept as $point) {
83 | $route->points[] = PointParser::parse($point);
84 | }
85 | }
86 | break;
87 | default:
88 | if (!in_array($attribute['type'], ['object', 'array'])) {
89 | $route->{$attribute['name']} = isset($node->$key) ? $node->$key : null;
90 | if (!is_null($route->{$attribute['name']})) {
91 | settype($route->{$attribute['name']}, $attribute['type']);
92 | }
93 | }
94 | break;
95 | }
96 | }
97 |
98 | if (phpGPX::$CALCULATE_STATS) {
99 | $route->recalculateStats();
100 | }
101 |
102 | $routes[] = $route;
103 | }
104 |
105 | return $routes;
106 | }
107 |
108 | /**
109 | * @param Route $route
110 | * @param \DOMDocument $document
111 | * @return \DOMElement
112 | */
113 | public static function toXML(Route $route, \DOMDocument &$document)
114 | {
115 | $node = $document->createElement(self::$tagName);
116 |
117 | foreach (self::$attributeMapper as $key => $attribute) {
118 | if (!is_null($route->{$attribute['name']})) {
119 | switch ($key) {
120 | case 'links':
121 | $child = LinkParser::toXMLArray($route->links, $document);
122 | break;
123 | case 'extensions':
124 | $child = ExtensionParser::toXML($route->extensions, $document);
125 | break;
126 | case 'rtept':
127 | $child = PointParser::toXMLArray($route->points, $document);
128 | break;
129 | default:
130 | $child = $document->createElement($key);
131 | $elementText = $document->createTextNode((string) $route->{$attribute['name']});
132 | $child->appendChild($elementText);
133 | break;
134 | }
135 |
136 | if (is_array($child)) {
137 | foreach ($child as $item) {
138 | $node->appendChild($item);
139 | }
140 | } else {
141 | $node->appendChild($child);
142 | }
143 | }
144 | }
145 |
146 | return $node;
147 | }
148 |
149 | /**
150 | * @param array $routes
151 | * @param \DOMDocument $document
152 | * @return \DOMElement[]
153 | */
154 | public static function toXMLArray(array $routes, \DOMDocument &$document)
155 | {
156 | $result = [];
157 |
158 | foreach ($routes as $route) {
159 | $result[] = self::toXML($route, $document);
160 | }
161 |
162 | return $result;
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/docs/phpGPX-Models-Extensions-TrackPointExtension.md:
--------------------------------------------------------------------------------
1 | phpGPX\Models\Extensions\TrackPointExtension
2 | ===============
3 |
4 | Class TrackPointExtension
5 | Extension version: v2
6 | Based on namespace: http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd
7 |
8 |
9 |
10 |
11 | * Class name: TrackPointExtension
12 | * Namespace: phpGPX\Models\Extensions
13 | * Parent class: [phpGPX\Models\Extensions\AbstractExtension](phpGPX-Models-Extensions-AbstractExtension.md)
14 |
15 |
16 |
17 | Constants
18 | ----------
19 |
20 |
21 | ### EXTENSION_V1_NAMESPACE
22 |
23 | const EXTENSION_V1_NAMESPACE = 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1'
24 |
25 |
26 |
27 |
28 |
29 | ### EXTENSION_V1_NAMESPACE_XSD
30 |
31 | const EXTENSION_V1_NAMESPACE_XSD = 'http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd'
32 |
33 |
34 |
35 |
36 |
37 | ### EXTENSION_NAMESPACE
38 |
39 | const EXTENSION_NAMESPACE = 'http://www.garmin.com/xmlschemas/TrackPointExtension/v2'
40 |
41 |
42 |
43 |
44 |
45 | ### EXTENSION_NAMESPACE_XSD
46 |
47 | const EXTENSION_NAMESPACE_XSD = 'http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd'
48 |
49 |
50 |
51 |
52 |
53 | ### EXTENSION_NAME
54 |
55 | const EXTENSION_NAME = 'TrackPointExtension'
56 |
57 |
58 |
59 |
60 |
61 | ### EXTENSION_NAMESPACE_PREFIX
62 |
63 | const EXTENSION_NAMESPACE_PREFIX = 'gpxtpx'
64 |
65 |
66 |
67 |
68 |
69 | Properties
70 | ----------
71 |
72 |
73 | ### $aTemp
74 |
75 | public float $aTemp
76 |
77 | Average temperature value measured in degrees Celsius.
78 |
79 |
80 |
81 | * Visibility: **public**
82 |
83 |
84 | ### $wTemp
85 |
86 | public float $wTemp
87 |
88 |
89 |
90 |
91 |
92 | * Visibility: **public**
93 |
94 |
95 | ### $depth
96 |
97 | public float $depth
98 |
99 | Depth in meters.
100 |
101 |
102 |
103 | * Visibility: **public**
104 |
105 |
106 | ### $heartRate
107 |
108 | public float $heartRate
109 |
110 | Heart rate in beats per minute.
111 |
112 |
113 |
114 | * Visibility: **public**
115 |
116 |
117 | ### $hr
118 |
119 | public float $hr
120 |
121 | Heart rate in beats per minute.
122 |
123 |
124 |
125 | * Visibility: **public**
126 |
127 |
128 | ### $cadence
129 |
130 | public float $cadence
131 |
132 | Cadence in revolutions per minute.
133 |
134 |
135 |
136 | * Visibility: **public**
137 |
138 |
139 | ### $cad
140 |
141 | public float $cad
142 |
143 | Cadence in revolutions per minute.
144 |
145 |
146 |
147 | * Visibility: **public**
148 |
149 |
150 | ### $speed
151 |
152 | public float $speed
153 |
154 | Speed in meters per second.
155 |
156 |
157 |
158 | * Visibility: **public**
159 |
160 |
161 | ### $course
162 |
163 | public integer $course
164 |
165 | Course. This type contains an angle measured in degrees in a clockwise direction from the true north line.
166 |
167 |
168 |
169 | * Visibility: **public**
170 |
171 |
172 | ### $bearing
173 |
174 | public integer $bearing
175 |
176 | Bearing. This type contains an angle measured in degrees in a clockwise direction from the true north line.
177 |
178 |
179 |
180 | * Visibility: **public**
181 |
182 |
183 | ### $namespace
184 |
185 | public string $namespace
186 |
187 | XML namespace of extension
188 |
189 |
190 |
191 | * Visibility: **public**
192 |
193 |
194 | ### $extensionName
195 |
196 | public string $extensionName
197 |
198 | Node name extension.
199 |
200 |
201 |
202 | * Visibility: **public**
203 |
204 |
205 | Methods
206 | -------
207 |
208 |
209 | ### __construct
210 |
211 | mixed phpGPX\Models\Extensions\AbstractExtension::__construct(string $namespace, string $extensionName)
212 |
213 | AbstractExtension constructor.
214 |
215 |
216 |
217 | * Visibility: **public**
218 | * This method is defined by [phpGPX\Models\Extensions\AbstractExtension](phpGPX-Models-Extensions-AbstractExtension.md)
219 |
220 |
221 | #### Arguments
222 | * $namespace **string**
223 | * $extensionName **string**
224 |
225 |
226 |
227 | ### toArray
228 |
229 | array phpGPX\Models\Summarizable::toArray()
230 |
231 | Serialize object to array
232 |
233 |
234 |
235 | * Visibility: **public**
236 | * This method is defined by [phpGPX\Models\Summarizable](phpGPX-Models-Summarizable.md)
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/src/phpGPX/Parsers/MetadataParser.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Parsers;
8 |
9 | use phpGPX\Helpers\DateTimeHelper;
10 | use phpGPX\Models\Metadata;
11 |
12 | /**
13 | * Class MetadataParser
14 | * @package phpGPX\Parsers
15 | */
16 | abstract class MetadataParser
17 | {
18 | private static $tagName = 'metadata';
19 |
20 | private static $attributeMapper = [
21 | 'name' => [
22 | 'name' => 'name',
23 | 'type' => 'string'
24 | ],
25 | 'desc' => [
26 | 'name' => 'description',
27 | 'type' => 'string'
28 | ],
29 | 'author' => [
30 | 'name' => 'author',
31 | 'type' => 'object'
32 | ],
33 | 'copyright' => [
34 | 'name' => 'copyright',
35 | 'type' => 'object'
36 | ],
37 | 'link' => [
38 | 'name' => 'links',
39 | 'type' => 'array'
40 | ],
41 | 'time' => [
42 | 'name' => 'time',
43 | 'type' => 'object'
44 | ],
45 | 'keywords' => [
46 | 'name' => 'keywords',
47 | 'type' => 'string'
48 | ],
49 | 'bounds' => [
50 | 'name' => 'bounds',
51 | 'type' => 'object'
52 | ],
53 | 'extensions' => [
54 | 'name' => 'extensions',
55 | 'type' => 'object'
56 | ]
57 | ];
58 |
59 | /**
60 | * @param \SimpleXMLElement $node
61 | * @return Metadata
62 | */
63 | public static function parse(\SimpleXMLElement $node)
64 | {
65 | $metadata = new Metadata();
66 |
67 | foreach (self::$attributeMapper as $key => $attribute) {
68 | switch ($key) {
69 | case 'author':
70 | $metadata->author = isset($node->author) ? PersonParser::parse($node->author) : null;
71 | break;
72 | case 'copyright':
73 | $metadata->copyright = isset($node->copyright) ? CopyrightParser::parse($node->copyright) : null;
74 | break;
75 | case 'link':
76 | $metadata->links = isset($node->link) ? LinkParser::parse($node->link) : null;
77 | break;
78 | case 'time':
79 | $metadata->time = isset($node->time) ? DateTimeHelper::parseDateTime($node->time) : null;
80 | break;
81 | case 'bounds':
82 | $metadata->bounds = isset($node->bounds) ? BoundsParser::parse($node->bounds) : null;
83 | break;
84 | case 'extensions':
85 | $metadata->extensions = isset($node->extensions) ? ExtensionParser::parse($node->extensions) : null;
86 | break;
87 | default:
88 | if (!in_array($attribute['type'], ['object', 'array'])) {
89 | $metadata->{$attribute['name']} = isset($node->$key) ? $node->$key : null;
90 | if (!is_null($metadata->{$attribute['name']})) {
91 | settype($metadata->{$attribute['name']}, $attribute['type']);
92 | }
93 | }
94 | break;
95 | }
96 | }
97 |
98 | return $metadata;
99 | }
100 |
101 | public static function toXML(Metadata $metadata, \DOMDocument &$document)
102 | {
103 | $node = $document->createElement(self::$tagName);
104 |
105 | foreach (self::$attributeMapper as $key => $attribute) {
106 | if (!is_null($metadata->{$attribute['name']})) {
107 | switch ($key) {
108 | case 'author':
109 | $child = PersonParser::toXML($metadata->author, $document);
110 | break;
111 | case 'copyright':
112 | $child = CopyrightParser::toXML($metadata->copyright, $document);
113 | break;
114 | case 'link':
115 | $child = LinkParser::toXMLArray($metadata->links, $document);
116 | break;
117 | case 'time':
118 | $child = $document->createElement('time', DateTimeHelper::formatDateTime($metadata->time));
119 | break;
120 | case 'bounds':
121 | $child = BoundsParser::toXML($metadata->bounds, $document);
122 | break;
123 | case 'extensions':
124 | $child = ExtensionParser::toXML($metadata->extensions, $document);
125 | break;
126 | default:
127 | $child = $document->createElement($key);
128 | $elementText = $document->createTextNode((string) $metadata->{$attribute['name']});
129 | $child->appendChild($elementText);
130 | break;
131 | }
132 |
133 | if (is_array($child)) {
134 | foreach ($child as $item) {
135 | $node->appendChild($item);
136 | }
137 | } else {
138 | $node->appendChild($child);
139 | }
140 | }
141 | }
142 |
143 | return $node;
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Segment.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\BoundsCalculator;
10 | use phpGPX\Helpers\DistanceCalculator;
11 | use phpGPX\Helpers\ElevationGainLossCalculator;
12 | use phpGPX\Helpers\GeoHelper;
13 | use phpGPX\Helpers\SerializationHelper;
14 | use phpGPX\phpGPX;
15 |
16 | /**
17 | * Class Segment
18 | * A Track Segment holds a list of Track Points which are logically connected in order.
19 | * To represent a single GPS track where GPS reception was lost, or the GPS receiver was turned off,
20 | * start a new Track Segment for each continuous span of track data.
21 | * @package phpGPX\Models
22 | */
23 | class Segment implements Summarizable, StatsCalculator
24 | {
25 | /**
26 | * Array of segment points
27 | * @var Point[]
28 | */
29 | public $points;
30 |
31 | /**
32 | * You can add extend GPX by adding your own elements from another schema here.
33 | * @var Extensions|null
34 | */
35 | public $extensions;
36 |
37 | /**
38 | * @var Stats|null
39 | */
40 | public $stats;
41 |
42 | /**
43 | * Segment constructor.
44 | */
45 | public function __construct()
46 | {
47 | $this->points = [];
48 | $this->extensions = null;
49 | $this->stats = null;
50 | }
51 |
52 |
53 | /**
54 | * Serialize object to array
55 | * @return array
56 | */
57 | public function toArray()
58 | {
59 | return [
60 | 'points' => SerializationHelper::serialize($this->points),
61 | 'extensions' => SerializationHelper::serialize($this->extensions),
62 | 'stats' => SerializationHelper::serialize($this->stats)
63 | ];
64 | }
65 |
66 | /**
67 | * @return array|Point[]
68 | */
69 | public function getPoints()
70 | {
71 | return $this->points;
72 | }
73 |
74 | /**
75 | * Recalculate stats objects.
76 | * @return void
77 | */
78 | public function recalculateStats()
79 | {
80 | if (empty($this->stats)) {
81 | $this->stats = new Stats();
82 | }
83 |
84 | $count = count($this->points);
85 | $this->stats->reset();
86 |
87 | if (empty($this->points)) {
88 | return;
89 | }
90 |
91 | $firstPoint = &$this->points[0];
92 | $lastPoint = end($this->points);
93 |
94 | $this->stats->startedAt = $firstPoint->time;
95 | $this->stats->startedAtCoords = ["lat" => $firstPoint->latitude, "lng" => $firstPoint->longitude];
96 | $this->stats->finishedAt = $lastPoint->time;
97 | $this->stats->finishedAtCoords = ["lat" => $lastPoint->latitude, "lng" => $lastPoint->longitude];
98 | $this->stats->minAltitude = $firstPoint->elevation;
99 | $this->stats->minAltitudeCoords = ["lat" => $firstPoint->latitude, "lng" => $firstPoint->longitude];
100 |
101 | list($this->stats->cumulativeElevationGain, $this->stats->cumulativeElevationLoss) =
102 | ElevationGainLossCalculator::calculate($this->getPoints());
103 |
104 | $calculator = new DistanceCalculator($this->getPoints());
105 | $this->stats->distance = $calculator->getRawDistance();
106 | $this->stats->realDistance = $calculator->getRealDistance();
107 |
108 | for ($i = 0; $i < $count; $i++) {
109 | if ($this->stats->maxAltitude < $this->points[$i]->elevation) {
110 | $this->stats->maxAltitude = $this->points[$i]->elevation;
111 | $this->stats->maxAltitudeCoords = ["lat" => $this->points[$i]->latitude, "lng" => $this->points[$i]->longitude];
112 | }
113 |
114 | if ((phpGPX::$IGNORE_ELEVATION_0 === false || $this->points[$i]->elevation > 0) && $this->stats->minAltitude > $this->points[$i]->elevation) {
115 | $this->stats->minAltitude = $this->points[$i]->elevation;
116 | $this->stats->minAltitudeCoords = ["lat" => $this->points[$i]->latitude, "lng" => $this->points[$i]->longitude];
117 | }
118 | }
119 |
120 | if (isset($firstPoint->time) && isset($lastPoint->time) && $firstPoint->time instanceof \DateTime && $lastPoint->time instanceof \DateTime) {
121 | $this->stats->duration = $lastPoint->time->getTimestamp() - $firstPoint->time->getTimestamp();
122 |
123 | if ($this->stats->duration != 0) {
124 | $this->stats->averageSpeed = $this->stats->distance / $this->stats->duration;
125 | }
126 |
127 | if ($this->stats->distance != 0) {
128 | $this->stats->averagePace = $this->stats->duration / ($this->stats->distance / 1000);
129 | }
130 | }
131 |
132 | list($northWest, $southEast) = BoundsCalculator::calculate($this->getPoints());
133 | $this->stats->bounds = [$northWest, $southEast];
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/Route.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\BoundsCalculator;
10 | use phpGPX\Helpers\DistanceCalculator;
11 | use phpGPX\Helpers\ElevationGainLossCalculator;
12 | use phpGPX\Helpers\GeoHelper;
13 | use phpGPX\Helpers\SerializationHelper;
14 | use phpGPX\phpGPX;
15 |
16 | /**
17 | * Class Route
18 | * @package phpGPX\Models
19 | */
20 | class Route extends Collection
21 | {
22 |
23 | /**
24 | * A list of route points.
25 | * An original GPX 1.1 attribute.
26 | * @var Point[]
27 | */
28 | public $points;
29 |
30 | /**
31 | * Route constructor.
32 | */
33 | public function __construct()
34 | {
35 | parent::__construct();
36 | $this->points = [];
37 | }
38 |
39 |
40 | /**
41 | * Return all points in collection.
42 | * @return Point[]
43 | */
44 | public function getPoints(): array
45 | {
46 | /** @var Point[] $points */
47 | $points = [];
48 |
49 | $points = array_merge($points, $this->points);
50 |
51 | if (phpGPX::$SORT_BY_TIMESTAMP && !empty($points) && $points[0]->time !== null) {
52 | usort($points, array('phpGPX\Helpers\DateTimeHelper', 'comparePointsByTimestamp'));
53 | }
54 |
55 | return $points;
56 | }
57 |
58 | /**
59 | * Serialize object to array
60 | * @return array
61 | */
62 | public function toArray()
63 | {
64 | return [
65 | 'name' => SerializationHelper::stringOrNull($this->name),
66 | 'cmt' => SerializationHelper::stringOrNull($this->comment),
67 | 'desc' => SerializationHelper::stringOrNull($this->description),
68 | 'src' => SerializationHelper::stringOrNull($this->source),
69 | 'link' => SerializationHelper::serialize($this->links),
70 | 'number' => SerializationHelper::integerOrNull($this->number),
71 | 'type' => SerializationHelper::stringOrNull($this->type),
72 | 'extensions' => SerializationHelper::serialize($this->extensions),
73 | 'rtep' => SerializationHelper::serialize($this->points),
74 | 'stats' => SerializationHelper::serialize($this->stats)
75 | ];
76 | }
77 |
78 | /**
79 | * Recalculate stats objects.
80 | * @return void
81 | */
82 | public function recalculateStats()
83 | {
84 | if (empty($this->stats)) {
85 | $this->stats = new Stats();
86 | }
87 |
88 | $this->stats->reset();
89 |
90 | if (empty($this->points)) {
91 | return;
92 | }
93 |
94 | $pointCount = count($this->points);
95 |
96 | $firstPoint = &$this->points[0];
97 | $lastPoint = end($this->points);
98 |
99 | $this->stats->startedAt = $firstPoint->time;
100 | $this->stats->startedAtCoords = ["lat" => $firstPoint->latitude, "lng" => $firstPoint->longitude];
101 | $this->stats->finishedAt = $lastPoint->time;
102 | $this->stats->finishedAtCoords = ["lat" => $lastPoint->latitude, "lng" => $lastPoint->longitude];
103 | $this->stats->minAltitude = $firstPoint->elevation;
104 | $this->stats->minAltitudeCoords = ["lat" => $firstPoint->latitude, "lng" => $firstPoint->longitude];
105 |
106 | list($this->stats->cumulativeElevationGain, $this->stats->cumulativeElevationLoss) =
107 | ElevationGainLossCalculator::calculate($this->getPoints());
108 |
109 | $calculator = new DistanceCalculator($this->getPoints());
110 | $this->stats->distance = $calculator->getRawDistance();
111 | $this->stats->realDistance = $calculator->getRealDistance();
112 |
113 | for ($p = 0; $p < $pointCount; $p++) {
114 | if ((phpGPX::$IGNORE_ELEVATION_0 === false || $this->points[$p]->elevation > 0) && $this->stats->minAltitude > $this->points[$p]->elevation) {
115 | $this->stats->minAltitude = $this->points[$p]->elevation;
116 | $this->stats->minAltitudeCoords = ["lat" => $this->points[$p]->latitude, "lng" => $this->points[$p]->longitude];
117 | }
118 |
119 | if ($this->stats->maxAltitude < $this->points[$p]->elevation) {
120 | $this->stats->maxAltitude = $this->points[$p]->elevation;
121 | $this->stats->maxAltitudeCoords = ["lat" => $this->points[$p]->latitude, "lng" => $this->points[$p]->longitude];
122 | }
123 |
124 | if ($this->stats->minAltitude > $this->points[$p]->elevation) {
125 | $this->stats->minAltitude = $this->points[$p]->elevation;
126 | $this->stats->minAltitudeCoords = ["lat" => $this->points[$p]->latitude, "lng" => $this->points[$p]->longitude];
127 | }
128 | }
129 |
130 | if (($firstPoint->time instanceof \DateTime) && ($lastPoint->time instanceof \DateTime)) {
131 | $this->stats->duration = $lastPoint->time->getTimestamp() - $firstPoint->time->getTimestamp();
132 |
133 | if ($this->stats->duration != 0) {
134 | $this->stats->averageSpeed = $this->stats->distance / $this->stats->duration;
135 | }
136 |
137 | if ($this->stats->distance != 0) {
138 | $this->stats->averagePace = $this->stats->duration / ($this->stats->distance / 1000);
139 | }
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/phpGPX/Models/GpxFile.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace phpGPX\Models;
8 |
9 | use phpGPX\Helpers\SerializationHelper;
10 | use phpGPX\Parsers\ExtensionParser;
11 | use phpGPX\Parsers\MetadataParser;
12 | use phpGPX\Parsers\PointParser;
13 | use phpGPX\Parsers\RouteParser;
14 | use phpGPX\Parsers\TrackParser;
15 | use phpGPX\phpGPX;
16 |
17 | /**
18 | * Class GpxFile
19 | * Representation of GPX file.
20 | * @package phpGPX\Models
21 | */
22 | class GpxFile implements Summarizable
23 | {
24 | /**
25 | * A list of waypoints.
26 | * @var Point[]
27 | */
28 | public $waypoints;
29 |
30 | /**
31 | * A list of routes.
32 | * @var Route[]
33 | */
34 | public $routes;
35 |
36 | /**
37 | * A list of tracks.
38 | * @var Track[]
39 | */
40 | public $tracks;
41 |
42 | /**
43 | * Metadata about the file.
44 | * The original GPX 1.1 attribute.
45 | * @var Metadata|null
46 | */
47 | public $metadata;
48 |
49 | /**
50 | * @var Extensions|null
51 | */
52 | public $extensions;
53 |
54 | /**
55 | * Creator of GPX file.
56 | * @var string|null
57 | */
58 | public $creator;
59 |
60 | /**
61 | * GpxFile constructor.
62 | */
63 | public function __construct()
64 | {
65 | $this->waypoints = [];
66 | $this->routes = [];
67 | $this->tracks = [];
68 | $this->metadata = null;
69 | $this->extensions = null;
70 | $this->creator = null;
71 | }
72 |
73 |
74 | /**
75 | * Serialize object to array
76 | * @return array
77 | */
78 | public function toArray()
79 | {
80 | return SerializationHelper::filterNotNull([
81 | 'creator' => SerializationHelper::stringOrNull($this->creator),
82 | 'metadata' => SerializationHelper::serialize($this->metadata),
83 | 'waypoints' => SerializationHelper::serialize($this->waypoints),
84 | 'routes' => SerializationHelper::serialize($this->routes),
85 | 'tracks' => SerializationHelper::serialize($this->tracks),
86 | 'extensions' => SerializationHelper::serialize($this->extensions)
87 | ]);
88 | }
89 |
90 | /**
91 | * Return JSON representation of GPX file with statistics.
92 | * @return string
93 | */
94 | public function toJSON()
95 | {
96 | return json_encode($this->toArray(), phpGPX::$PRETTY_PRINT ? JSON_PRETTY_PRINT : null);
97 | }
98 |
99 | /**
100 | * Create XML representation of GPX file.
101 | * @return \DOMDocument
102 | */
103 | public function toXML()
104 | {
105 | $document = new \DOMDocument("1.0", 'UTF-8');
106 |
107 | $gpx = $document->createElementNS("http://www.topografix.com/GPX/1/1", "gpx");
108 | $gpx->setAttribute("version", "1.1");
109 | $gpx->setAttribute("creator", $this->creator ? $this->creator : phpGPX::getSignature());
110 |
111 | ExtensionParser::$usedNamespaces = [];
112 |
113 | if (!empty($this->metadata)) {
114 | $gpx->appendChild(MetadataParser::toXML($this->metadata, $document));
115 | }
116 |
117 | foreach ($this->waypoints as $waypoint) {
118 | $gpx->appendChild(PointParser::toXML($waypoint, $document));
119 | }
120 |
121 | foreach ($this->routes as $route) {
122 | $gpx->appendChild(RouteParser::toXML($route, $document));
123 | }
124 |
125 | foreach ($this->tracks as $track) {
126 | $gpx->appendChild(TrackParser::toXML($track, $document));
127 | }
128 |
129 | if (!empty($this->extensions)) {
130 | $gpx->appendChild(ExtensionParser::toXML($this->extensions, $document));
131 | }
132 |
133 | // Namespaces
134 | $schemaLocationArray = [
135 | 'http://www.topografix.com/GPX/1/1',
136 | 'http://www.topografix.com/GPX/1/1/gpx.xsd'
137 | ];
138 |
139 | foreach (ExtensionParser::$usedNamespaces as $usedNamespace) {
140 | $gpx->setAttributeNS(
141 | "http://www.w3.org/2000/xmlns/",
142 | sprintf("xmlns:%s", $usedNamespace['prefix']),
143 | $usedNamespace['namespace']
144 | );
145 |
146 | $schemaLocationArray[] = $usedNamespace['namespace'];
147 | $schemaLocationArray[] = $usedNamespace['xsd'];
148 | }
149 |
150 | $gpx->setAttributeNS(
151 | 'http://www.w3.org/2001/XMLSchema-instance',
152 | 'xsi:schemaLocation',
153 | implode(" ", $schemaLocationArray)
154 | );
155 |
156 | $document->appendChild($gpx);
157 |
158 | if (phpGPX::$PRETTY_PRINT) {
159 | $document->formatOutput = true;
160 | $document->preserveWhiteSpace = true;
161 | }
162 | return $document;
163 | }
164 |
165 | /**
166 | * Save data to file according to selected format.
167 | * @param string $path
168 | * @param string $format
169 | */
170 | public function save($path, $format)
171 | {
172 | switch ($format) {
173 | case phpGPX::XML_FORMAT:
174 | $document = $this->toXML();
175 | $document->save($path);
176 | break;
177 | case phpGPX::JSON_FORMAT:
178 | file_put_contents($path, $this->toJSON());
179 | break;
180 | default:
181 | throw new \RuntimeException("Unsupported file format!");
182 | };
183 | }
184 | }
185 |
--------------------------------------------------------------------------------